fix document 500 error
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user