Initial commit with Email Import Wizard and Task Processor updates
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { ApiKey } from '../database/entities/api-key.entity';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
@Injectable()
|
||||
export class ApiKeysService {
|
||||
constructor(
|
||||
@InjectRepository(ApiKey)
|
||||
private readonly apiKeyRepo: Repository<ApiKey>,
|
||||
) {}
|
||||
|
||||
async createApiKey(name: string, expiresDays?: number): Promise<{ plainKey: string; entity: ApiKey }> {
|
||||
const prefix = 'pm_';
|
||||
const randomPart = crypto.randomBytes(24).toString('hex'); // 48 chars hex
|
||||
const plainKey = `${prefix}${randomPart}`;
|
||||
|
||||
const keyHash = this.hashKey(plainKey);
|
||||
|
||||
const apiKey = this.apiKeyRepo.create({
|
||||
name,
|
||||
keyPrefix: prefix,
|
||||
keyHash,
|
||||
expiresAt: expiresDays ? new Date(Date.now() + expiresDays * 24 * 60 * 60 * 1000) : null,
|
||||
});
|
||||
|
||||
const savedKey = await this.apiKeyRepo.save(apiKey);
|
||||
|
||||
return {
|
||||
plainKey,
|
||||
entity: savedKey,
|
||||
};
|
||||
}
|
||||
|
||||
async validateKey(plainKey: string): Promise<ApiKey> {
|
||||
const keyHash = this.hashKey(plainKey);
|
||||
|
||||
const apiKey = await this.apiKeyRepo.findOne({
|
||||
where: { keyHash },
|
||||
});
|
||||
|
||||
if (!apiKey) {
|
||||
throw new UnauthorizedException('Invalid API Key');
|
||||
}
|
||||
|
||||
if (apiKey.expiresAt && apiKey.expiresAt < new Date()) {
|
||||
throw new UnauthorizedException('API Key has expired');
|
||||
}
|
||||
|
||||
// Update last used timestamp (async, don't wait for it to return response faster)
|
||||
apiKey.lastUsedAt = new Date();
|
||||
this.apiKeyRepo.save(apiKey).catch(err => console.error('Error updating lastUsedAt:', err));
|
||||
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
async listKeys(): Promise<ApiKey[]> {
|
||||
return this.apiKeyRepo.find({
|
||||
order: { createdAt: 'DESC' },
|
||||
});
|
||||
}
|
||||
|
||||
async deleteKey(id: string): Promise<void> {
|
||||
await this.apiKeyRepo.delete(id);
|
||||
}
|
||||
|
||||
private hashKey(key: string): string {
|
||||
return crypto.createHash('sha256').update(key).digest('hex');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user