fix document 500 error

This commit is contained in:
lendry
2026-06-26 10:20:29 +03:00
parent dd4323ba51
commit ead3155ad8
2 changed files with 63 additions and 7 deletions

View File

@@ -124,17 +124,47 @@ export class DocumentsService {
} }
private toResponse(document: Awaited<ReturnType<PrismaService['userDocument']['create']>>) { private toResponse(document: Awaited<ReturnType<PrismaService['userDocument']['create']>>) {
const metadata = document.metadata as { encryptedPayload?: string } | null;
return { return {
id: document.id, id: document.id,
userId: document.userId, userId: document.userId,
type: document.type, type: document.type,
number: this.encryption.decrypt(document.number), number: this.encryption.decryptIfNeeded(document.number),
issuedAt: document.issuedAt?.toISOString(), issuedAt: this.formatOptionalDate(document.issuedAt),
expiresAt: document.expiresAt?.toISOString(), expiresAt: this.formatOptionalDate(document.expiresAt),
metadataJson: metadata?.encryptedPayload ? this.encryption.decrypt(metadata.encryptedPayload) : undefined, metadataJson: this.resolveMetadataJson(document.metadata),
createdAt: document.createdAt.toISOString(), createdAt: this.formatRequiredDate(document.createdAt),
updatedAt: document.updatedAt.toISOString() updatedAt: this.formatRequiredDate(document.updatedAt)
}; };
} }
private resolveMetadataJson(metadata: Prisma.JsonValue | null): string | undefined {
if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata)) {
return undefined;
}
const record = metadata as Record<string, unknown>;
if (typeof record.encryptedPayload === 'string') {
return this.encryption.decryptIfNeeded(record.encryptedPayload);
}
if (Object.keys(record).length === 0) {
return undefined;
}
return JSON.stringify(record);
}
private formatOptionalDate(value: Date | null | undefined): string | undefined {
if (!value || Number.isNaN(value.getTime())) {
return undefined;
}
return value.toISOString();
}
private formatRequiredDate(value: Date): string {
if (Number.isNaN(value.getTime())) {
return new Date(0).toISOString();
}
return value.toISOString();
}
} }

View File

@@ -15,6 +15,21 @@ export class EncryptionService {
return `${iv.toString('base64url')}.${authTag.toString('base64url')}.${encrypted.toString('base64url')}`; return `${iv.toString('base64url')}.${authTag.toString('base64url')}.${encrypted.toString('base64url')}`;
} }
looksEncrypted(value: string): boolean {
const parts = value.split('.');
if (parts.length !== 3) return false;
const [ivRaw, authTagRaw, encryptedRaw] = parts;
if (!ivRaw || !authTagRaw || !encryptedRaw) return false;
try {
Buffer.from(ivRaw, 'base64url');
Buffer.from(authTagRaw, 'base64url');
Buffer.from(encryptedRaw, 'base64url');
return true;
} catch {
return false;
}
}
decrypt(value: string): string { decrypt(value: string): string {
const [ivRaw, authTagRaw, encryptedRaw] = value.split('.'); const [ivRaw, authTagRaw, encryptedRaw] = value.split('.');
if (!ivRaw || !authTagRaw || !encryptedRaw) { if (!ivRaw || !authTagRaw || !encryptedRaw) {
@@ -25,4 +40,15 @@ export class EncryptionService {
const decrypted = Buffer.concat([decipher.update(Buffer.from(encryptedRaw, 'base64url')), decipher.final()]); const decrypted = Buffer.concat([decipher.update(Buffer.from(encryptedRaw, 'base64url')), decipher.final()]);
return decrypted.toString('utf8'); return decrypted.toString('utf8');
} }
decryptIfNeeded(value: string): string {
if (!this.looksEncrypted(value)) {
return value;
}
try {
return this.decrypt(value);
} catch {
return value;
}
}
} }