feat: add modular services and repositories for improved code organization
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.
This commit is contained in:
58
backend/src/crypto/services/encryption.service.ts
Normal file
58
backend/src/crypto/services/encryption.service.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import * as jose from "jose";
|
||||
|
||||
@Injectable()
|
||||
export class EncryptionService {
|
||||
private readonly logger = new Logger(EncryptionService.name);
|
||||
private readonly jwtSecret: Uint8Array;
|
||||
private readonly encryptionKey: Uint8Array;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
const secret = this.configService.get<string>("JWT_SECRET");
|
||||
this.jwtSecret = new TextEncoder().encode(
|
||||
secret || "default-secret-change-me-in-production",
|
||||
);
|
||||
|
||||
const encKey = this.configService.get<string>("ENCRYPTION_KEY");
|
||||
if (!encKey) {
|
||||
this.logger.warn(
|
||||
"ENCRYPTION_KEY is not defined, using a default insecure key for development",
|
||||
);
|
||||
}
|
||||
const rawKey = encKey || "default-encryption-key-32-chars-";
|
||||
this.encryptionKey = new TextEncoder().encode(
|
||||
rawKey.padEnd(32, "0").substring(0, 32),
|
||||
);
|
||||
}
|
||||
|
||||
async encryptContent(content: string): Promise<string> {
|
||||
const data = new TextEncoder().encode(content);
|
||||
return new jose.CompactEncrypt(data)
|
||||
.setProtectedHeader({ alg: "dir", enc: "A256GCM" })
|
||||
.encrypt(this.encryptionKey);
|
||||
}
|
||||
|
||||
async decryptContent(jwe: string): Promise<string> {
|
||||
const { plaintext } = await jose.compactDecrypt(jwe, this.encryptionKey);
|
||||
return new TextDecoder().decode(plaintext);
|
||||
}
|
||||
|
||||
async signContent(content: string): Promise<string> {
|
||||
const data = new TextEncoder().encode(content);
|
||||
return new jose.CompactSign(data)
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.sign(this.jwtSecret);
|
||||
}
|
||||
|
||||
async verifyContentSignature(jws: string): Promise<string> {
|
||||
const { payload } = await jose.compactVerify(jws, this.jwtSecret);
|
||||
return new TextDecoder().decode(payload);
|
||||
}
|
||||
|
||||
getPgpEncryptionKey(): string {
|
||||
return (
|
||||
this.configService.get<string>("PGP_ENCRYPTION_KEY") || "default-pgp-key"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user