mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-01 16:12:02 +00:00
83 lines
2.8 KiB
TypeScript
83 lines
2.8 KiB
TypeScript
/**
|
|
* @vitest-environment node
|
|
*/
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { NextRequest } from 'next/server';
|
|
|
|
let readOnly = false;
|
|
let saveError: Error | null = null;
|
|
const jmapCalls: Array<[string, Record<string, unknown>]> = [];
|
|
|
|
vi.mock('@/lib/admin/session', () => ({
|
|
requireAdminAuth: async () => ({ ok: true }),
|
|
getClientIP: () => '127.0.0.1',
|
|
}));
|
|
vi.mock('@/lib/stalwart/credentials', () => ({
|
|
getStalwartCredentials: async () => ({
|
|
serverUrl: 'https://mail.example.org',
|
|
authHeader: 'Basic x',
|
|
trusted: true,
|
|
username: 'admin@example.org',
|
|
}),
|
|
}));
|
|
vi.mock('@/lib/admin/paths', async (importOriginal) => ({
|
|
...(await importOriginal<typeof import('@/lib/admin/paths')>()),
|
|
isConfigReadOnly: () => readOnly,
|
|
}));
|
|
vi.mock('@/lib/admin/config-manager', () => ({
|
|
configManager: {
|
|
ensureLoaded: async () => {},
|
|
setAdminConfig: async () => { if (saveError) throw saveError; },
|
|
},
|
|
}));
|
|
vi.mock('@/lib/admin/audit', () => ({ auditLog: async () => {} }));
|
|
vi.mock('@/lib/stalwart/server-fetch', () => ({
|
|
fetchJmapServer: async (url: string, init: { body?: string }) => {
|
|
if (url.endsWith('/.well-known/jmap')) {
|
|
return Response.json({ primaryAccounts: { 'urn:stalwart:jmap': 'a' } });
|
|
}
|
|
const [name, args] = JSON.parse(init.body!).methodCalls[0];
|
|
jmapCalls.push([name, args]);
|
|
if (name === 'x:OAuthClient/query') return Response.json({ methodResponses: [[name, { ids: [] }, '0']] });
|
|
return Response.json({ methodResponses: [[name, { created: { new: { id: 'h' } } }, '0']] });
|
|
},
|
|
}));
|
|
|
|
import { POST } from '../route';
|
|
|
|
function setup() {
|
|
return POST(new NextRequest('http://localhost/api/admin/oauth/setup', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ origin: 'https://webmail.example.org', issuerUrl: 'https://mail.example.org' }),
|
|
}));
|
|
}
|
|
|
|
beforeEach(() => {
|
|
readOnly = false;
|
|
saveError = null;
|
|
jmapCalls.length = 0;
|
|
});
|
|
|
|
describe('POST /api/admin/oauth/setup', () => {
|
|
it('creates the client on Stalwart when the config is writable', async () => {
|
|
const res = await setup();
|
|
expect(res.status).toBe(200);
|
|
expect(jmapCalls.map(([name]) => name)).toEqual(['x:OAuthClient/query', 'x:OAuthClient/set']);
|
|
});
|
|
|
|
it('refuses in read-only mode without sending anything to Stalwart (#1250)', async () => {
|
|
readOnly = true;
|
|
const res = await setup();
|
|
expect(res.status).toBe(409);
|
|
expect((await res.json()).error).toMatch(/read-only/);
|
|
expect(jmapCalls).toEqual([]);
|
|
});
|
|
|
|
it('destroys the client it just created when saving the config fails', async () => {
|
|
saveError = new Error('EROFS');
|
|
const res = await setup();
|
|
expect(res.status).toBe(500);
|
|
expect(jmapCalls.at(-1)).toEqual(['x:OAuthClient/set', { accountId: 'a', destroy: ['h'] }]);
|
|
});
|
|
});
|