A key can be limited to IP addresses or CIDR networks (e.g. the Wabenhain server); a stolen key is useless from anywhere else. Requests from other addresses get 403 "not allowed for this IP" and a log line. The admin UI asks for the addresses when creating a key, warns when a key works from anywhere, shows the last source address and can take it over into the allowlist - changing the list needs no new key (PATCH /api-keys/:id). Also: a key can only carry scopes its creator holds. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common';
|
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
|
import { RequirePermission } from '../auth/decorators/require-permission.decorator';
|
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
|
import type { AuthenticatedUser } from '../auth/types/authenticated-user';
|
|
import { CreateApiKeyDto } from './dto/create-api-key.dto';
|
|
import { UpdateApiKeyDto } from './dto/update-api-key.dto';
|
|
import {
|
|
ApiKeySummary,
|
|
ApiKeysService,
|
|
CreatedApiKey,
|
|
} from './api-keys.service';
|
|
|
|
@ApiTags('api-keys')
|
|
@ApiBearerAuth()
|
|
@Controller('api-keys')
|
|
export class ApiKeysController {
|
|
constructor(private readonly apiKeys: ApiKeysService) {}
|
|
|
|
@RequirePermission('api-keys:manage')
|
|
@Get()
|
|
findAll(): Promise<ApiKeySummary[]> {
|
|
return this.apiKeys.findAll();
|
|
}
|
|
|
|
@RequirePermission('api-keys:manage')
|
|
@Post()
|
|
create(
|
|
@Body() dto: CreateApiKeyDto,
|
|
@CurrentUser() actor: AuthenticatedUser,
|
|
): Promise<CreatedApiKey> {
|
|
return this.apiKeys.create(dto, actor.id);
|
|
}
|
|
|
|
@RequirePermission('api-keys:manage')
|
|
@Patch(':id')
|
|
updateAllowedIps(
|
|
@Param('id') id: string,
|
|
@Body() dto: UpdateApiKeyDto,
|
|
@CurrentUser() actor: AuthenticatedUser,
|
|
): Promise<ApiKeySummary> {
|
|
return this.apiKeys.updateAllowedIps(id, dto, actor.id);
|
|
}
|
|
|
|
@RequirePermission('api-keys:manage')
|
|
@Post(':id/revoke')
|
|
revoke(
|
|
@Param('id') id: string,
|
|
@CurrentUser() actor: AuthenticatedUser,
|
|
): Promise<ApiKeySummary> {
|
|
return this.apiKeys.revoke(id, actor.id);
|
|
}
|
|
}
|