-
-
Notifications
You must be signed in to change notification settings - Fork 440
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f56d371
commit 4f8b4a3
Showing
40 changed files
with
1,776 additions
and
1,887 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/** @odoo-module alias=vault.export **/ | ||
// © 2021-2022 Florian Kantelberg - initOS GmbH | ||
// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
import {_t} from "web.core"; | ||
import utils from "vault.utils"; | ||
|
||
// This class handles the export to different formats by using a standardize | ||
// JSON formatted data generated by the python backend. | ||
// | ||
// JSON format description: | ||
// | ||
// Entries are represented as objects with the following attributes | ||
// `name`, `uuid`, `url`, `note` | ||
// Specific fields of the entry. `uuid` is used for updating existing records | ||
// `childs` | ||
// Child entries | ||
// `fields`, `files` | ||
// List of encypted fields/files with `name`, `iv`, and `value` | ||
// | ||
export default class VaultExporter { | ||
/** | ||
* Encrypt a field of the above format properly for the backend to store. | ||
* The changes are done inplace. | ||
* | ||
* @private | ||
* @param {CryptoKey} master_key | ||
* @param {Object} node | ||
*/ | ||
async _export_json_entry(master_key, node) { | ||
const fields = []; | ||
for (const field of node.fields || []) | ||
fields.push({ | ||
name: field.name, | ||
value: await utils.sym_decrypt(master_key, field.value, field.iv), | ||
}); | ||
|
||
const files = []; | ||
for (const file of node.files || []) | ||
files.push({ | ||
name: file.name, | ||
value: await utils.sym_decrypt(master_key, file.value, file.iv), | ||
}); | ||
|
||
const childs = []; | ||
for (const entry of node.childs || []) | ||
childs.push(await this._export_json_entry(master_key, entry)); | ||
|
||
return { | ||
name: node.name || "", | ||
uuid: node.uuid || null, | ||
url: node.url || "", | ||
note: node.note || "", | ||
childs: childs, | ||
fields: fields, | ||
files: files, | ||
}; | ||
} | ||
|
||
/** | ||
* Decrypt the data fro the JSON export. | ||
* | ||
* @private | ||
* @param {CryptoKey} master_key | ||
* @param {Object} data | ||
* @returns the encrypted entry for the database | ||
*/ | ||
async _export_json_data(master_key, data) { | ||
const result = []; | ||
for (const node of data) | ||
result.push(await this._export_json_entry(master_key, node)); | ||
return JSON.stringify(result); | ||
} | ||
|
||
/** | ||
* Export using JSON format. The database is stored in the `data` field of the JSON | ||
* type and is an encrypted JSON object. For the encryption the needed encryption | ||
* parameter `iv`, `salt` and `iterations` are stored in the file. | ||
* This will add `iv` to fields and files and encrypt the `value` | ||
* | ||
* @private | ||
* @param {CryptoKey} master_key | ||
* @param {String} data | ||
* @returns the encrypted entry for the database | ||
*/ | ||
async _export_json(master_key, data) { | ||
// Get the password for the exported file from the user | ||
const askpass = await utils.askpass( | ||
_t("Please enter the password for the database") | ||
); | ||
let password = askpass.password || ""; | ||
if (askpass.keyfile) | ||
password += await utils.digest(utils.toBinary(askpass.keyfile)); | ||
|
||
const iv = utils.generate_iv_base64(); | ||
const salt = utils.generate_bytes(utils.SaltLength).buffer; | ||
const iterations = 4000; | ||
const key = await utils.derive_key(password, salt, iterations); | ||
|
||
// Unwrap the master key and decrypt the entries | ||
const content = await this._export_json_data(master_key, JSON.parse(data)); | ||
return { | ||
type: "encrypted", | ||
iv: iv, | ||
salt: utils.toBase64(salt), | ||
data: await utils.sym_encrypt(key, content, iv), | ||
iterations: iterations, | ||
}; | ||
} | ||
|
||
/** | ||
* The main export functions which checks the file ending and calls the right function | ||
* to handle the rest of the export | ||
* | ||
* @private | ||
* @param {CryptoKey} master_key | ||
* @param {String} filename | ||
* @param {String} content | ||
* @returns the data importable by the backend or false on error | ||
*/ | ||
async export(master_key, filename, content) { | ||
if (!utils.supported()) return false; | ||
|
||
if (filename.endsWith(".json")) | ||
return await this._export_json(master_key, content); | ||
return false; | ||
} | ||
} |
Oops, something went wrong.