Add import/exportUserDataBackup
This commit is contained in:
parent
39d57d4749
commit
848777d751
@ -6,7 +6,7 @@ import ModalService from './modal.service';
|
|||||||
import Database from './database.service';
|
import Database from './database.service';
|
||||||
import { navigate } from '../router';
|
import { navigate } from '../router';
|
||||||
import { storeData, retrieveData, testData } from './storage.service';
|
import { storeData, retrieveData, testData } from './storage.service';
|
||||||
import { BackUp } from '~/models/backup.model';
|
import { UserDataBackUp } from '~/models/backup.model';
|
||||||
import { PDFDocument, rgb, StandardFonts } from 'pdf-lib';
|
import { PDFDocument, rgb, StandardFonts } from 'pdf-lib';
|
||||||
|
|
||||||
export const U32_MAX = 4294967295;
|
export const U32_MAX = 4294967295;
|
||||||
@ -1210,48 +1210,68 @@ export default class Services {
|
|||||||
this.notifications = notifications;
|
this.notifications = notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
async importJSON(backup: BackUp): Promise<void> {
|
public async importUserDataBackup(backup: UserDataBackUp): Promise<void> {
|
||||||
const device = JSON.stringify(backup.device);
|
try {
|
||||||
|
if (typeof backup.user_data.device === 'string') {
|
||||||
|
throw new Error('Must decrypt backup first');
|
||||||
|
}
|
||||||
|
// Reset current device
|
||||||
|
await this.resetDevice();
|
||||||
|
|
||||||
// Reset current device
|
await this.saveDeviceInDatabase(backup.user_data.device);
|
||||||
await this.resetDevice();
|
|
||||||
|
|
||||||
await this.saveDeviceInDatabase(device);
|
this.restoreDevice(backup.user_data.device);
|
||||||
|
|
||||||
this.restoreDevice(device);
|
const secretsStore = backup.user_data.secrets as SecretsStore;
|
||||||
|
await this.restoreSecretsFromBackUp(secretsStore);
|
||||||
|
|
||||||
// TODO restore secrets and processes from file
|
const processes = backup.user_data.processes as Record<string, Process>;
|
||||||
const secretsStore = backup.secrets;
|
await this.restoreProcessesFromBackUp(processes);
|
||||||
await this.restoreSecretsFromBackUp(secretsStore);
|
} catch (e) {
|
||||||
|
// TODO reset everything
|
||||||
const processes = backup.processes;
|
throw new Error(`Failed to import user data backup: ${e}`);
|
||||||
await this.restoreProcessesFromBackUp(processes);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createBackUp(): Promise<BackUp | null> {
|
public async exportUserDataBackup(password: string | undefined | null): Promise<UserDataBackUp> {
|
||||||
// Get the device from indexedDB
|
try {
|
||||||
const deviceStr = await this.getDeviceFromDatabase();
|
const userData = {
|
||||||
if (!deviceStr) {
|
device: this.dumpDeviceFromMemory(),
|
||||||
console.error('No device loaded');
|
secrets: await this.getAllSecrets(),
|
||||||
return null;
|
processes: await this.getProcesses(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Now hash the content of user data to produce a checksum
|
||||||
|
const textAsBuffer = new TextEncoder().encode(JSON.stringify(userData));
|
||||||
|
const hashBuffer = await window.crypto.subtle.digest("SHA-256", textAsBuffer);
|
||||||
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||||
|
const hash = hashArray
|
||||||
|
.map((item) => item.toString(16).padStart(2, "0"))
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
// We'll let the sdk handle the pbkdf and encryption
|
||||||
|
// this.sdkClient.encrypt_backup_data(password, JSON.stringify(userData));
|
||||||
|
// metadata.encrypted = true;
|
||||||
|
// userData
|
||||||
|
// textAsBuffer = enc.encode(cipher);
|
||||||
|
throw new Error('Encryption not implemented yet');
|
||||||
|
}
|
||||||
|
|
||||||
|
const metadata = {
|
||||||
|
encrypted: false,
|
||||||
|
checksum: hash,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
version: 1,
|
||||||
|
exported_at: new Date(),
|
||||||
|
user_data: userData,
|
||||||
|
metadata,
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to export user data backup: ${e}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const device: Device = JSON.parse(deviceStr);
|
|
||||||
|
|
||||||
// Get the processes
|
|
||||||
const processes = await this.getProcesses();
|
|
||||||
|
|
||||||
// Get the shared secrets
|
|
||||||
const secrets = await this.getAllSecrets();
|
|
||||||
|
|
||||||
// Create a backup object
|
|
||||||
const backUp = {
|
|
||||||
device: device,
|
|
||||||
secrets: secrets,
|
|
||||||
processes: processes,
|
|
||||||
};
|
|
||||||
|
|
||||||
return backUp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Device 1 wait Device 2
|
// Device 1 wait Device 2
|
||||||
@ -1490,6 +1510,11 @@ export default class Services {
|
|||||||
const membersList = this.getAllMembers();
|
const membersList = this.getAllMembers();
|
||||||
try {
|
try {
|
||||||
const res = this.sdkClient.request_data(processId, stateIds, roles, membersList);
|
const res = this.sdkClient.request_data(processId, stateIds, roles, membersList);
|
||||||
|
// If ciphers_to_send is empty, it means that there's nobody to ask the data to
|
||||||
|
if (res.ciphers_to_send.length === 0) {
|
||||||
|
console.warn('Data unavailable from peers');
|
||||||
|
return;
|
||||||
|
}
|
||||||
await this.handleApiReturn(res);
|
await this.handleApiReturn(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user