MCPcopy Create free account
hub / github.com/Linen-dev/linen.dev / ApiKeysService

Class ApiKeysService

apps/web/services/api-keys.ts:4–62  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2import { createHash, randomBytes } from 'crypto';
3
4export class ApiKeysService {
5 private static decryptKey({ token }: { token: string }) {
6 const hash = createHash('sha256')
7 .update(`${token}${process.env.NEXTAUTH_SECRET}`)
8 .digest('hex');
9 return hash;
10 }
11
12 private static createKey() {
13 const token = randomBytes(64).toString('hex');
14 const hash = createHash('sha256')
15 .update(`${token}${process.env.NEXTAUTH_SECRET}`)
16 .digest('hex');
17 return { token, hash };
18 }
19
20 static async getAccountByApiKey({ apiKey }: { apiKey: string }) {
21 const hash = this.decryptKey({ token: apiKey });
22 return await prisma.apiKeys.findFirst({
23 include: { account: true },
24 where: { hash },
25 });
26 }
27
28 static async list({ accountId }: { accountId: string }) {
29 return await prisma.apiKeys.findMany({
30 select: { id: true, createdAt: true, name: true, scope: true },
31 where: { accountId },
32 });
33 }
34
35 static async create({
36 accountId,
37 name,
38 scope,
39 }: {
40 accountId: string;
41 name: string;
42 scope?: string[];
43 }) {
44 const { token, hash } = this.createKey();
45 await prisma.apiKeys.create({
46 data: { name, accountId, scope, hash },
47 });
48 return { token };
49 }
50
51 static async revoke({ id, accountId }: { id: string; accountId: string }) {
52 const apiKey = await prisma.apiKeys.findUnique({ where: { id } });
53 if (!apiKey) {
54 return { ok: false, data: 'not_found' };
55 }
56 if (apiKey.accountId !== accountId) {
57 return { ok: false, data: 'account_mismatch' };
58 }
59 await prisma.apiKeys.delete({ where: { id: apiKey.id } });
60 return { ok: true };
61 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected