Add decryptAttribute

This commit is contained in:
Sosthene 2025-08-25 01:12:30 +02:00
parent bd10842a53
commit 33dbf552a6

View File

@ -1108,6 +1108,77 @@ export class Service {
} }
} }
async decryptAttribute(processId: string, state: ProcessState, attribute: string): Promise<any | null> {
let hash = state.pcd_commitment[attribute];
if (!hash) {
// attribute doesn't exist
return null;
}
let key = state.keys[attribute];
const pairingProcessId = this.getPairingProcessId();
// If key is missing, request an update and then retry
if (!key) {
const roles = state.roles;
let hasAccess = false;
// If we're not supposed to have access to this attribute, ignore
for (const role of Object.values(roles)) {
for (const rule of Object.values(role.validation_rules)) {
if (rule.fields.includes(attribute)) {
if (role.members.includes(pairingProcessId)) {
// We have access to this attribute
hasAccess = true;
break;
}
}
}
}
if (!hasAccess) return null;
// We should have the key, so we're going to ask other members for it
await this.requestDataFromPeers(processId, [state.state_id], [state.roles]);
const maxRetries = 5;
const retryDelay = 500; // delay in milliseconds
let retries = 0;
while ((!hash || !key) && retries < maxRetries) {
await new Promise(resolve => setTimeout(resolve, retryDelay));
// Re-read hash and key after waiting
hash = state.pcd_commitment[attribute];
key = state.keys[attribute];
retries++;
}
}
if (hash && key) {
const blob = await this.getBlobFromDb(hash);
if (blob) {
// Decrypt the data
const buf = await blob.arrayBuffer();
const cipher = new Uint8Array(buf);
const keyUIntArray = this.hexToUInt8Array(key);
try {
const clear = wasm.decrypt_data(keyUIntArray, cipher);
if (clear) {
// deserialize the result to get the actual data
const decoded = wasm.decode_value(clear);
return decoded;
} else {
throw new Error('decrypt_data returned null');
}
} catch (e) {
console.error(`Failed to decrypt data: ${e}`);
}
}
}
return null;
}
decodeValue(value: number[]): any | null { decodeValue(value: number[]): any | null {
try { try {
return wasm.decode_value(new Uint8Array(value)); return wasm.decode_value(new Uint8Array(value));