UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

106 lines (99 loc) 3.37 kB
import { $inject } from "alepha"; import { $secure } from "alepha/security"; import { $action } from "alepha/server"; import { createApiKeyBodySchema } from "../schemas/createApiKeyBodySchema.ts"; import { createApiKeyResponseSchema } from "../schemas/createApiKeyResponseSchema.ts"; import { listApiKeyResponseSchema } from "../schemas/listApiKeyResponseSchema.ts"; import { revokeApiKeyParamsSchema } from "../schemas/revokeApiKeyParamsSchema.ts"; import { revokeApiKeyResponseSchema } from "../schemas/revokeApiKeyResponseSchema.ts"; import { ApiKeyService } from "../services/ApiKeyService.ts"; /** * REST API controller for user's own API key management. * Users can create, list, and revoke their own API keys. */ export class ApiKeyController { protected readonly url = "/api-keys"; protected readonly group = "api-keys"; protected readonly apiKeyService = $inject(ApiKeyService); /** * Create a new API key for the authenticated user. * The token is only returned once upon creation. */ public readonly createApiKey = $action({ method: "POST", path: this.url, group: this.group, description: "Create a new API key", use: [$secure({ permissions: ["api-key:create"] })], schema: { body: createApiKeyBodySchema, response: createApiKeyResponseSchema, }, handler: async (request) => { const { apiKey, token } = await this.apiKeyService.create({ userId: request.user.id, name: request.body.name, description: request.body.description, roles: request.user.roles ?? [], expiresAt: request.body.expiresAt ? new Date(request.body.expiresAt) : undefined, }); return { id: apiKey.id, name: apiKey.name, token, tokenSuffix: apiKey.tokenSuffix, roles: apiKey.roles, createdAt: apiKey.createdAt, expiresAt: apiKey.expiresAt, }; }, }); /** * List all active API keys for the authenticated user. * Does not return the actual tokens. */ public readonly listApiKeys = $action({ path: this.url, group: this.group, description: "List your API keys", use: [$secure({ permissions: ["api-key:read"] })], schema: { response: listApiKeyResponseSchema, }, handler: async (request) => { const apiKeys = await this.apiKeyService.list(request.user.id); return apiKeys.map((apiKey) => ({ id: apiKey.id, name: apiKey.name, tokenPrefix: apiKey.tokenPrefix, tokenSuffix: apiKey.tokenSuffix, roles: apiKey.roles, createdAt: apiKey.createdAt, lastUsedAt: apiKey.lastUsedAt, lastUsedIp: apiKey.lastUsedIp, expiresAt: apiKey.expiresAt, usageCount: apiKey.usageCount, })); }, }); /** * Revoke an API key. Only the owner can revoke their own keys. */ public readonly revokeMyApiKey = $action({ method: "DELETE", path: `${this.url}/:id`, group: this.group, description: "Revoke an API key", use: [$secure({ permissions: ["api-key:delete"] })], schema: { params: revokeApiKeyParamsSchema, response: revokeApiKeyResponseSchema, }, handler: async (request) => { await this.apiKeyService.revoke(request.params.id, request.user.id); return { ok: true }; }, }); }