Skip to content
Snippets Groups Projects

908 account recovery ability to add contacts to trusted contacts list for account recovery

Compare and
5 files
+ 1228
6
Compare changes
  • Side-by-side
  • Inline
Files
5
@@ -40,6 +40,12 @@ import {
STATUS_USER_BLOCKED
} from "../constants/statuses";
import generateQrCode from "../utilities/generateQrCode";
import {
generateRecoveryKey,
getRecoveryKeyShares,
checkRecoveryKeyCombine,
encryptShare
} from "../utilities/secrets";
const penpalMethods = require("../../temp/penpal-methods").default;
const WopiAPI = require("./wopiapi-iframe");
@@ -717,10 +723,7 @@ const connection = Penpal.connectToParent({
});
});
},
finalizeEmployeeRegistration: async (
identity,
identifier
) => {
finalizeEmployeeRegistration: async (identity, identifier) => {
viamApi.setIdentity(identity.authentication.publicKey);
return executeRestfulFunction(
"public",
@@ -970,6 +973,103 @@ const connection = Penpal.connectToParent({
});
});
},
contactsGetTrusteeContactsPublicKeys: async () => {
try {
const response = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.contactsGetTrusteeContactsPublicKeys,
null
);
const responseData = response.data;
const trusteesUuids = Object.keys(responseData);
const contactsToDevices = Object.entries(responseData);
const sharesNumber = trusteesUuids.length;
if (!sharesNumber) {
return encodeResponse("400", "", response.status);
}
const generateAndSaveRecoveryKey = async () => {
const recoveryKey = generateRecoveryKey();
const recoveryKeyShares = getRecoveryKeyShares(
recoveryKey,
sharesNumber
);
const sanityCheckResponse = checkRecoveryKeyCombine(
recoveryKey,
recoveryKeyShares
);
if (sanityCheckResponse.code !== "200") {
return sanityCheckResponse;
}
// Encrypt each share with every publicKey of each contact device
const shamirPartsList = await Promise.all(
contactsToDevices.map(async ([contactUuid, device], index) => {
const deviceIdsToPublicKeys = Object.entries(device);
// Encrypt secret shares in parallel
const deviceIdsToEncryptedPartsList = await Promise.all(
deviceIdsToPublicKeys.map(async ([deviceId, publicKey]) => {
const encryptedShare = await encryptShare(
recoveryKeyShares[index],
publicKey
);
return [deviceId, encryptedShare];
})
);
// Turn deviceIdsToEncryptedPartsList array to object
const deviceIdsToEncryptedParts = Object.fromEntries(
deviceIdsToEncryptedPartsList
);
return [contactUuid, deviceIdsToEncryptedParts];
})
);
// Turn shamirPartsList array to object
const shamirParts = Object.fromEntries(shamirPartsList);
// Save Shamir parts to database
await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.contactsSaveShamirParts,
null,
shamirParts
);
// Store trustees devices in localStorage
const trusteesToDevicesList = contactsToDevices.reduce(
(acc, [trusteeUuid, devicesToPublicKeys]) => {
acc[trusteeUuid] = Object.keys(devicesToPublicKeys);
return acc;
},
{}
);
localStorage.setItem(
"trustees",
JSON.stringify(trusteesToDevicesList)
);
};
// Check for changes in trustees
const storedTrustees = localStorage.getItem("trustees");
if (storedTrustees) {
const prevTrustees = JSON.parse(storedTrustees);
if (Object.keys(prevTrustees).length !== trusteesUuids.length) {
await generateAndSaveRecoveryKey();
}
} else {
await generateAndSaveRecoveryKey();
}
return response;
} catch (error) {
return encodeResponse("400", "", error.message);
}
},
parseSMIME,
getCurrentlyLoggedInUUID() {
return new Penpal.Promise(result => {
Loading