File size: 1,647 Bytes
b5e5eac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import crypto from 'crypto';
import { AppDataSource } from '../config/database';
import { ApiKey } from '../entities/ApiKey';

const apiKeyRepository = AppDataSource.getRepository(ApiKey);

/**
 * Generate a new API key
 */
export function generateApiKey(): string {
  return `zurri_${crypto.randomBytes(32).toString('hex')}`;
}

/**
 * Hash API key for storage
 */
export async function hashApiKey(key: string): Promise<string> {
  return crypto.createHash('sha256').update(key).digest('hex');
}

/**
 * Verify API key
 */
export async function verifyApiKey(
  providedKey: string,
  userId: string
): Promise<ApiKey | null> {
  const hashedKey = await hashApiKey(providedKey);

  const apiKey = await apiKeyRepository.findOne({
    where: {
      key: hashedKey,
      userId,
      isActive: true,
    },
  });

  if (!apiKey) {
    return null;
  }

  // Check expiry
  if (apiKey.expiresAt && apiKey.expiresAt < new Date()) {
    return null;
  }

  // Update usage stats
  apiKey.usageCount += 1;
  apiKey.lastUsedAt = new Date();
  await apiKeyRepository.save(apiKey);

  return apiKey;
}

/**
 * Create API key for user
 */
export async function createApiKey(
  userId: string,
  options?: {
    rateLimit?: number;
    expiresAt?: Date;
  }
): Promise<{ key: string; apiKey: ApiKey }> {
  const rawKey = generateApiKey();
  const hashedKey = await hashApiKey(rawKey);

  const apiKey = apiKeyRepository.create({
    key: hashedKey,
    userId,
    rateLimit: options?.rateLimit,
    expiresAt: options?.expiresAt,
    isActive: true,
  });

  const saved = await apiKeyRepository.save(apiKey);

  return { key: rawKey, apiKey: saved };
}