kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
at main 63 lines 1.8 kB view raw
1import { createHash } from "node:crypto"; 2import { and, eq, gt, isNull, or } from "drizzle-orm"; 3import db, { schema } from "../database"; 4 5async function hashApiKey(key: string): Promise<string> { 6 const hash = createHash("sha256").update(key).digest(); 7 return hash 8 .toString("base64") 9 .replace(/\+/g, "-") 10 .replace(/\//g, "_") 11 .replace(/=/g, ""); 12} 13 14export async function verifyApiKey(key: string) { 15 const hashedKey = await hashApiKey(key); 16 17 const [apiKey] = await db 18 .select() 19 .from(schema.apikeyTable) 20 .where( 21 and( 22 eq(schema.apikeyTable.key, hashedKey), 23 eq(schema.apikeyTable.enabled, true), 24 or( 25 isNull(schema.apikeyTable.expiresAt), 26 gt(schema.apikeyTable.expiresAt, new Date()), 27 ), 28 ), 29 ) 30 .limit(1); 31 32 if (!apiKey) { 33 return null; 34 } 35 36 return { 37 valid: true, 38 key: { 39 id: apiKey.id, 40 userId: apiKey.referenceId ?? apiKey.userId ?? "", 41 name: apiKey.name, 42 prefix: apiKey.prefix, 43 start: apiKey.start, 44 enabled: apiKey.enabled ?? false, 45 expiresAt: apiKey.expiresAt, 46 permissions: apiKey.permissions 47 ? (JSON.parse(apiKey.permissions) as Record<string, string[]>) 48 : null, 49 refillInterval: apiKey.refillInterval, 50 refillAmount: apiKey.refillAmount, 51 lastRefillAt: apiKey.lastRefillAt, 52 rateLimitEnabled: apiKey.rateLimitEnabled, 53 rateLimitTimeWindow: apiKey.rateLimitTimeWindow, 54 rateLimitMax: apiKey.rateLimitMax, 55 requestCount: apiKey.requestCount, 56 remaining: apiKey.remaining, 57 lastRequest: apiKey.lastRequest, 58 metadata: apiKey.metadata 59 ? (JSON.parse(apiKey.metadata) as Record<string, unknown>) 60 : null, 61 }, 62 }; 63}