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 };
}
|