feat(tokens): Add support for organization-owned API tokens and org-level token management

This commit is contained in:
2025-11-28 12:57:17 +00:00
parent 93ae998e3f
commit dface47942
9 changed files with 354 additions and 54 deletions

View File

@@ -9,6 +9,8 @@ import { AuditService } from './audit.service.ts';
export interface ICreateTokenOptions {
userId: string;
organizationId?: string; // For org-owned tokens
createdById?: string; // Who created the token (defaults to userId)
name: string;
protocols: TRegistryProtocol[];
scopes: ITokenScope[];
@@ -52,6 +54,8 @@ export class TokenService {
const token = new ApiToken();
token.id = await ApiToken.getNewId();
token.userId = options.userId;
token.organizationId = options.organizationId;
token.createdById = options.createdById || options.userId;
token.name = options.name;
token.tokenHash = tokenHash;
token.tokenPrefix = tokenPrefix;
@@ -150,6 +154,13 @@ export class TokenService {
return await ApiToken.getUserTokens(userId);
}
/**
* Get all tokens for an organization
*/
public async getOrgTokens(organizationId: string): Promise<ApiToken[]> {
return await ApiToken.getOrgTokens(organizationId);
}
/**
* Revoke a token
*/
@@ -175,6 +186,18 @@ export class TokenService {
return tokens.length;
}
/**
* Revoke all tokens for an organization
*/
public async revokeAllOrgTokens(organizationId: string, reason?: string): Promise<number> {
const tokens = await ApiToken.getOrgTokens(organizationId);
for (const token of tokens) {
await token.revoke(reason);
await this.auditService.logTokenRevoked(token.id, token.name);
}
return tokens.length;
}
/**
* Check if token has permission for a specific action
*/