Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/modules/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ChangePasswordParams,
ResetPasswordParams,
} from "./auth.types";
import { getLoginUrl } from "../utils/auth-utils.js";

function isInsideIframe(): boolean {
if (typeof window === "undefined") return false;
Expand Down Expand Up @@ -116,8 +117,11 @@ export function createAuthModule(
? new URL(nextUrl, window.location.origin).toString()
: window.location.href;

// Build the login URL
const loginUrl = `${options.appBaseUrl}/login?from_url=${encodeURIComponent(redirectUrl)}`;
// A foreign origin (e.g. local dev) can't resolve the app by Host, so
// the login URL must carry the app id; same-origin keeps the bare path.
const loginUrl = options.appBaseUrl
? getLoginUrl(redirectUrl, { serverUrl: options.appBaseUrl, appId })
: `/login?from_url=${encodeURIComponent(redirectUrl)}`;

// Redirect to the login page
window.location.href = loginUrl;
Expand Down
23 changes: 20 additions & 3 deletions tests/unit/auth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ describe('Auth Module', () => {

// Verify the redirect URL was set correctly
expect(mockLocation.href).toBe(
`${appBaseUrl}/login?from_url=${encodeURIComponent(nextUrl)}`
`${appBaseUrl}/login?from_url=${encodeURIComponent(nextUrl)}&app_id=${appId}`
);

// Restore window
Expand All @@ -185,7 +185,7 @@ describe('Auth Module', () => {

// Verify the redirect URL uses current URL
expect(mockLocation.href).toBe(
`${appBaseUrl}/login?from_url=${encodeURIComponent(currentUrl)}`
`${appBaseUrl}/login?from_url=${encodeURIComponent(currentUrl)}&app_id=${appId}`
);

// Restore window
Expand All @@ -212,13 +212,30 @@ describe('Auth Module', () => {

// Verify the redirect URL uses the custom appBaseUrl
expect(mockLocation.href).toBe(
`${customAppBaseUrl}/login?from_url=${encodeURIComponent(nextUrl)}`
`${customAppBaseUrl}/login?from_url=${encodeURIComponent(nextUrl)}&app_id=${appId}`
);

// Restore window
global.window = originalWindow;
});

test('should preserve a query string in nextUrl through from_url encoding', () => {
const originalWindow = global.window;
const mockLocation = { href: '' };
global.window = {
location: mockLocation
};

const nextUrl = 'https://example.com/dashboard?tab=x&page=2';
base44.auth.redirectToLogin(nextUrl);

expect(mockLocation.href).toBe(
`${appBaseUrl}/login?from_url=${encodeURIComponent(nextUrl)}&app_id=${appId}`
);

global.window = originalWindow;
});

test('should use relative URL for login redirect when appBaseUrl is not provided', () => {
// Create a client without appBaseUrl
const clientWithoutAppBaseUrl = createClient({
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ describe('appBaseUrl Normalization', () => {

// Verify the redirect URL uses the custom appBaseUrl
expect(mockLocation.href).toBe(
`${customAppBaseUrl}/login?from_url=${encodeURIComponent(nextUrl)}`
`${customAppBaseUrl}/login?from_url=${encodeURIComponent(nextUrl)}&app_id=test-app-id`
);

// Restore window
Expand Down
Loading