MCPcopy Create free account
hub / github.com/ShipSecAI/studio / ApiKeysService

Class ApiKeysService

backend/src/api-keys/api-keys.service.ts:21–196  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

19
20@Injectable()
21export class ApiKeysService {
22 private readonly logger = new Logger(ApiKeysService.name);
23
24 constructor(
25 @Inject(DRIZZLE_TOKEN)
26 private readonly db: NodePgDatabase<typeof schema>,
27 ) {}
28
29 async create(auth: AuthContext, dto: CreateApiKeyDto) {
30 if (!auth.organizationId) {
31 throw new InternalServerErrorException('Organization ID missing in context');
32 }
33
34 const { key: plainKey, id: keyId } = this.generateKeyWithId();
35 const keyHash = await bcrypt.hash(plainKey, 10);
36
37 const [apiKey] = await this.db
38 .insert(apiKeys)
39 .values({
40 name: dto.name,
41 description: dto.description,
42 keyHash,
43 keyPrefix: KEY_PREFIX,
44 keyHint: keyId,
45 permissions: dto.permissions,
46 organizationId: dto.organizationId ?? auth.organizationId,
47 createdBy: auth.userId || 'system',
48 expiresAt: dto.expiresAt ? new Date(dto.expiresAt) : null,
49 rateLimit: dto.rateLimit,
50 isActive: true,
51 })
52 .returning();
53
54 return { apiKey, plainKey };
55 }
56
57 async list(auth: AuthContext, query: ListApiKeysQueryDto) {
58 if (!auth.organizationId) {
59 return [];
60 }
61
62 const conditions = [eq(apiKeys.organizationId, auth.organizationId)];
63
64 if (query.isActive !== undefined) {
65 conditions.push(eq(apiKeys.isActive, query.isActive));
66 }
67
68 return this.db
69 .select()
70 .from(apiKeys)
71 .where(and(...conditions))
72 .orderBy(desc(apiKeys.createdAt))
73 .limit(query.limit)
74 .offset(query.offset);
75 }
76
77 async get(auth: AuthContext, id: string) {
78 if (!auth.organizationId) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected