feat(admin): document POST /admin-auth/ in OpenAPI (#7693)

Adds verifyAdminAccess as the operation that the admin UI's LoginScreen
and App session check both call. Documents Basic auth, session cookie,
and anonymous request modes plus their 200/401/403 responses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
John McLear 2026-05-08 15:59:24 +01:00
parent 633d0a493d
commit 0e8548e530
2 changed files with 45 additions and 1 deletions

View file

@ -22,7 +22,29 @@ export const generateAdminDefinition = (): any => ({
'Distinct from the public /api/{version}/* surface served by /api/openapi.json.',
version: getEpVersion(),
},
paths: {},
paths: {
'/admin-auth/': {
post: {
operationId: 'verifyAdminAccess',
summary: 'Verify or establish an admin session',
description:
'POST with `Authorization: Basic <user:pass>` to log in as an admin ' +
'(server sets a session cookie on success). POST with no auth header ' +
'to verify an existing admin session cookie. The response body is ' +
'always empty; the status code conveys the outcome.',
security: [
{basicAuth: []},
{sessionCookie: []},
{},
],
responses: {
'200': {description: 'Caller is an authenticated admin.'},
'401': {description: 'No authentication presented and no admin session exists.'},
'403': {description: 'Authenticated, but the user is not an admin.'},
},
},
},
},
components: {
schemas: {},
securitySchemes: {

View file

@ -33,4 +33,26 @@ describe('admin OpenAPI document', function () {
assert.equal(doc.components.securitySchemes.sessionCookie.type, 'apiKey');
assert.equal(doc.components.securitySchemes.sessionCookie.in, 'cookie');
});
describe('/admin-auth/', function () {
it('declares POST with operationId verifyAdminAccess', function () {
const op = doc.paths['/admin-auth/']?.post;
assert.ok(op, 'POST /admin-auth/ is missing');
assert.equal(op.operationId, 'verifyAdminAccess');
});
it('documents responses 200, 401, 403', function () {
const responses = doc.paths['/admin-auth/'].post.responses;
assert.ok(responses['200'], 'missing 200 response');
assert.ok(responses['401'], 'missing 401 response');
assert.ok(responses['403'], 'missing 403 response');
});
it('declares security: basicAuth, sessionCookie, anonymous', function () {
const security = doc.paths['/admin-auth/'].post.security;
assert.ok(Array.isArray(security));
const keys = security.map((s: any) => Object.keys(s)[0] ?? '__anon__');
assert.deepEqual(keys.sort(), ['__anon__', 'basicAuth', 'sessionCookie'].sort());
});
});
});