BREAKING CHANGE(opsserver): Require authentication for OpsServer endpoints, split handlers into authenticated view/admin routers, and make identity required on many TypedRequest interfaces
This commit is contained in:
@@ -3,34 +3,20 @@ import type { OpsServer } from '../classes.opsserver.js';
|
||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||
|
||||
export class ApiTokenHandler {
|
||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||
|
||||
constructor(private opsServerRef: OpsServer) {
|
||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
||||
this.registerHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Token management requires admin JWT only (tokens cannot manage tokens).
|
||||
*/
|
||||
private async requireAdmin(identity?: interfaces.data.IIdentity): Promise<string> {
|
||||
if (!identity?.jwt) {
|
||||
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
||||
}
|
||||
const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({ identity });
|
||||
if (!isAdmin) {
|
||||
throw new plugins.typedrequest.TypedResponseError('admin access required');
|
||||
}
|
||||
return identity.userId;
|
||||
}
|
||||
|
||||
private registerHandlers(): void {
|
||||
// All token management endpoints register directly on adminRouter
|
||||
// (middleware enforces admin JWT check, so no per-handler requireAdmin needed)
|
||||
const router = this.opsServerRef.adminRouter;
|
||||
|
||||
// Create API token
|
||||
this.typedrouter.addTypedHandler(
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateApiToken>(
|
||||
'createApiToken',
|
||||
async (dataArg) => {
|
||||
const userId = await this.requireAdmin(dataArg.identity);
|
||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||
if (!manager) {
|
||||
return { success: false, message: 'Token management not initialized' };
|
||||
@@ -39,7 +25,7 @@ export class ApiTokenHandler {
|
||||
dataArg.name,
|
||||
dataArg.scopes,
|
||||
dataArg.expiresInDays ?? null,
|
||||
userId,
|
||||
dataArg.identity.userId,
|
||||
);
|
||||
return { success: true, tokenId: result.id, tokenValue: result.rawToken };
|
||||
},
|
||||
@@ -47,11 +33,10 @@ export class ApiTokenHandler {
|
||||
);
|
||||
|
||||
// List API tokens
|
||||
this.typedrouter.addTypedHandler(
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListApiTokens>(
|
||||
'listApiTokens',
|
||||
async (dataArg) => {
|
||||
await this.requireAdmin(dataArg.identity);
|
||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||
if (!manager) {
|
||||
return { tokens: [] };
|
||||
@@ -62,11 +47,10 @@ export class ApiTokenHandler {
|
||||
);
|
||||
|
||||
// Revoke API token
|
||||
this.typedrouter.addTypedHandler(
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RevokeApiToken>(
|
||||
'revokeApiToken',
|
||||
async (dataArg) => {
|
||||
await this.requireAdmin(dataArg.identity);
|
||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||
if (!manager) {
|
||||
return { success: false, message: 'Token management not initialized' };
|
||||
@@ -78,11 +62,10 @@ export class ApiTokenHandler {
|
||||
);
|
||||
|
||||
// Roll API token
|
||||
this.typedrouter.addTypedHandler(
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RollApiToken>(
|
||||
'rollApiToken',
|
||||
async (dataArg) => {
|
||||
await this.requireAdmin(dataArg.identity);
|
||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||
if (!manager) {
|
||||
return { success: false, message: 'Token management not initialized' };
|
||||
@@ -97,11 +80,10 @@ export class ApiTokenHandler {
|
||||
);
|
||||
|
||||
// Toggle API token
|
||||
this.typedrouter.addTypedHandler(
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ToggleApiToken>(
|
||||
'toggleApiToken',
|
||||
async (dataArg) => {
|
||||
await this.requireAdmin(dataArg.identity);
|
||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||
if (!manager) {
|
||||
return { success: false, message: 'Token management not initialized' };
|
||||
|
||||
Reference in New Issue
Block a user