Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 32 additions & 27 deletions vault/static/src/backend/controller.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,37 +71,42 @@ patch(FormController.prototype, {
* @private
*/
async _newVaultKeyPair() {
// Get the current private key
const private_key = await this.vault.get_private_key();

// Generate new keys
await this.vault.generate_keys();

const public_key = await this.vault.get_public_key();
this.uuid = await this.vault._check_database();
if (this.uuid) {
// The user has a private key so get it
const private_key = await this.vault.get_private_key();

// Generate new keys
await this.vault.generate_keys();

const public_key = await this.vault.get_public_key();

// Re-encrypt the master keys
const master_keys = await rpc("/vault/rights/get");
let result = {};
for (const uuid in master_keys) {
result[uuid] = await this.vault_utils.wrap(
await this.vault_utils.unwrap(master_keys[uuid], private_key),
public_key
);
}

// Re-encrypt the master keys
const master_keys = await rpc("/vault/rights/get");
let result = {};
for (const uuid in master_keys) {
result[uuid] = await this.vault_utils.wrap(
await this.vault_utils.unwrap(master_keys[uuid], private_key),
public_key
);
}
await rpc("/vault/rights/store", {keys: result});

await rpc("/vault/rights/store", {keys: result});
// Re-encrypt the inboxes to not loose it
const inbox_keys = await rpc("/vault/inbox/get");
result = {};
for (const uuid in inbox_keys) {
result[uuid] = await this.vault_utils.wrap(
await this.vault_utils.unwrap(inbox_keys[uuid], private_key),
public_key
);
}

// Re-encrypt the inboxes to not loose it
const inbox_keys = await rpc("/vault/inbox/get");
result = {};
for (const uuid in inbox_keys) {
result[uuid] = await this.vault_utils.wrap(
await this.vault_utils.unwrap(inbox_keys[uuid], private_key),
public_key
);
await rpc("/vault/inbox/store", {keys: result});
} else {
await this.vault._initialize_keys();
}

await rpc("/vault/inbox/store", {keys: result});
},

/**
Expand Down
33 changes: 25 additions & 8 deletions vault/static/src/backend/fields/vault_export_file.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,38 @@ export class VaultExportFile extends VaultMixin(BinaryField) {
this.exporter = useService("vault_export");
this.vault_utils = useService("vault_utils");
}

/**
* Get the value saved on db because the system is showing just the
* size on the props.
*
* @param {Object} ev
*/
async _getCryptedValue() {
const crypted = await this.orm.read(
this.props.record.resModel,
[this.props.record.resId],
[this.props.name]
);
return crypted[0][this.props.name];
}

/**
* Call the exporter and download the finalized file
*/
async onFileDownload() {
if (!this.props.value) {
this.do_warn(
_t("Save As..."),
_t("The field is empty, there's nothing to save!")
);
const cryptedValue = await this._getCryptedValue();
if (!cryptedValue) {
this.notification.add(_t("The field is empty, there's nothing to save!"), {
title: _t("Save As..."),
type: "danger",
});
} else if (this.vault_utils.supported()) {
const content = JSON.stringify(
await this.exporter.export(
await this._getMasterKey(),
this.state.fileName,
this.props.value
this.fileName,
cryptedValue
)
);

Expand All @@ -38,7 +55,7 @@ export class VaultExportFile extends VaultMixin(BinaryField) {
for (let i = 0; i < content.length; i++) arr[i] = content.charCodeAt(i);

const blob = new Blob([arr]);
await downloadFile(blob, this.state.fileName || "");
await downloadFile(blob, this.fileName || "");
}
}
}
Expand Down
35 changes: 26 additions & 9 deletions vault/static/src/backend/fields/vault_file.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export class VaultFile extends VaultMixin(BinaryField) {
static template = "vault.FileVault";
setup() {
super.setup();

this.orm = useService("orm");
this.notification = useService("notification");
this.action = useService("action");
}

Expand All @@ -21,6 +22,21 @@ export class VaultFile extends VaultMixin(BinaryField) {
return await super.update({data: encrypted, name: name});
}

/**
* Get the value saved on db because the system is showing just the
* size on the props.
*
* @param {Object} ev
*/
async _getCryptedValue() {
const crypted = await this.orm.read(
this.props.record.resModel,
[this.props.record.resId],
[this.props.name]
);
return crypted[0][this.props.name];
}

/**
* Send the secret to an inbox of an user
*
Expand All @@ -29,27 +45,28 @@ export class VaultFile extends VaultMixin(BinaryField) {
async _onSendValue(ev) {
ev.stopPropagation();

await this.sendValue("", this.props.value, this.state.fileName);
await this.sendValue("", await this._getCryptedValue(), this.fileName);
}

/**
* Decrypt the file and download it
*/
async onFileDownload() {
if (!this.props.value) {
this.do_warn(
_t("Save As..."),
_t("The field is empty, there's nothing to save!")
);
const cryptedValue = await this._getCryptedValue();
if (!cryptedValue) {
this.notification.add(_t("The field is empty, there's nothing to save!"), {
title: _t("Save As..."),
type: "danger",
});
} else if (this.vault_utils.supported()) {
const decrypted = await this._decrypt(this.props.value);
const decrypted = await this._decrypt(cryptedValue);
const base64 = atob(decrypted);
const buffer = new ArrayBuffer(base64.length);
const arr = new Uint8Array(buffer);
for (let i = 0; i < base64.length; i++) arr[i] = base64.charCodeAt(i);

const blob = new Blob([arr]);
await downloadFile(blob, this.state.fileName || "");
await downloadFile(blob, this.fileName || "");
}
}
}
Expand Down
18 changes: 0 additions & 18 deletions vault/static/src/backend/vault.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,6 @@ const vaultService = {
}

class Vault {
/**
* Check if the user actually has keys otherwise generate them on init
*
* @override
*/
constructor() {
const self = this;

function waitAndCheck() {
if (!vault_utils.supported()) return null;

if (odoo.isReady) self._initialize_keys();
else setTimeout(waitAndCheck, 500);
}

setTimeout(waitAndCheck, 500);
}

/**
* Generate a new key pair and export to database and object store
*/
Expand Down
8 changes: 2 additions & 6 deletions vault/static/src/common/vault_utils_service.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export class AskPassDialog extends Component {
}

onCancel() {
this.props.onReject(_t("Cancelled"));
this.props.close();
}
}
Expand Down Expand Up @@ -88,7 +87,6 @@ export class GeneratePassDialog extends Component {
}

onCancel() {
this.props.onReject(_t("Cancelled"));
this.props.close();
}

Expand All @@ -111,22 +109,20 @@ export const vaultUtilsService = {
title,
confirm: Boolean(options.confirm),
};
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
dialog.add(AskPassDialog, {
...props,
onResolve: resolve,
onReject: reject,
});
});
}

function generate_pass(title, options = {}) {
const props = {title, ...options};
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
dialog.add(GeneratePassDialog, {
...props,
onResolve: resolve,
onReject: reject,
});
});
}
Expand Down
Loading