fix: keep the mock JMAP server out of release builds

The mock JMAP server behind `/api/dev-jmap` accepts any password and
shipped in every image, held back only by `DEV_MOCK_JMAP=true` at
runtime. It now also needs the flag at build time (inlined through
`next.config.ts`), so a build made without it cannot switch the mock on,
and the Docker image drops the route before building.
This commit is contained in:
Linus Rath
2026-09-26 17:07:31 +02:00
parent 05fe7f8780
commit c329d486a7
3 changed files with 28 additions and 2 deletions
+3 -1
View File
@@ -21,7 +21,9 @@ ENV NEXT_PUBLIC_DEFAULT_LOCALE=$NEXT_PUBLIC_DEFAULT_LOCALE
# `git rev-parse` inside the build can't find it - CI must pass it in.
ARG GIT_COMMIT=unknown
ENV GIT_COMMIT=$GIT_COMMIT
RUN npx next build --webpack
# The mock JMAP server (DEV_MOCK_JMAP) accepts any password and is for
# `npm run dev` only; images ship without it.
RUN rm -rf "app/api/dev-jmap" && npx next build --webpack
FROM node:24-alpine AS runner
+5 -1
View File
@@ -2471,7 +2471,11 @@ function tooLargeFor(method: string, args: MethodArgs, callId: string): MethodRe
// ---------------------------------------------------------------------------
function isDevMockEnabled(): boolean {
return process.env.DEV_MOCK_JMAP === 'true';
// NEXT_PUBLIC_DEV_MOCK_JMAP is inlined at build time from DEV_MOCK_JMAP
// (next.config.ts `env`), so a build made without the mock - every
// release image and tarball - cannot switch it on through the runtime
// environment: the mock accepts any password.
return process.env.NEXT_PUBLIC_DEV_MOCK_JMAP === 'true' && process.env.DEV_MOCK_JMAP === 'true';
}
function getBaseUrl(request: NextRequest): string {
+20
View File
@@ -3,6 +3,8 @@ import { describe, it, expect, beforeAll, vi } from 'vitest';
// Mock the environment variable
beforeAll(() => {
vi.stubEnv('DEV_MOCK_JMAP', 'true');
// Inlined from DEV_MOCK_JMAP at build time in a real build.
vi.stubEnv('NEXT_PUBLIC_DEV_MOCK_JMAP', 'true');
});
// We test via dynamic import to get a fresh module with env set
@@ -369,3 +371,21 @@ describe('dev-jmap mock server', () => {
});
});
});
// The mock accepts any password; a build made without DEV_MOCK_JMAP (every
// release image) must not be able to switch it on at runtime.
describe('dev-jmap mock in a build made without it', () => {
it('stays off even when DEV_MOCK_JMAP is set at runtime', async () => {
vi.stubEnv('NEXT_PUBLIC_DEV_MOCK_JMAP', '');
try {
const { GET } = await loadRoute();
const req = makeRequest('http://localhost:3000/api/dev-jmap/.well-known/jmap', {
headers: { host: 'localhost:3000' },
});
const res = await GET(req as never, { params: Promise.resolve({ path: ['.well-known', 'jmap'] }) });
expect(res.status).toBe(404);
} finally {
vi.stubEnv('NEXT_PUBLIC_DEV_MOCK_JMAP', 'true');
}
});
});