Files
webmail/lib/__tests__/plugin-admin-config-secrets.test.ts
T

50 lines
2.6 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest';
import { dispatchApiCall } from '@/lib/plugin-sandbox/host-api';
import type { InstalledPlugin } from '@/lib/plugin-types';
// api.admin.getConfig asked the config route without ?public=1. The route
// hands an admin session every field, secrets included, so a plugin running
// for a user who was also signed in to the admin console got its own API
// keys (the Safe Browsing key of the link check). Secrets are for the server
// proxy only.
const plugin = {
id: 'external-link-warning', name: 'Link check', version: '2.0.0', author: '', description: '', type: 'hook',
permissions: ['admin:config'], grantedPermissions: ['admin:config'], managed: true, entrypoint: 'index.js',
enabled: true, status: 'running', settings: {},
} as unknown as InstalledPlugin;
afterEach(() => vi.unstubAllGlobals());
describe('api.admin config reads', () => {
it('ask for the fields without secrets', async () => {
const urls: string[] = [];
vi.stubGlobal('fetch', vi.fn(async (url: RequestInfo | URL) => {
urls.push(String(url));
return new Response(JSON.stringify({ trustedDomains: 'example.com' }), { headers: { 'content-type': 'application/json' } });
}));
expect(await dispatchApiCall(plugin, 'admin.getAllConfig', [])).toEqual({ trustedDomains: 'example.com' });
expect(await dispatchApiCall(plugin, 'admin.getConfig', ['trustedDomains'])).toBe('example.com');
expect(urls).toHaveLength(2);
for (const url of urls) expect(url).toMatch(/\/api\/admin\/plugins\/external-link-warning\/config\?public=1$/);
});
});
// The server a plugin's credential reaches (originKey) is what stays
// reachable with no third-party traffic: the plugin may not write it.
describe('api.admin config writes', () => {
it("refuse the plugin's own server address fields", async () => {
const fetchSpy = vi.fn(async () => new Response('{}'));
vi.stubGlobal('fetch', fetchSpy);
const withServer = {
...plugin,
credentials: { linkcheck: { label: 'x', scope: 'admin', inject: { type: 'bearer' }, secretKey: 'endpointToken', originKey: 'endpointUrl' } },
} as unknown as InstalledPlugin;
await expect(dispatchApiCall(withServer, 'admin.setConfig', ['endpointUrl', 'https://collector.example/'])).rejects.toThrow(/only an administrator/);
await expect(dispatchApiCall(withServer, 'admin.deleteConfig', ['endpointUrl'])).rejects.toThrow(/only an administrator/);
expect(fetchSpy).not.toHaveBeenCalled();
await dispatchApiCall(withServer, 'admin.setConfig', ['trustedDomains', 'example.com']);
expect(fetchSpy).toHaveBeenCalledTimes(1);
});
});