diff --git a/src/frontend/apps/impress/.env.development b/src/frontend/apps/impress/.env.development index 362bb0f5..70468788 100644 --- a/src/frontend/apps/impress/.env.development +++ b/src/frontend/apps/impress/.env.development @@ -1,2 +1,3 @@ -NEXT_PUBLIC_API_URL=http://localhost:8071/api/v1.0/ +NEXT_PUBLIC_API_ORIGIN=http://localhost:8071 +NEXT_PUBLIC_API_URL=/api/v1.0/ NEXT_PUBLIC_SIGNALING_URL=ws://localhost:4444 diff --git a/src/frontend/apps/impress/.env.production b/src/frontend/apps/impress/.env.production index 5e9c0b70..a84acd1a 100644 --- a/src/frontend/apps/impress/.env.production +++ b/src/frontend/apps/impress/.env.production @@ -1,2 +1 @@ -NEXT_PUBLIC_API_URL=https://impress-staging.beta.numerique.gouv.fr/api/v1.0/ -NEXT_PUBLIC_SIGNALING_URL=wss://impress-staging.beta.numerique.gouv.fr/ws +NEXT_PUBLIC_API_URL=/api/v1.0/ diff --git a/src/frontend/apps/impress/.env.test b/src/frontend/apps/impress/.env.test index eda49a1b..f8102d78 100644 --- a/src/frontend/apps/impress/.env.test +++ b/src/frontend/apps/impress/.env.test @@ -1 +1,2 @@ +NEXT_PUBLIC_API_ORIGIN=http://test.jest NEXT_PUBLIC_API_URL=/api/ diff --git a/src/frontend/apps/impress/src/api/__tests__/fetchApi.test.tsx b/src/frontend/apps/impress/src/api/__tests__/fetchApi.test.tsx index d08d86d1..1a1fe346 100644 --- a/src/frontend/apps/impress/src/api/__tests__/fetchApi.test.tsx +++ b/src/frontend/apps/impress/src/api/__tests__/fetchApi.test.tsx @@ -5,22 +5,19 @@ import { useAuthStore } from '@/core/auth'; describe('fetchAPI', () => { beforeEach(() => { - process.env.NEXT_PUBLIC_API_URL = 'http://some.api.url/api/v1.0/'; fetchMock.restore(); }); it('adds correctly the basename', () => { - fetchMock.mock('http://some.api.url/api/v1.0/some/url', 200); + fetchMock.mock('http://test.jest/api/some/url', 200); void fetchAPI('some/url'); - expect(fetchMock.lastUrl()).toEqual( - 'http://some.api.url/api/v1.0/some/url', - ); + expect(fetchMock.lastUrl()).toEqual('http://test.jest/api/some/url'); }); it('adds the credentials automatically', () => { - fetchMock.mock('http://some.api.url/api/v1.0/some/url', 200); + fetchMock.mock('http://test.jest/api/some/url', 200); void fetchAPI('some/url', { body: 'some body' }); @@ -45,14 +42,14 @@ describe('fetchAPI', () => { useAuthStore.setState({ userData: { email: 'test@test.com', id: '1234' } }); - fetchMock.mock('http://some.api.url/api/v1.0/some/url', 401); + fetchMock.mock('http://test.jest/api/some/url', 401); await fetchAPI('some/url'); expect(useAuthStore.getState().userData).toBeUndefined(); expect(mockReplace).toHaveBeenCalledWith( - 'http://some.api.url/api/v1.0/authenticate/', + 'http://test.jest/api/authenticate/', ); }); }); diff --git a/src/frontend/apps/impress/src/api/fetchApi.ts b/src/frontend/apps/impress/src/api/fetchApi.ts index c2e2e2b8..4513e9bc 100644 --- a/src/frontend/apps/impress/src/api/fetchApi.ts +++ b/src/frontend/apps/impress/src/api/fetchApi.ts @@ -1,4 +1,4 @@ -import { login, useAuthStore } from '@/core/auth'; +import { baseApiUrl, login, useAuthStore } from '@/core'; /** * Retrieves the CSRF token from the document's cookies. @@ -14,7 +14,7 @@ function getCSRFToken() { } export const fetchAPI = async (input: string, init?: RequestInit) => { - const apiUrl = `${process.env.NEXT_PUBLIC_API_URL}${input}`; + const apiUrl = `${baseApiUrl()}${input}`; const { logout } = useAuthStore.getState(); const csrfToken = getCSRFToken(); diff --git a/src/frontend/apps/impress/src/core/auth/useAuthStore.tsx b/src/frontend/apps/impress/src/core/auth/useAuthStore.tsx index e2a2f3a1..b1f3c56d 100644 --- a/src/frontend/apps/impress/src/core/auth/useAuthStore.tsx +++ b/src/frontend/apps/impress/src/core/auth/useAuthStore.tsx @@ -1,11 +1,11 @@ import { create } from 'zustand'; +import { baseApiUrl } from '@/core/conf'; + import { User, getMe } from './api'; export const login = () => { - window.location.replace( - new URL('authenticate/', process.env.NEXT_PUBLIC_API_URL).href, - ); + window.location.replace(new URL('authenticate/', baseApiUrl()).href); }; interface AuthStore { diff --git a/src/frontend/apps/impress/src/core/conf.ts b/src/frontend/apps/impress/src/core/conf.ts new file mode 100644 index 00000000..d26686c8 --- /dev/null +++ b/src/frontend/apps/impress/src/core/conf.ts @@ -0,0 +1,11 @@ +export const baseApiUrl = () => { + const origin = + process.env.NEXT_PUBLIC_API_ORIGIN || + (typeof window !== 'undefined' ? window.location.origin : ''); + + return `${origin}${process.env.NEXT_PUBLIC_API_URL}`; +}; + +export const signalingUrl = () => + process.env.NEXT_PUBLIC_SIGNALING_URL || + (typeof window !== 'undefined' ? `wss://${window.location.host}/ws` : ''); diff --git a/src/frontend/apps/impress/src/core/index.ts b/src/frontend/apps/impress/src/core/index.ts index bd2c0cdc..97ec4897 100644 --- a/src/frontend/apps/impress/src/core/index.ts +++ b/src/frontend/apps/impress/src/core/index.ts @@ -1 +1,3 @@ export * from './AppProvider'; +export * from './auth'; +export * from './conf'; diff --git a/src/frontend/apps/impress/src/custom-next.d.ts b/src/frontend/apps/impress/src/custom-next.d.ts index 3e71f784..979f6e88 100644 --- a/src/frontend/apps/impress/src/custom-next.d.ts +++ b/src/frontend/apps/impress/src/custom-next.d.ts @@ -19,6 +19,7 @@ declare module '*.svg?url' { namespace NodeJS { interface ProcessEnv { + NEXT_PUBLIC_API_ORIGIN?: string; NEXT_PUBLIC_API_URL?: string; NEXT_PUBLIC_SIGNALING_URL?: string; } diff --git a/src/frontend/apps/impress/src/features/pads/pad/stores/usePadStore.tsx b/src/frontend/apps/impress/src/features/pads/pad/stores/usePadStore.tsx index d721c389..f7839e1b 100644 --- a/src/frontend/apps/impress/src/features/pads/pad/stores/usePadStore.tsx +++ b/src/frontend/apps/impress/src/features/pads/pad/stores/usePadStore.tsx @@ -3,6 +3,8 @@ import { WebrtcProvider } from 'y-webrtc'; import * as Y from 'yjs'; import { create } from 'zustand'; +import { signalingUrl } from '@/core'; + import { Pad } from '../types'; export interface PadStore { @@ -24,7 +26,7 @@ export const usePadStore = create((set) => ({ padsStore: initialState.padsStore, createProvider: (padId: string) => { const provider = new WebrtcProvider(padId, new Y.Doc(), { - signaling: [process.env.NEXT_PUBLIC_SIGNALING_URL || ''], + signaling: [signalingUrl()], }); set(({ padsStore }) => { diff --git a/src/frontend/apps/impress/src/features/pads/pads-panel/__tests__/PanelPads.test.tsx b/src/frontend/apps/impress/src/features/pads/pads-panel/__tests__/PanelPads.test.tsx index 7899b885..bcdf71db 100644 --- a/src/frontend/apps/impress/src/features/pads/pads-panel/__tests__/PanelPads.test.tsx +++ b/src/frontend/apps/impress/src/features/pads/pads-panel/__tests__/PanelPads.test.tsx @@ -23,7 +23,7 @@ describe('PanelPads', () => { }); it('renders with no pad to display', async () => { - fetchMock.mock(`/api/documents/?page=1&ordering=-created_at`, { + fetchMock.mock(`end:/api/documents/?page=1&ordering=-created_at`, { count: 0, results: [], }); @@ -40,7 +40,7 @@ describe('PanelPads', () => { }); it('renders an empty pad', async () => { - fetchMock.mock(`/api/documents/?page=1&ordering=-created_at`, { + fetchMock.mock(`end:/api/documents/?page=1&ordering=-created_at`, { count: 1, results: [ { @@ -59,7 +59,7 @@ describe('PanelPads', () => { }); it('renders a pad with only 1 member', async () => { - fetchMock.mock(`/api/documents/?page=1&ordering=-created_at`, { + fetchMock.mock(`end:/api/documents/?page=1&ordering=-created_at`, { count: 1, results: [ { @@ -83,7 +83,7 @@ describe('PanelPads', () => { }); it('renders a non-empty pad', async () => { - fetchMock.mock(`/api/documents/?page=1&ordering=-created_at`, { + fetchMock.mock(`end:/api/documents/?page=1&ordering=-created_at`, { count: 1, results: [ { @@ -111,7 +111,7 @@ describe('PanelPads', () => { }); it('renders the error', async () => { - fetchMock.mock(`/api/documents/?page=1&ordering=-created_at`, { + fetchMock.mock(`end:/api/documents/?page=1&ordering=-created_at`, { status: 500, }); @@ -127,7 +127,7 @@ describe('PanelPads', () => { }); it('renders with pad panel open', async () => { - fetchMock.mock(`/api/documents/?page=1&ordering=-created_at`, { + fetchMock.mock(`end:/api/documents/?page=1&ordering=-created_at`, { count: 1, results: [], }); @@ -142,7 +142,7 @@ describe('PanelPads', () => { }); it('closes and opens the pad panel', async () => { - fetchMock.mock(`/api/documents/?page=1&ordering=-created_at`, { + fetchMock.mock(`end:/api/documents/?page=1&ordering=-created_at`, { count: 1, results: [], }); diff --git a/src/helm/env.d/dev/values.impress.yaml.gotmpl b/src/helm/env.d/dev/values.impress.yaml.gotmpl index d399d95e..7e711043 100644 --- a/src/helm/env.d/dev/values.impress.yaml.gotmpl +++ b/src/helm/env.d/dev/values.impress.yaml.gotmpl @@ -50,7 +50,8 @@ backend: frontend: envVars: PORT: 8080 - NEXT_PUBLIC_API_URL: https://impress.127.0.0.1.nip.io/api/v1.0/ + NEXT_PUBLIC_API_ORIGIN: https://impress.127.0.0.1.nip.io + NEXT_PUBLIC_API_URL: /api/v1.0/ NEXT_PUBLIC_SIGNALING_URL: wss://impress.127.0.0.1.nip.io/ws replicas: 1