Use internal origin for runtime locale state
CI / quality (push) Waiting to run

This commit is contained in:
MOH
2026-03-15 08:33:27 +01:00
parent 4da093bb24
commit 635d54cb0e
3 changed files with 50 additions and 4 deletions
+1
View File
@@ -11,6 +11,7 @@ services:
NEXT_TELEMETRY_DISABLED: "1" NEXT_TELEMETRY_DISABLED: "1"
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-https://mohfarawati.de} NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-https://mohfarawati.de}
NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL:-https://root.mohfarawati.de} NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL:-https://root.mohfarawati.de}
SITE_RUNTIME_ORIGIN: ${SITE_RUNTIME_ORIGIN:-http://127.0.0.1:3000}
DATABASE_URL: postgresql://postgres:postgres@db:5432/moh_sass?schema=public DATABASE_URL: postgresql://postgres:postgres@db:5432/moh_sass?schema=public
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-change-me} ADMIN_PASSWORD: ${ADMIN_PASSWORD:-change-me}
ADMIN_AUTH_SECRET: ${ADMIN_AUTH_SECRET:-change-me-long-secret} ADMIN_AUTH_SECRET: ${ADMIN_AUTH_SECRET:-change-me-long-secret}
+18 -4
View File
@@ -28,6 +28,20 @@ type SiteRuntimeState = {
maintenanceEnabled: boolean; maintenanceEnabled: boolean;
}; };
function getSiteRuntimeStateOrigin(request: NextRequest): string {
const configuredOrigin = process.env.SITE_RUNTIME_ORIGIN?.trim();
if (configuredOrigin) {
return configuredOrigin;
}
if (process.env.NODE_ENV === "production") {
return "http://127.0.0.1:3000";
}
return request.nextUrl.origin;
}
function getPathLocale(pathname: string, fallbackLocale: (typeof appLocales)[number]) { function getPathLocale(pathname: string, fallbackLocale: (typeof appLocales)[number]) {
const locale = pathname.split("/")[1]; const locale = pathname.split("/")[1];
@@ -40,8 +54,8 @@ function isComingSoonPath(pathname: string) {
async function getSiteRuntimeState(request: NextRequest): Promise<SiteRuntimeState> { async function getSiteRuntimeState(request: NextRequest): Promise<SiteRuntimeState> {
try { try {
const runtimeStateUrl = new URL("/api/site/default-locale", request.url); const runtimeStateUrl = new URL("/api/site/default-locale", getSiteRuntimeStateOrigin(request));
const response = await fetch(new URL("/api/site/default-locale", request.url), { const response = await fetch(runtimeStateUrl, {
headers: { headers: {
"x-middleware-request": "1", "x-middleware-request": "1",
}, },
@@ -74,8 +88,8 @@ async function getSiteRuntimeState(request: NextRequest): Promise<SiteRuntimeSta
defaultLocale: isSupportedLocale(data.defaultLocale) ? data.defaultLocale : FALLBACK_LOCALE, defaultLocale: isSupportedLocale(data.defaultLocale) ? data.defaultLocale : FALLBACK_LOCALE,
maintenanceEnabled: data.maintenanceEnabled === true, maintenanceEnabled: data.maintenanceEnabled === true,
}; };
} catch { } catch (error) {
console.error("middleware:getSiteRuntimeState:failed"); console.error("middleware:getSiteRuntimeState:failed", error);
return { return {
defaultLocale: FALLBACK_LOCALE, defaultLocale: FALLBACK_LOCALE,
maintenanceEnabled: false, maintenanceEnabled: false,
+31
View File
@@ -39,6 +39,8 @@ function createMockRequest(url: string) {
describe("middleware locale runtime config", () => { describe("middleware locale runtime config", () => {
beforeEach(() => { beforeEach(() => {
vi.resetModules(); vi.resetModules();
process.env.NODE_ENV = "production";
delete process.env.SITE_RUNTIME_ORIGIN;
createMiddlewareMock.mockReset(); createMiddlewareMock.mockReset();
intlHandlerMock.mockReset(); intlHandlerMock.mockReset();
intlHandlerMock.mockReturnValue(NextResponse.next()); intlHandlerMock.mockReturnValue(NextResponse.next());
@@ -66,6 +68,10 @@ describe("middleware locale runtime config", () => {
await middleware(request as never); await middleware(request as never);
expect(fetch).toHaveBeenCalledWith(
new URL("http://127.0.0.1:3000/api/site/default-locale"),
expect.any(Object),
);
expect(createMiddlewareMock).toHaveBeenCalledTimes(1); expect(createMiddlewareMock).toHaveBeenCalledTimes(1);
expect(createMiddlewareMock).toHaveBeenCalledWith( expect(createMiddlewareMock).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
@@ -115,4 +121,29 @@ describe("middleware locale runtime config", () => {
expect(response.headers.get("location")).toBe("https://example.com/coming-soon"); expect(response.headers.get("location")).toBe("https://example.com/coming-soon");
expect(intlHandlerMock).not.toHaveBeenCalled(); expect(intlHandlerMock).not.toHaveBeenCalled();
}); });
it("prefers the configured internal runtime origin when provided", async () => {
process.env.SITE_RUNTIME_ORIGIN = "http://app:3000";
vi.stubGlobal(
"fetch",
vi.fn(async () => ({
ok: true,
json: async () => ({
defaultLocale: "en",
maintenanceEnabled: false,
}),
})),
);
const { default: middleware } = await import("../middleware");
const request = createMockRequest("https://example.com/");
await middleware(request as never);
expect(fetch).toHaveBeenCalledWith(
new URL("http://app:3000/api/site/default-locale"),
expect.any(Object),
);
});
}); });