fix redirect 2nd time
Build & Deploy / Build & Push Docker Image (push) Successful in 2m55s
Test / Type Check (all packages) (push) Successful in 53s
Build & Deploy / Deploy to VPS (push) Successful in 3s
Test / API Unit Tests (push) Successful in 46s
Test / Homepage Unit Tests (push) Successful in 44s
Test / Carplace Unit Tests (push) Successful in 40s
Test / Admin Unit Tests (push) Successful in 42s
Test / Dashboard Unit Tests (push) Successful in 41s
Test / API Integration Tests (push) Successful in 1m0s

This commit is contained in:
root
2026-07-02 22:01:16 -04:00
parent c27f0909df
commit 2959285425
2 changed files with 52 additions and 5 deletions
+25
View File
@@ -4,6 +4,9 @@ function installBrowser(token?: string) {
Object.defineProperty(globalThis, 'window', { Object.defineProperty(globalThis, 'window', {
configurable: true, configurable: true,
value: { value: {
location: {
hostname: 'localhost',
},
localStorage: { localStorage: {
getItem: vi.fn(() => token ?? null), getItem: vi.fn(() => token ?? null),
}, },
@@ -11,6 +14,10 @@ function installBrowser(token?: string) {
}) })
} }
function setBrowserHostname(hostname: string) {
;(globalThis.window as any).location.hostname = hostname
}
afterEach(() => { afterEach(() => {
vi.restoreAllMocks() vi.restoreAllMocks()
Reflect.deleteProperty(globalThis, 'window') Reflect.deleteProperty(globalThis, 'window')
@@ -55,6 +62,24 @@ describe('dashboard apiFetch', () => {
expect(fetchMock).toHaveBeenCalledWith('https://api.rentaldrivego.ma/api/v1/auth/account/start', expect.any(Object)) expect(fetchMock).toHaveBeenCalledWith('https://api.rentaldrivego.ma/api/v1/auth/account/start', expect.any(Object))
}) })
it('uses the dashboard proxy on production hosts when the public API URL is cross-host', async () => {
installBrowser()
setBrowserHostname('rentaldrivego.ma')
process.env.NEXT_PUBLIC_API_URL = 'https://api.rentaldrivego.ma/api/v1'
const fetchMock = vi.fn(async () => ({
ok: true,
json: async () => ({ data: { ok: true } }),
}))
Object.defineProperty(globalThis, 'fetch', { configurable: true, value: fetchMock })
const { apiFetch } = await import('./api')
await apiFetch('/auth/employee/login', { method: 'POST', body: JSON.stringify({}) })
expect(fetchMock).toHaveBeenCalledWith('/dashboard/api/v1/auth/employee/login', expect.objectContaining({
credentials: 'include',
}))
})
it.each([ it.each([
['https://api.rentaldrivego.ma', 'https://api.rentaldrivego.ma/api/v1/auth/account/start'], ['https://api.rentaldrivego.ma', 'https://api.rentaldrivego.ma/api/v1/auth/account/start'],
['https://api.rentaldrivego.ma/', 'https://api.rentaldrivego.ma/api/v1/auth/account/start'], ['https://api.rentaldrivego.ma/', 'https://api.rentaldrivego.ma/api/v1/auth/account/start'],
+27 -5
View File
@@ -4,12 +4,34 @@ export function normalizeApiBase(value: string): string {
return /\/api\/v1$/.test(base) ? base : `${base}/api/v1` return /\/api\/v1$/.test(base) ? base : `${base}/api/v1`
} }
export function resolveApiBase(): string { const DASHBOARD_PROXY_API_BASE = '/dashboard/api/v1'
const value = typeof window === 'undefined'
? (process.env.API_INTERNAL_URL || 'http://localhost:4000/api/v1')
: (process.env.NEXT_PUBLIC_API_URL || '/dashboard/api/v1')
return normalizeApiBase(value) function isLocalBrowserHost(hostname: string): boolean {
return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1'
}
function shouldUseDashboardProxy(configuredApiBase?: string): boolean {
if (typeof window === 'undefined') return false
if (!configuredApiBase) return true
if (configuredApiBase.startsWith('/')) return false
const currentHostname = window.location?.hostname
if (!currentHostname || isLocalBrowserHost(currentHostname)) return false
try {
return new URL(configuredApiBase).hostname !== currentHostname
} catch {
return false
}
}
export function resolveApiBase(): string {
if (typeof window === 'undefined') {
return normalizeApiBase(process.env.API_INTERNAL_URL || 'http://localhost:4000/api/v1')
}
const configuredApiBase = process.env.NEXT_PUBLIC_API_URL
return normalizeApiBase(shouldUseDashboardProxy(configuredApiBase) ? DASHBOARD_PROXY_API_BASE : (configuredApiBase || DASHBOARD_PROXY_API_BASE))
} }
export const API_BASE = resolveApiBase() export const API_BASE = resolveApiBase()