Skip to content
Snippets Groups Projects

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

Compare and
5 files
+ 1282
10
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");
@@ -427,7 +433,7 @@ function getCertificateForPassport(passportUUID, internal) {
const passportIdentity = window.currentlyAuthenticatedIdentity;
const passport = passportIdentity.getPassport(passportUUID);
if (passport === undefined || passport === null) {
createPassportCertificate(passportUUID).then(function(keys) {
createPassportCertificate(passportUUID).then(function (keys) {
const cryptoData = new CryptoData();
cryptoData.setPublicKey(keys["publicKeyPEM"]);
cryptoData.setPrivateKey(keys["privateKeyPEM"]);
@@ -545,7 +551,7 @@ const connection = Penpal.connectToParent({
...penpalMethods,
createIdentity(pinCode) {
return new Penpal.Promise(result => {
createPassportCertificate(makeid()).then(function(keys) {
createPassportCertificate(makeid()).then(function (keys) {
const newIdentity = new Identity();
const cryptoData = new CryptoData();
cryptoData.setPublicKey(keys["publicKeyPEM"]);
@@ -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,152 @@ const connection = Penpal.connectToParent({
});
});
},
identityInitiateSocialRecovery: async accessToken => {
const response = await executeRestfulFunction(
"public",
viamApi,
viamApi.identityInitiateSocialRecovery,
null,
accessToken
);
return response;
},
contactsCheckAccountRecoveryStatus: async restoreAccessIdentity => {
window.currentlyLoadedIdentity = restoreAccessIdentity;
const {
publicKey,
x509Certificate
} = restoreAccessIdentity.authentication;
window.loadedIdentities[publicKey] = restoreAccessIdentity;
window.viamApi.setSessionData("", "");
window.viamApi.setIdentity(publicKey);
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));
async function checkAccountRecoveryStatus() {
const response = await executeRestfulFunction(
"public",
viamApi,
viamApi.contactsCheckAccountRecoveryStatus,
null
);
if (response.data === 0) {
await timeout(1000);
await checkAccountRecoveryStatus();
return;
}
const deviceHash = await createDeviceHash(publicKey);
window.viamApi.setDeviceHash(deviceHash);
const identityLoginResponse = await executeRestfulFunction(
"public",
window.viamApi,
window.viamApi.identityLogin,
null,
"previousaddeddevice"
);
const { code, data } = identityLoginResponse;
if (code === "200") {
handleIdentityLogin(restoreAccessIdentity, data.Uuid, data.Session);
await getProfileData(restoreAccessIdentity);
await setIdentityInLocalStorage(restoreAccessIdentity);
}
}
await checkAccountRecoveryStatus();
},
contactsGetTrusteeContactsPublicKeys: async () => {
try {
const response = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.contactsGetTrusteeContactsPublicKeys,
null
);
if (response.code !== "200") {
return response;
}
const responseData = response.data;
const trusteesDevices = Object.values(responseData);
/** Check if there are new trustees without added secret part */
const hasNewTrustees = trusteesDevices.some(device => {
const deviceData = Object.values(device);
return deviceData.some(data => data.hasShamir === "0");
});
if (!hasNewTrustees) {
return response;
}
// Generate and split recovery key
const trusteesUuids = Object.keys(responseData);
const trusteesToDevices = Object.entries(responseData);
const sharesNumber = trusteesUuids.length;
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(
trusteesToDevices.map(async ([contactUuid, device], index) => {
const deviceIdsToPublicKeys = Object.entries(device);
// Encrypt secret shares in parallel
const deviceIdsToEncryptedPartsList = await Promise.all(
deviceIdsToPublicKeys.map(async ([deviceId, { content }]) => {
const encryptedShare = await encryptShare(
recoveryKeyShares[index],
content
);
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
const saveShamirPartsResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.contactsSaveShamirParts,
null,
shamirParts
);
if (saveShamirPartsResponse !== "200") {
return saveShamirPartsResponse;
}
return response;
} catch (error) {
return encodeResponse("400", "", error.message);
}
},
parseSMIME,
getCurrentlyLoggedInUUID() {
return new Penpal.Promise(result => {
@@ -1067,7 +1216,7 @@ const connection = Penpal.connectToParent({
emailArg,
passportPrivateKey,
passportCertificate
).then(function(keys) {
).then(function (keys) {
const publicKeyOneTime = keys["publicKeyPEM"];
const privateKeyOneTime = keys["privateKeyPEM"];
const certificateOneTime = keys["certificatePEM"];
@@ -2169,7 +2318,7 @@ connection.promise.then(parent => {
let previousLocalStorageToken;
let previousLocalStorageIdentity;
setInterval(async function() {
setInterval(async function () {
if (window.currentlyAuthenticatedIdentity) {
const { authentication } = window.currentlyAuthenticatedIdentity;
const pinCode = getPincode(authentication.publicKey);
Loading