Introduce repository pattern across multiple services, including `favorites`, `tags`, `sessions`, `reports`, `auth`, and more. Decouple crypto functionalities into modular services like `HashingService`, `JwtService`, and `EncryptionService`. Improve testability and maintainability by simplifying dependencies and consolidating utility logic.
59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import { and, eq } from "drizzle-orm";
|
|
import { DatabaseService } from "../../database/database.service";
|
|
import { apiKeys } from "../../database/schemas";
|
|
|
|
@Injectable()
|
|
export class ApiKeysRepository {
|
|
constructor(private readonly databaseService: DatabaseService) {}
|
|
|
|
async create(data: {
|
|
userId: string;
|
|
name: string;
|
|
prefix: string;
|
|
keyHash: string;
|
|
expiresAt?: Date;
|
|
}) {
|
|
return await this.databaseService.db.insert(apiKeys).values(data);
|
|
}
|
|
|
|
async findAll(userId: string) {
|
|
return await this.databaseService.db
|
|
.select({
|
|
id: apiKeys.id,
|
|
name: apiKeys.name,
|
|
prefix: apiKeys.prefix,
|
|
isActive: apiKeys.isActive,
|
|
lastUsedAt: apiKeys.lastUsedAt,
|
|
expiresAt: apiKeys.expiresAt,
|
|
createdAt: apiKeys.createdAt,
|
|
})
|
|
.from(apiKeys)
|
|
.where(eq(apiKeys.userId, userId));
|
|
}
|
|
|
|
async revoke(userId: string, keyId: string) {
|
|
return await this.databaseService.db
|
|
.update(apiKeys)
|
|
.set({ isActive: false, updatedAt: new Date() })
|
|
.where(and(eq(apiKeys.id, keyId), eq(apiKeys.userId, userId)))
|
|
.returning();
|
|
}
|
|
|
|
async findActiveByKeyHash(keyHash: string) {
|
|
const result = await this.databaseService.db
|
|
.select()
|
|
.from(apiKeys)
|
|
.where(and(eq(apiKeys.keyHash, keyHash), eq(apiKeys.isActive, true)))
|
|
.limit(1);
|
|
return result[0] || null;
|
|
}
|
|
|
|
async updateLastUsed(id: string) {
|
|
return await this.databaseService.db
|
|
.update(apiKeys)
|
|
.set({ lastUsedAt: new Date() })
|
|
.where(eq(apiKeys.id, id));
|
|
}
|
|
}
|