Initial commit with Email Import Wizard and Task Processor updates

This commit is contained in:
2026-05-04 08:02:11 +02:00
commit effdc5d59f
170 changed files with 67739 additions and 0 deletions
@@ -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');
}
}