mirror of
https://gitlab.com/psono/psono-client
synced 2025-04-19 03:22:16 +03:00
Revert all changes after commit 52569f829a77530fae8c3302f11d0f8f02677c54
This commit is contained in:
parent
c6e53bcba5
commit
0018e1a79c
49
package-lock.json
generated
49
package-lock.json
generated
@ -26,6 +26,7 @@
|
||||
"core-js": "^3.19.1",
|
||||
"date-fns": "^2.26.0",
|
||||
"dompurify": "^3.1.0",
|
||||
"ecma-nacl": "^2.4.2",
|
||||
"ed25519-keygen": "^0.4.1",
|
||||
"fast-xml-parser": "^4.2.7",
|
||||
"file-saver": "^2.0.5",
|
||||
@ -36,7 +37,6 @@
|
||||
"js-sha1": "^0.6.0",
|
||||
"js-sha256": "^0.9.0",
|
||||
"js-sha512": "^0.8.0",
|
||||
"libsodium-wrappers": "^0.7.14",
|
||||
"localforage": "^1.10.0",
|
||||
"mui-datatables": "^4.3.0",
|
||||
"openpgp": "^5.11.0",
|
||||
@ -60,7 +60,6 @@
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-state-sync": "^3.1.2",
|
||||
"redux-thunk": "^2.4.0",
|
||||
"scrypt-async": "^2.0.1",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"uuid-js": "^0.7.5"
|
||||
},
|
||||
@ -6376,6 +6375,13 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ecma-nacl": {
|
||||
"version": "2.4.2",
|
||||
"license": "MPL-2.0",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ed25519-keygen": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ed25519-keygen/-/ed25519-keygen-0.4.1.tgz",
|
||||
@ -10458,19 +10464,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/libsodium": {
|
||||
"version": "0.7.14",
|
||||
"resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.14.tgz",
|
||||
"integrity": "sha512-/pOd7eO6oZrfORquRTC4284OUJFcMi8F3Vnc9xtRBT0teLfOUxWIItaBFF3odYjZ7nlJNwnLdUVEUFHxVyX/Sw=="
|
||||
},
|
||||
"node_modules/libsodium-wrappers": {
|
||||
"version": "0.7.14",
|
||||
"resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.14.tgz",
|
||||
"integrity": "sha512-300TtsePizhJZ7HjLmWr6hLHAgJUxIGhapSw+EwfCtDuWaEmEdGXSQv6j6qFw0bs9l4vS2NH9BtOHfXAq6h5kQ==",
|
||||
"dependencies": {
|
||||
"libsodium": "^0.7.14"
|
||||
}
|
||||
},
|
||||
"node_modules/lie": {
|
||||
"version": "3.1.1",
|
||||
"license": "MIT",
|
||||
@ -12559,11 +12552,6 @@
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/scrypt-async": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-2.0.1.tgz",
|
||||
"integrity": "sha512-wHR032jldwZNy7Tzrfu7RccOgGf8r5hyDMSP2uV6DpLiBUsR8JsDcx/in73o2UGVVrH5ivRFdNsFPcjtl3LErQ=="
|
||||
},
|
||||
"node_modules/select-hose": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
@ -19410,6 +19398,9 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"ecma-nacl": {
|
||||
"version": "2.4.2"
|
||||
},
|
||||
"ed25519-keygen": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ed25519-keygen/-/ed25519-keygen-0.4.1.tgz",
|
||||
@ -22398,19 +22389,6 @@
|
||||
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
|
||||
"dev": true
|
||||
},
|
||||
"libsodium": {
|
||||
"version": "0.7.14",
|
||||
"resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.14.tgz",
|
||||
"integrity": "sha512-/pOd7eO6oZrfORquRTC4284OUJFcMi8F3Vnc9xtRBT0teLfOUxWIItaBFF3odYjZ7nlJNwnLdUVEUFHxVyX/Sw=="
|
||||
},
|
||||
"libsodium-wrappers": {
|
||||
"version": "0.7.14",
|
||||
"resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.14.tgz",
|
||||
"integrity": "sha512-300TtsePizhJZ7HjLmWr6hLHAgJUxIGhapSw+EwfCtDuWaEmEdGXSQv6j6qFw0bs9l4vS2NH9BtOHfXAq6h5kQ==",
|
||||
"requires": {
|
||||
"libsodium": "^0.7.14"
|
||||
}
|
||||
},
|
||||
"lie": {
|
||||
"version": "3.1.1",
|
||||
"requires": {
|
||||
@ -23910,11 +23888,6 @@
|
||||
"ajv-keywords": "^3.5.2"
|
||||
}
|
||||
},
|
||||
"scrypt-async": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-2.0.1.tgz",
|
||||
"integrity": "sha512-wHR032jldwZNy7Tzrfu7RccOgGf8r5hyDMSP2uV6DpLiBUsR8JsDcx/in73o2UGVVrH5ivRFdNsFPcjtl3LErQ=="
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"dev": true
|
||||
|
@ -15,6 +15,7 @@
|
||||
"buildelectron": "webpack --config webpack.environment.prod.electron.js",
|
||||
"deployfirefox": "node ./var/firefox_deploy.js",
|
||||
"deploychrome": "node ./var/chrome_deploy.js",
|
||||
"buildsw": "node ./src/build-service-worker.js",
|
||||
"test": "jest --detectOpenHandles --forceExit"
|
||||
},
|
||||
"keywords": [],
|
||||
@ -37,6 +38,7 @@
|
||||
"core-js": "^3.19.1",
|
||||
"date-fns": "^2.26.0",
|
||||
"dompurify": "^3.1.0",
|
||||
"ecma-nacl": "^2.4.2",
|
||||
"ed25519-keygen": "^0.4.1",
|
||||
"fast-xml-parser": "^4.2.7",
|
||||
"file-saver": "^2.0.5",
|
||||
@ -47,7 +49,6 @@
|
||||
"js-sha1": "^0.6.0",
|
||||
"js-sha256": "^0.9.0",
|
||||
"js-sha512": "^0.8.0",
|
||||
"libsodium-wrappers": "^0.7.14",
|
||||
"localforage": "^1.10.0",
|
||||
"mui-datatables": "^4.3.0",
|
||||
"openpgp": "^5.11.0",
|
||||
@ -71,7 +72,6 @@
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-state-sync": "^3.1.2",
|
||||
"redux-thunk": "^2.4.0",
|
||||
"scrypt-async": "^2.0.1",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"uuid-js": "^0.7.5"
|
||||
},
|
||||
|
31
src/build-service-worker.js
Normal file
31
src/build-service-worker.js
Normal file
@ -0,0 +1,31 @@
|
||||
const workboxBuild = require('workbox-build');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const buildSW = () => {
|
||||
workboxBuild
|
||||
.injectManifest({
|
||||
swSrc: 'src/webclient/data/service-worker.js',
|
||||
swDest: 'build/service-worker.js',
|
||||
globDirectory: 'build/webclient/',
|
||||
globPatterns: [
|
||||
'**/*'
|
||||
],
|
||||
globIgnores: [
|
||||
'**/*.map'
|
||||
],
|
||||
compileSrc: true,
|
||||
maximumFileSizeToCacheInBytes: 20000000,
|
||||
webpackCompilationPlugins: [
|
||||
new webpack.DefinePlugin({
|
||||
CACHE_VERSION: JSON.stringify("test!")
|
||||
})
|
||||
]
|
||||
})
|
||||
.then(({ count, size, warnings }) => {
|
||||
// Optionally, log any warnings and details.
|
||||
warnings.forEach(console.warn);
|
||||
console.log(`${count} files will be precached, totaling ${size} bytes.`);
|
||||
})
|
||||
.catch(console.error);
|
||||
};
|
||||
buildSW();
|
@ -33,9 +33,6 @@
|
||||
"storage": {
|
||||
"managed_schema": "managed_storage.json"
|
||||
},
|
||||
"content_security_policy": {
|
||||
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
|
||||
},
|
||||
"icons": {
|
||||
"16": "data/img/icon-16.png",
|
||||
"32": "data/img/icon-32.png",
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -13,7 +13,7 @@ body {
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
margin: -190px 0 0 -170px;
|
||||
margin: -130px 0 0 -170px;
|
||||
border-radius: 4px; }
|
||||
.loginbox .progress-bar, .registerbox .progress-bar, .activationbox .progress-bar, .logoutsuccessbox .progress-bar, .lostpasswordbox .progress-bar {
|
||||
background-color: #2dbb93; }
|
||||
@ -24,7 +24,7 @@ body {
|
||||
@media only screen and (min-width: 600px) {
|
||||
.loginbox, .registerbox, .activationbox, .logoutsuccessbox, .lostpasswordbox {
|
||||
width: 540px;
|
||||
margin: -190px 0 0 -270px; } }
|
||||
margin: -130px 0 0 -270px; } }
|
||||
|
||||
.progress {
|
||||
margin-bottom: 0; }
|
||||
|
@ -31,7 +31,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
|
||||
</html>
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="js/bundle.min.js"></script>
|
||||
<script src="js/service-worker-load.js" type="application/javascript"></script>
|
||||
|
||||
|
@ -125,7 +125,7 @@ const DialogAcceptGroupShares = (props) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const onSuccess = async function (group_details) {
|
||||
const onSuccess = function (group_details) {
|
||||
const encryptedShares = [];
|
||||
for (let i = 0; i < group_details.group_share_rights.length; i++) {
|
||||
const share = group_details.group_share_rights[i];
|
||||
@ -141,7 +141,7 @@ const DialogAcceptGroupShares = (props) => {
|
||||
encryptedShares.push(share);
|
||||
}
|
||||
|
||||
const shares = await groupsService.decryptGroupShares(group.group_id, encryptedShares);
|
||||
const shares = groupsService.decryptGroupShares(group.group_id, encryptedShares);
|
||||
|
||||
return datastorePassword
|
||||
.createShareLinksInDatastore(
|
||||
|
@ -91,7 +91,7 @@ const DialogCreateLinkShare = (props) => {
|
||||
const copyToClipbard = (event) => {
|
||||
browserClient.copyToClipboard(() => Promise.resolve(linkShareAccessUrl));
|
||||
};
|
||||
const onCreate = async (event) => {
|
||||
const onCreate = (event) => {
|
||||
const linkShareSecret = cryptoLibraryService.generateSecretKey();
|
||||
|
||||
const content = {
|
||||
@ -115,7 +115,7 @@ const DialogCreateLinkShare = (props) => {
|
||||
content["file_title"] = props.item["file_title"];
|
||||
}
|
||||
|
||||
const itemEncrypted = await cryptoLibraryService.encryptData(JSON.stringify(content), linkShareSecret);
|
||||
const itemEncrypted = cryptoLibraryService.encryptData(JSON.stringify(content), linkShareSecret);
|
||||
|
||||
let validTillStr = null;
|
||||
if (validTill !== null) {
|
||||
@ -146,14 +146,14 @@ const DialogCreateLinkShare = (props) => {
|
||||
const encodedServerUrl = converter.toBase58(converter.encodeUtf8(getStore().getState().server.url));
|
||||
setLinkShareAccessUrl(
|
||||
info["data"]["decoded_info"]["web_client"] +
|
||||
"/link-share-access.html#!/link-share-access/" +
|
||||
result.link_share_id +
|
||||
"/" +
|
||||
linkShareSecret +
|
||||
"/" +
|
||||
encodedServerUrl +
|
||||
"/" +
|
||||
getStore().getState().server.verifyKey
|
||||
"/link-share-access.html#!/link-share-access/" +
|
||||
result.link_share_id +
|
||||
"/" +
|
||||
linkShareSecret +
|
||||
"/" +
|
||||
encodedServerUrl +
|
||||
"/" +
|
||||
getStore().getState().server.verifyKey
|
||||
);
|
||||
});
|
||||
};
|
||||
|
@ -115,7 +115,7 @@ const DialogEditGroup = (props) => {
|
||||
console.log(result);
|
||||
};
|
||||
|
||||
const onSuccess = async function (groupDetails) {
|
||||
const onSuccess = function (groupDetails) {
|
||||
if (!isSubscribed) return;
|
||||
const userId = getStore().getState().user.userId;
|
||||
setGroup(groupDetails);
|
||||
@ -132,7 +132,7 @@ const DialogEditGroup = (props) => {
|
||||
users.push(groupDetails.members[i]);
|
||||
}
|
||||
for (let i = 0; i < shares.length; i++) {
|
||||
shares[i].title = await groupsService.decryptSecretKey(groupId, shares[i].title, shares[i].title_nonce);
|
||||
shares[i].title = groupsService.decryptSecretKey(groupId, shares[i].title, shares[i].title_nonce);
|
||||
}
|
||||
|
||||
if (!readOnly) {
|
||||
|
@ -231,7 +231,7 @@ const DialogRightsOverview = (props) => {
|
||||
await createUserShareRight(users[i]);
|
||||
}
|
||||
|
||||
async function createGroupShareRight(group) {
|
||||
function createGroupShareRight(group) {
|
||||
const onSuccess = function (data) {
|
||||
// pass
|
||||
};
|
||||
@ -253,7 +253,7 @@ const DialogRightsOverview = (props) => {
|
||||
description,
|
||||
});
|
||||
};
|
||||
const groupSecretKey = await groupsService.getGroupSecretKey(
|
||||
const groupSecretKey = groupsService.getGroupSecretKey(
|
||||
group.group_id,
|
||||
group.secret_key,
|
||||
group.secret_key_nonce,
|
||||
|
@ -1,16 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const TextWithLineBreaks = ({ text }) => {
|
||||
const parts = text.split('\n');
|
||||
return (
|
||||
<>
|
||||
{parts.map((part, index) => (
|
||||
<p key={index}>
|
||||
{part}
|
||||
{index < parts.length - 1}
|
||||
</p>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default TextWithLineBreaks;
|
36
src/js/crypto-worker.js
Normal file
36
src/js/crypto-worker.js
Normal file
@ -0,0 +1,36 @@
|
||||
import nacl from "ecma-nacl";
|
||||
|
||||
function encrypt_file(data, k, n) {
|
||||
data = new Uint8Array(data);
|
||||
k = new Uint8Array(k);
|
||||
n = new Uint8Array(n);
|
||||
|
||||
const encrypted_data = nacl.secret_box.formatWN.pack(data, n, k);
|
||||
const encrypted_buffer = encrypted_data.buffer;
|
||||
|
||||
self.postMessage({ kwargs: encrypted_buffer }, [encrypted_buffer]);
|
||||
}
|
||||
|
||||
function decrypt_file(text, k) {
|
||||
text = new Uint8Array(text);
|
||||
k = new Uint8Array(k);
|
||||
|
||||
const decrypted_data = nacl.secret_box.formatWN.open(text, k);
|
||||
let decrypted_buffer = decrypted_data.buffer;
|
||||
decrypted_buffer = decrypted_buffer.slice(32, decrypted_buffer.byteLength);
|
||||
|
||||
self.postMessage({ kwargs: decrypted_buffer }, [decrypted_buffer]);
|
||||
}
|
||||
|
||||
self.onmessage = function (msg) {
|
||||
switch (msg.data.job) {
|
||||
case "encrypt_file":
|
||||
encrypt_file(msg.data.kwargs.data, msg.data.kwargs.k, msg.data.kwargs.n);
|
||||
break;
|
||||
case "decrypt_file":
|
||||
decrypt_file(msg.data.kwargs.text, msg.data.kwargs.k);
|
||||
break;
|
||||
default:
|
||||
throw "job could not be handled: " + msg.data.job;
|
||||
}
|
||||
};
|
@ -11,7 +11,7 @@ import i18n from "../i18n";
|
||||
// TODO add later for audit log again
|
||||
//let AUDIT_LOG_HEADER = 'Audit-Log';
|
||||
|
||||
const decryptData = async function (sessionSecretKey, data, url, method) {
|
||||
const decryptData = function (sessionSecretKey, data, url, method) {
|
||||
if (
|
||||
sessionSecretKey &&
|
||||
data !== null &&
|
||||
@ -34,17 +34,17 @@ const decryptData = async function (sessionSecretKey, data, url, method) {
|
||||
data.data.hasOwnProperty("text") &&
|
||||
data.data.hasOwnProperty("nonce")
|
||||
) {
|
||||
data.data = JSON.parse(await cryptoLibrary.decryptData(data.data.text, data.data.nonce, sessionSecretKey));
|
||||
data.data = JSON.parse(cryptoLibrary.decryptData(data.data.text, data.data.nonce, sessionSecretKey));
|
||||
}
|
||||
offlineCache.set(url, method, data);
|
||||
return data;
|
||||
};
|
||||
|
||||
async function _statelessCall(method, endpoint, body, headers, sessionSecretKey, serverUrl, deviceFingerprint, sideEffect) {
|
||||
function _statelessCall(method, endpoint, body, headers, sessionSecretKey, serverUrl, deviceFingerprint, sideEffect) {
|
||||
const url = serverUrl + endpoint;
|
||||
|
||||
if (sessionSecretKey && body !== null) {
|
||||
body = await cryptoLibrary.encryptData(JSON.stringify(body), sessionSecretKey);
|
||||
body = cryptoLibrary.encryptData(JSON.stringify(body), sessionSecretKey);
|
||||
}
|
||||
|
||||
if (sessionSecretKey && headers && headers.hasOwnProperty("Authorization")) {
|
||||
@ -53,7 +53,7 @@ async function _statelessCall(method, endpoint, body, headers, sessionSecretKey,
|
||||
request_device_fingerprint: deviceFingerprint,
|
||||
};
|
||||
headers["Authorization-Validator"] = JSON.stringify(
|
||||
await cryptoLibrary.encryptData(JSON.stringify(validator), sessionSecretKey)
|
||||
cryptoLibrary.encryptData(JSON.stringify(validator), sessionSecretKey)
|
||||
);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ async function _statelessCall(method, endpoint, body, headers, sessionSecretKey,
|
||||
// }
|
||||
//
|
||||
// if (sessionSecretKey && headers && headers.hasOwnProperty(AUDIT_LOG_HEADER) && log_audit) {
|
||||
// headers[AUDIT_LOG_HEADER] = JSON.stringify(await cryptoLibrary.encryptData(JSON.stringify(headers[AUDIT_LOG_HEADER]), sessionSecretKey));
|
||||
// headers[AUDIT_LOG_HEADER] = JSON.stringify(cryptoLibrary.encryptData(JSON.stringify(headers[AUDIT_LOG_HEADER]), sessionSecretKey));
|
||||
// } else if (headers && headers.hasOwnProperty(AUDIT_LOG_HEADER)) {
|
||||
// delete headers[AUDIT_LOG_HEADER];
|
||||
// }
|
||||
@ -154,7 +154,7 @@ async function _statelessCall(method, endpoint, body, headers, sessionSecretKey,
|
||||
});
|
||||
}
|
||||
|
||||
async function call(method, endpoint, body, headers, sessionSecretKey) {
|
||||
function call(method, endpoint, body, headers, sessionSecretKey) {
|
||||
const serverUrl = getStore().getState().server.url;
|
||||
const deviceFingerprint = device.getDeviceFingerprint();
|
||||
const sideEffect = (rawResponse) => {
|
||||
|
@ -15,13 +15,13 @@ function readApiKey(apiKeyId) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const onSuccess = async function (result) {
|
||||
result.data.private_key = await cryptoLibrary.decryptSecretKey(
|
||||
const onSuccess = function (result) {
|
||||
result.data.private_key = cryptoLibrary.decryptSecretKey(
|
||||
result.data.private_key,
|
||||
result.data.private_key_nonce
|
||||
);
|
||||
delete result.data.private_key_nonce;
|
||||
result.data.secret_key = await cryptoLibrary.decryptSecretKey(result.data.secret_key, result.data.secret_key_nonce);
|
||||
result.data.secret_key = cryptoLibrary.decryptSecretKey(result.data.secret_key, result.data.secret_key_nonce);
|
||||
delete result.data.secret_key_nonce;
|
||||
|
||||
return result.data;
|
||||
@ -61,10 +61,10 @@ function readApiKeySecrets(apiKeyId) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const onSuccess = async function (result) {
|
||||
const onSuccess = function (result) {
|
||||
const secrets = result.data;
|
||||
for (let i = 0; i < secrets.length; i++) {
|
||||
secrets[i]["name"] = await cryptoLibrary.decryptSecretKey(secrets[i]["title"], secrets[i]["title_nonce"]);
|
||||
secrets[i]["name"] = cryptoLibrary.decryptSecretKey(secrets[i]["title"], secrets[i]["title_nonce"]);
|
||||
}
|
||||
return secrets;
|
||||
};
|
||||
@ -84,12 +84,12 @@ function readApiKeySecrets(apiKeyId) {
|
||||
*
|
||||
* @returns {Promise} Promise with the new id
|
||||
*/
|
||||
async function addSecretToApiKey(apiKeyId, apiKeySecretKey, secret) {
|
||||
function addSecretToApiKey(apiKeyId, apiKeySecretKey, secret) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const secret_secret_key_enc = await cryptoLibrary.encryptData(secret.secret_key, apiKeySecretKey);
|
||||
const secret_title_enc = await cryptoLibrary.encryptSecretKey(secret.name);
|
||||
const secret_secret_key_enc = cryptoLibrary.encryptData(secret.secret_key, apiKeySecretKey);
|
||||
const secret_title_enc = cryptoLibrary.encryptSecretKey(secret.name);
|
||||
|
||||
return apiClient.addSecretToApiKey(
|
||||
token,
|
||||
@ -139,20 +139,20 @@ function addSecretsToApiKey(apiKeyId, apiKeySecretKey, secrets) {
|
||||
*
|
||||
* @returns {Promise} Promise with the new id
|
||||
*/
|
||||
async function createApiKey(title, restrictToSecrets, allowInsecureAccess, allowReadAccess, allowWriteAccess, secrets) {
|
||||
function createApiKey(title, restrictToSecrets, allowInsecureAccess, allowReadAccess, allowWriteAccess, secrets) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const apiKeySecretKey = cryptoLibrary.generateSecretKey();
|
||||
const api_key_public_private_key_pair = await cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const api_key_public_private_key_pair = cryptoLibrary.generatePublicPrivateKeypair();
|
||||
|
||||
const api_key_private_key_enc = await cryptoLibrary.encryptSecretKey(api_key_public_private_key_pair.private_key);
|
||||
const apiKeySecretKey_enc = await cryptoLibrary.encryptSecretKey(apiKeySecretKey);
|
||||
const api_key_private_key_enc = cryptoLibrary.encryptSecretKey(api_key_public_private_key_pair.private_key);
|
||||
const apiKeySecretKey_enc = cryptoLibrary.encryptSecretKey(apiKeySecretKey);
|
||||
|
||||
const user_private_key_enc = await cryptoLibrary.encryptData(getStore().getState().user.userPrivateKey, apiKeySecretKey);
|
||||
const user_secret_key_enc = await cryptoLibrary.encryptData(getStore().getState().user.userSecretKey, apiKeySecretKey);
|
||||
const user_private_key_enc = cryptoLibrary.encryptData(getStore().getState().user.userPrivateKey, apiKeySecretKey);
|
||||
const user_secret_key_enc = cryptoLibrary.encryptData(getStore().getState().user.userSecretKey, apiKeySecretKey);
|
||||
|
||||
const verify_key = await cryptoLibrary.getVerifyKey(api_key_public_private_key_pair.private_key);
|
||||
const verify_key = cryptoLibrary.getVerifyKey(api_key_public_private_key_pair.private_key);
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const apiKeyId = result.data["api_key_id"];
|
||||
|
@ -2,8 +2,8 @@
|
||||
* Service with all the cryptographic operations
|
||||
*/
|
||||
|
||||
import scrypt from 'scrypt-async';
|
||||
import * as OTPAuth from "otpauth";
|
||||
import nacl from "ecma-nacl";
|
||||
import uuid from "uuid-js";
|
||||
import sha1 from "js-sha1";
|
||||
import sha512 from "js-sha512";
|
||||
@ -110,40 +110,36 @@ function clearScryptLookupTable() {
|
||||
*
|
||||
* @returns {string} The scrypt hash
|
||||
*/
|
||||
async function passwordScrypt(password, salt) {
|
||||
const u = 14; // 2^14 = 16384
|
||||
function passwordScrypt(password, salt) {
|
||||
// Lets first generate our key from our user_sauce and password
|
||||
const u = 14; //2^14 = 16MB
|
||||
const r = 8;
|
||||
const p = 1;
|
||||
const l = 64; // 64 Bytes = 512 Bits
|
||||
let k;
|
||||
|
||||
const lookup_hash = sha512(password) + sha512(salt);
|
||||
|
||||
if (scrypt_lookup_table.hasOwnProperty(lookup_hash)) {
|
||||
return scrypt_lookup_table[lookup_hash];
|
||||
k = scrypt_lookup_table[lookup_hash];
|
||||
} else {
|
||||
const passwordBuf = converterService.encodeUtf8(password);
|
||||
const saltBuf = converterService.encodeUtf8(salt);
|
||||
|
||||
const derivedKey = await new Promise((resolve, reject) => {
|
||||
scrypt(passwordBuf, saltBuf, {
|
||||
N: Math.pow(2, u),
|
||||
r: r,
|
||||
p: p,
|
||||
dkLen: l,
|
||||
encoding: 'binary'
|
||||
}, (derivedKey) => {
|
||||
resolve(derivedKey);
|
||||
});
|
||||
});
|
||||
|
||||
const k = converterService.toHex(new Uint8Array(derivedKey));
|
||||
k = converterService.toHex(
|
||||
nacl.scrypt(
|
||||
converterService.encodeUtf8(password),
|
||||
converterService.encodeUtf8(salt),
|
||||
u,
|
||||
r,
|
||||
p,
|
||||
l,
|
||||
function (pDone) {}
|
||||
)
|
||||
);
|
||||
scrypt_lookup_table[lookup_hash] = k;
|
||||
clearScryptLookupTable();
|
||||
return k;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* takes the sha512 of lowercase username as salt to generate scrypt password hash in hex called
|
||||
* the authkey, so basically:
|
||||
@ -160,9 +156,9 @@ async function passwordScrypt(password, salt) {
|
||||
* @param {string} username Username of the user (in email format)
|
||||
* @param {string} password Password of the user
|
||||
*
|
||||
* @returns {Promise} auth_key Scrypt hex value of the password with the sha512 of lowercase email as salt
|
||||
* @returns {string} auth_key Scrypt hex value of the password with the sha512 of lowercase email as salt
|
||||
*/
|
||||
async function generateAuthkey(username, password) {
|
||||
function generateAuthkey(username, password) {
|
||||
if (!username || !username.includes("@")) {
|
||||
// security. Do not remove!
|
||||
throw new Error("Malformed username.");
|
||||
@ -187,15 +183,13 @@ function generateSecretKey() {
|
||||
*
|
||||
* @returns {PublicPrivateKeyPair} Returns object with a public-private-key-pair
|
||||
*/
|
||||
async function generatePublicPrivateKeypair() {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
const keyPair = sodium.crypto_box_keypair();
|
||||
function generatePublicPrivateKeypair() {
|
||||
const sk = randomBytes(32);
|
||||
const pk = nacl.box.generate_pubkey(sk);
|
||||
|
||||
return {
|
||||
public_key: converterService.toHex(keyPair.publicKey), // 32 Bytes = 256 Bits
|
||||
private_key: converterService.toHex(keyPair.privateKey), // 32 Bytes = 256 Bits
|
||||
public_key: converterService.toHex(pk), // 32 Bytes = 256 Bits
|
||||
private_key: converterService.toHex(sk), // 32 Bytes = 256 Bits
|
||||
};
|
||||
}
|
||||
|
||||
@ -208,24 +202,22 @@ async function generatePublicPrivateKeypair() {
|
||||
* @param {string} password The password you want to use to encrypt the secret
|
||||
* @param {string} userSauce The user's sauce
|
||||
*
|
||||
* @returns {Promise} The encrypted text and the nonce
|
||||
* @returns {EncryptedValue} The encrypted text and the nonce
|
||||
*/
|
||||
async function encryptSecret(secret, password, userSauce) {
|
||||
if (userSauce.includes("@")) {
|
||||
function encryptSecret(secret, password, userSauce) {
|
||||
|
||||
if (userSauce.includes("@")){
|
||||
// security. Do not remove!
|
||||
throw new Error("encrypt secret may not contain an @ as it may be a username");
|
||||
}
|
||||
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
const salt = sha512(userSauce);
|
||||
const k = converterService.fromHex(sha256(await passwordScrypt(password, salt))); // key
|
||||
const k = converterService.fromHex(sha256(passwordScrypt(password, salt))); // key
|
||||
|
||||
// and now lets encrypt
|
||||
const m = converterService.encodeUtf8(secret); // message
|
||||
const n = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES); // nonce
|
||||
const c = sodium.crypto_secretbox_easy(m, n, k); // encrypted message
|
||||
const n = randomBytes(24); // nonce
|
||||
const c = nacl.secret_box.pack(m, n, k); //encrypted message
|
||||
|
||||
return {
|
||||
nonce: converterService.toHex(n),
|
||||
@ -242,78 +234,103 @@ async function encryptSecret(secret, password, userSauce) {
|
||||
* @param {string} password The password to decrypt the text
|
||||
* @param {string} userSauce The users sauce used during encryption
|
||||
*
|
||||
* @returns {Promise} secret The decrypted secret
|
||||
* @returns {string} secret The decrypted secret
|
||||
*/
|
||||
async function decryptSecret(text, nonce, password, userSauce) {
|
||||
if (userSauce.includes("@")) {
|
||||
function decryptSecret(text, nonce, password, userSauce) {
|
||||
|
||||
if (userSauce.includes("@")){
|
||||
// security. Do not remove!
|
||||
throw new Error("encrypt secret may not contain an @ as it may be a username");
|
||||
}
|
||||
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
const salt = sha512(userSauce);
|
||||
const k = converterService.fromHex(sha256(await passwordScrypt(password, salt)));
|
||||
const k = converterService.fromHex(sha256(passwordScrypt(password, salt)));
|
||||
|
||||
// and now lets decrypt
|
||||
const n = converterService.fromHex(nonce);
|
||||
const c = converterService.fromHex(text);
|
||||
const m1 = sodium.crypto_secretbox_open_easy(c, n, k);
|
||||
|
||||
if (!m1) {
|
||||
throw new Error("Decryption failed");
|
||||
}
|
||||
const m1 = nacl.secret_box.open(c, n, k);
|
||||
|
||||
return converterService.decodeUtf8(m1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a file (in Uint8Array representation)
|
||||
* runs async jobs
|
||||
*
|
||||
* @param {Uint8Array} data - The data of the file in Uint8Array encoding
|
||||
* @param {string} secretKey - The secret key to use for encryption
|
||||
* @param job
|
||||
* @param kwargs
|
||||
* @param transfers
|
||||
*
|
||||
* @returns {Promise<Uint8Array>} - A promise that resolves with the encrypted file with the nonce as Uint8Array
|
||||
* @returns {PromiseLike<any> | f | * | e | promise}
|
||||
*/
|
||||
async function encryptFile(data, secretKey) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
function runCryptoWorkAsync(job, kwargs, transfers) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const cryptoWorker = new Worker("js/crypto-worker.js");
|
||||
|
||||
const k = converterService.fromHex(secretKey);
|
||||
const n = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
|
||||
const encryptedData = sodium.crypto_secretbox_easy(data, n, k);
|
||||
function handle_message_from_worker(msg) {
|
||||
cryptoWorker.terminate();
|
||||
resolve(msg.data.kwargs);
|
||||
}
|
||||
|
||||
// Combine nonce and encrypted data into a single Uint8Array
|
||||
const combined = new Uint8Array(n.length + encryptedData.length);
|
||||
combined.set(n);
|
||||
combined.set(encryptedData, n.length);
|
||||
|
||||
return combined;
|
||||
cryptoWorker.addEventListener("message", handle_message_from_worker);
|
||||
cryptoWorker.postMessage(
|
||||
{
|
||||
job: job,
|
||||
kwargs: kwargs,
|
||||
},
|
||||
transfers
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a file (in Uint8Array representation) with prepended nonce
|
||||
* Encrypts a file (in Uint8 representation)
|
||||
*
|
||||
* @param {Uint8Array} text - The encrypted data of the file in Uint8Array encoding with prepended nonce
|
||||
* @param {string} secretKey - The secret key used to encrypt the text
|
||||
* @param {Uint8Array} data The data of the file in Uint8Array encoding
|
||||
* @param {string} secretKey The secret key you want to use to encrypt the data
|
||||
*
|
||||
* @returns {Promise<Uint8Array>} - A promise that resolves with the decrypted data as Uint8Array
|
||||
* @returns {Promise} A promise that will return the encrypted file with the nonce as Uint8Array
|
||||
*/
|
||||
async function decryptFile(text, secretKey) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
function encryptFile(data, secretKey) {
|
||||
const k = converterService.fromHex(secretKey).buffer;
|
||||
const n = randomBytes(24).buffer;
|
||||
const arrayBuffer = data.buffer;
|
||||
|
||||
const k = converterService.fromHex(secretKey);
|
||||
const n = text.slice(0, sodium.crypto_secretbox_NONCEBYTES);
|
||||
const c = text.slice(sodium.crypto_secretbox_NONCEBYTES);
|
||||
const decryptedData = sodium.crypto_secretbox_open_easy(c, n, k);
|
||||
return runCryptoWorkAsync(
|
||||
"encrypt_file",
|
||||
{
|
||||
data: arrayBuffer,
|
||||
k: k,
|
||||
n: n,
|
||||
},
|
||||
[arrayBuffer]
|
||||
).then(function (buffer) {
|
||||
return new Uint8Array(buffer);
|
||||
});
|
||||
}
|
||||
|
||||
if (!decryptedData) {
|
||||
throw new Error('Decryption failed');
|
||||
}
|
||||
/**
|
||||
* Decrypts a file (in Uint8 representation) with prepended nonce
|
||||
*
|
||||
* @param {Uint8Array} text The encrypted data of the file in Uint8Array encoding with prepended nonce
|
||||
* @param {string} secretKey The secret key used in the past to encrypt the text
|
||||
*
|
||||
* @returns {Promise} A promise that will return the decrypted data as Uint8Array
|
||||
*/
|
||||
function decryptFile(text, secretKey) {
|
||||
const k = converterService.fromHex(secretKey).buffer;
|
||||
const arrayBuffer = text.buffer;
|
||||
|
||||
return decryptedData;
|
||||
return runCryptoWorkAsync(
|
||||
"decrypt_file",
|
||||
{
|
||||
text: arrayBuffer,
|
||||
k: k,
|
||||
},
|
||||
[arrayBuffer]
|
||||
).then(function (buffer) {
|
||||
return new Uint8Array(buffer);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,14 +342,11 @@ async function decryptFile(text, secretKey) {
|
||||
*
|
||||
* @returns {EncryptedValue} The encrypted text and the nonce
|
||||
*/
|
||||
async function encryptData(data, secretKey) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
function encryptData(data, secretKey) {
|
||||
const k = converterService.fromHex(secretKey);
|
||||
const m = converterService.encodeUtf8(data);
|
||||
const n = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES); // nonce
|
||||
const c = sodium.crypto_secretbox_easy(m, n, k); // encrypted message
|
||||
const n = randomBytes(24);
|
||||
const c = nacl.secret_box.pack(m, n, k);
|
||||
|
||||
return {
|
||||
nonce: converterService.toHex(n),
|
||||
@ -348,20 +362,13 @@ async function encryptData(data, secretKey) {
|
||||
* @param {string} nonce The nonce of the encrypted text
|
||||
* @param {string} secretKey The secret key used in the past to encrypt the text
|
||||
*
|
||||
* @returns {Promise<String>} The decrypted data
|
||||
* @returns {string} The decrypted data
|
||||
*/
|
||||
async function decryptData(text, nonce, secretKey) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
function decryptData(text, nonce, secretKey) {
|
||||
const k = converterService.fromHex(secretKey);
|
||||
const n = converterService.fromHex(nonce);
|
||||
const c = converterService.fromHex(text);
|
||||
const m1 = sodium.crypto_secretbox_open_easy(c, n, k);
|
||||
|
||||
if (!m1) {
|
||||
throw new Error('Decryption failed');
|
||||
}
|
||||
const m1 = nacl.secret_box.open(c, n, k);
|
||||
|
||||
return converterService.decodeUtf8(m1);
|
||||
}
|
||||
@ -376,15 +383,12 @@ async function decryptData(text, nonce, secretKey) {
|
||||
*
|
||||
* @returns {EncryptedValue} The encrypted text and the nonce
|
||||
*/
|
||||
async function encryptDataPublicKey(data, publicKey, privateKey) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
function encryptDataPublicKey(data, publicKey, privateKey) {
|
||||
const p = converterService.fromHex(publicKey);
|
||||
const s = converterService.fromHex(privateKey);
|
||||
const m = converterService.encodeUtf8(data);
|
||||
const n = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES); // nonce
|
||||
const c = sodium.crypto_box_easy(m, n, p, s); // encrypted message
|
||||
const n = randomBytes(24);
|
||||
const c = nacl.box.pack(m, n, p, s);
|
||||
|
||||
return {
|
||||
nonce: converterService.toHex(n),
|
||||
@ -401,21 +405,14 @@ async function encryptDataPublicKey(data, publicKey, privateKey) {
|
||||
* @param {string} publicKey The pulic key you want to use to decrypt the text
|
||||
* @param {string} privateKey The private key you want to use to encrypt the text
|
||||
*
|
||||
* @returns {Promise<String>} The decrypted data
|
||||
* @returns {string} The decrypted data
|
||||
*/
|
||||
async function decryptDataPublicKey(text, nonce, publicKey, privateKey) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
function decryptDataPublicKey(text, nonce, publicKey, privateKey) {
|
||||
const p = converterService.fromHex(publicKey);
|
||||
const s = converterService.fromHex(privateKey);
|
||||
const n = converterService.fromHex(nonce);
|
||||
const c = converterService.fromHex(text);
|
||||
const m1 = sodium.crypto_box_open_easy(c, n, p, s);
|
||||
|
||||
if (!m1) {
|
||||
throw new Error('Decryption failed');
|
||||
}
|
||||
const m1 = nacl.box.open(c, n, p, s);
|
||||
|
||||
return converterService.decodeUtf8(m1);
|
||||
}
|
||||
@ -519,17 +516,14 @@ function generateUuid() {
|
||||
* @param {string} signature The hex representation of the signature
|
||||
* @param {string} verifyKey The hex representation of the verification key
|
||||
*
|
||||
* @returns {Promise<boolean>} Returns whether the signature is correct or not
|
||||
* @returns {boolean} Returns whether the signature is correct or not
|
||||
*/
|
||||
async function validateSignature(message, signature, verifyKey) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
|
||||
const sig = converterService.fromHex(signature);
|
||||
const msg = converterService.encodeUtf8(message);
|
||||
const key = converterService.fromHex(verifyKey);
|
||||
|
||||
return sodium.crypto_sign_verify_detached(sig, msg, key);
|
||||
function validateSignature(message, signature, verifyKey) {
|
||||
return nacl.signing.verify(
|
||||
converterService.fromHex(signature),
|
||||
converterService.encodeUtf8(message),
|
||||
converterService.fromHex(verifyKey)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -537,16 +531,12 @@ async function validateSignature(message, signature, verifyKey) {
|
||||
*
|
||||
* @param {string} seed The seed
|
||||
*
|
||||
* @returns {Promise<String>} Returns the verify key for a given seed
|
||||
* @returns {string} Returns the verify key for a given seed
|
||||
*/
|
||||
async function getVerifyKey(seed) {
|
||||
const { default: sodium } = await import('libsodium-wrappers');
|
||||
await sodium.ready;
|
||||
function getVerifyKey(seed) {
|
||||
const pair = nacl.signing.generate_keypair(converterService.fromHex(seed));
|
||||
|
||||
const seedArray = converterService.fromHex(seed);
|
||||
const keyPair = sodium.crypto_sign_seed_keypair(seedArray);
|
||||
|
||||
return converterService.toHex(keyPair.publicKey);
|
||||
return converterService.toHex(pair.pkey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -602,10 +592,10 @@ function getTotpToken(key, period, algorithm, digits) {
|
||||
* @param {string} data The data you want to encrypt
|
||||
* @param {string} publicKey The public key you want to use for the encryption
|
||||
*
|
||||
* @returns {Promise<EncryptedValue>} The encrypted text and the nonce
|
||||
* @returns {EncryptedValue} The encrypted text and the nonce
|
||||
*/
|
||||
async function encryptPrivateKey(data, publicKey) {
|
||||
return await encryptDataPublicKey(data, publicKey, getStore().getState().user.userPrivateKey);
|
||||
function encryptPrivateKey(data, publicKey) {
|
||||
return encryptDataPublicKey(data, publicKey, getStore().getState().user.userPrivateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -615,10 +605,10 @@ async function encryptPrivateKey(data, publicKey) {
|
||||
* @param {string} nonce The nonce that belongs to the encrypted text
|
||||
* @param {string} publicKey The pulic key you want to use to decrypt the text
|
||||
*
|
||||
* @returns {Promise<String>} The decrypted data
|
||||
* @returns {string} The decrypted data
|
||||
*/
|
||||
async function decryptPrivateKey(text, nonce, publicKey) {
|
||||
return await decryptDataPublicKey(text, nonce, publicKey, getStore().getState().user.userPrivateKey);
|
||||
function decryptPrivateKey(text, nonce, publicKey) {
|
||||
return decryptDataPublicKey(text, nonce, publicKey, getStore().getState().user.userPrivateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -626,9 +616,9 @@ async function decryptPrivateKey(text, nonce, publicKey) {
|
||||
*
|
||||
* @param {string} data The data you want to encrypt
|
||||
*
|
||||
* @returns {Promise<EncryptedValue>} The encrypted text and the nonce
|
||||
* @returns {EncryptedValue} The encrypted text and the nonce
|
||||
*/
|
||||
async function encryptSecretKey(data) {
|
||||
function encryptSecretKey(data) {
|
||||
return encryptData(data, getStore().getState().user.userSecretKey);
|
||||
}
|
||||
|
||||
@ -638,10 +628,10 @@ async function encryptSecretKey(data) {
|
||||
* @param {string} text The encrypted text
|
||||
* @param {string} nonce The nonce of the encrypted text
|
||||
*
|
||||
* @returns {Promise<String>} The decrypted data
|
||||
* @returns {string} The decrypted data
|
||||
*/
|
||||
async function decryptSecretKey(text, nonce) {
|
||||
return await decryptData(text, nonce, getStore().getState().user.userSecretKey);
|
||||
function decryptSecretKey(text, nonce) {
|
||||
return decryptData(text, nonce, getStore().getState().user.userSecretKey);
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,22 +110,22 @@ describe('Service: cryptoLibraryService test suite #2', function() {
|
||||
).toBe("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
|
||||
});
|
||||
|
||||
// it('generatePublicPrivateKeypair returns a pair of 32 bytes long keys', function() {
|
||||
// let bytes, pair;
|
||||
// bytes = 32;
|
||||
// pair = cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
// expect(converterService.fromHex(pair.private_key).length).toBe(bytes);
|
||||
// return expect(converterService.fromHex(pair.public_key).length).toBe(bytes);
|
||||
// });
|
||||
it('generatePublicPrivateKeypair returns a pair of 32 bytes long keys', function() {
|
||||
let bytes, pair;
|
||||
bytes = 32;
|
||||
pair = cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
expect(converterService.fromHex(pair.private_key).length).toBe(bytes);
|
||||
return expect(converterService.fromHex(pair.public_key).length).toBe(bytes);
|
||||
});
|
||||
|
||||
// it('generatePublicPrivateKeypair returned pairs are different', function() {
|
||||
// let pair1, pair2;
|
||||
// pair1 = cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
// pair2 = cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
// expect(pair1.private_key).toBe(pair1.private_key);
|
||||
// expect(pair1.private_key).not.toBe(pair2.private_key);
|
||||
// return expect(pair1.public_key).not.toBe(pair2.public_key);
|
||||
// });
|
||||
it('generatePublicPrivateKeypair returned pairs are different', function() {
|
||||
let pair1, pair2;
|
||||
pair1 = cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
pair2 = cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
expect(pair1.private_key).toBe(pair1.private_key);
|
||||
expect(pair1.private_key).not.toBe(pair2.private_key);
|
||||
return expect(pair1.public_key).not.toBe(pair2.public_key);
|
||||
});
|
||||
|
||||
it('generateUserSauce', function() {
|
||||
let bytes, user_sauce1, user_sauce2;
|
||||
@ -188,218 +188,218 @@ describe('Service: cryptoLibraryService test suite #2', function() {
|
||||
cryptoLibraryService.recoveryPasswordChunkPassChecksum('UaKSKNNixJY2B')
|
||||
).toBeFalsy();
|
||||
});
|
||||
//
|
||||
// it('decryptSecret', async function () {
|
||||
// jest.useFakeTimers();
|
||||
// jest.spyOn(global, 'setTimeout');
|
||||
//
|
||||
// let data, nonce, password, text, user_sauce;
|
||||
// data = '12345';
|
||||
// password = 'myPassword';
|
||||
// user_sauce =
|
||||
// '6168de45af90c335967a8f9eae76f8f19bcb42fb8c3f602fee35f7617acdc489';
|
||||
// nonce = 'ff786149d8242bb7802379bc5fd2f9ccc744a2e1f18bb0a8';
|
||||
// text = 'a92528f78ca1f0812a4fb2ee5de4d16eb75d434318';
|
||||
//
|
||||
// const result = await cryptoLibraryService.decryptSecret(text, nonce, password, user_sauce);
|
||||
//
|
||||
// expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 60000);
|
||||
//
|
||||
// return expect(
|
||||
// result
|
||||
// ).toBe(data);
|
||||
// });
|
||||
//
|
||||
// it('encryptSecret', function() {
|
||||
// let bytes_nonce,
|
||||
// data,
|
||||
// encrypted_data,
|
||||
// encrypted_data2,
|
||||
// password,
|
||||
// user_sauce;
|
||||
// bytes_nonce = 24;
|
||||
// data = '12345';
|
||||
// password = 'myPassword';
|
||||
// user_sauce =
|
||||
// '6168de45af90c335967a8f9eae76f8f19bcb42fb8c3f602fee35f7617acdc489';
|
||||
// encrypted_data = cryptoLibraryService.encryptSecret(
|
||||
// data,
|
||||
// password,
|
||||
// user_sauce
|
||||
// );
|
||||
// expect(encrypted_data.text).not.toBe(void 0);
|
||||
// expect(encrypted_data.nonce).not.toBe(void 0);
|
||||
// expect(converterService.fromHex(encrypted_data.text).length).toBeGreaterThan(
|
||||
// 0
|
||||
// );
|
||||
// expect(converterService.fromHex(encrypted_data.nonce).length).toBe(
|
||||
// bytes_nonce
|
||||
// );
|
||||
// expect(
|
||||
// cryptoLibraryService.decryptSecret(
|
||||
// encrypted_data.text,
|
||||
// encrypted_data.nonce,
|
||||
// password,
|
||||
// user_sauce
|
||||
// )
|
||||
// ).toBe(data);
|
||||
// encrypted_data2 = cryptoLibraryService.encryptSecret(
|
||||
// data,
|
||||
// password,
|
||||
// user_sauce
|
||||
// );
|
||||
// return expect(encrypted_data.nonce).not.toBe(encrypted_data2.nonce);
|
||||
// });
|
||||
//
|
||||
// it('decryptData works', function() {
|
||||
// let data, nonce, secret_key, text;
|
||||
// data = '12345';
|
||||
// secret_key =
|
||||
// '9f3edbf7760d8ec1e8fd4a9c623b4fe569f324bf42c78770ef0a40a56495f92d';
|
||||
// nonce = 'd65673e9abcf379493bba61a576535a82bcf8d735a915390';
|
||||
// text = '9429f56f028a82ec44651bb7ea6b9f8baab3cd137e';
|
||||
// return expect(cryptoLibraryService.decryptData(text, nonce, secret_key)).toBe(
|
||||
// data
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// it('encryptData works', function() {
|
||||
// let bytes_nonce, data, encrypted_data, encrypted_data2, secret_key;
|
||||
// bytes_nonce = 24;
|
||||
// data = '12345';
|
||||
// secret_key =
|
||||
// '9f3edbf7760d8ec1e8fd4a9c623b4fe569f324bf42c78770ef0a40a56495f92d';
|
||||
// encrypted_data = cryptoLibraryService.encryptData(data, secret_key);
|
||||
// expect(encrypted_data.text).not.toBe(void 0);
|
||||
// expect(encrypted_data.nonce).not.toBe(void 0);
|
||||
// expect(converterService.fromHex(encrypted_data.text).length).toBeGreaterThan(
|
||||
// 0
|
||||
// );
|
||||
// expect(converterService.fromHex(encrypted_data.nonce).length).toBe(
|
||||
// bytes_nonce
|
||||
// );
|
||||
// expect(
|
||||
// cryptoLibraryService.decryptData(
|
||||
// encrypted_data.text,
|
||||
// encrypted_data.nonce,
|
||||
// secret_key
|
||||
// )
|
||||
// ).toBe(data);
|
||||
// encrypted_data2 = cryptoLibraryService.encryptData(data, secret_key);
|
||||
// return expect(encrypted_data.nonce).not.toBe(encrypted_data2.nonce);
|
||||
// });
|
||||
//
|
||||
// it('decryptDataPublicKey works', function() {
|
||||
// let data, nonce, pair, pair2, text;
|
||||
// data = '12345';
|
||||
// pair = {
|
||||
// public_key:
|
||||
// 'ed7293c239164855aca4c2e6edb19e09bba41e3451603ec427782d45f2d57b39',
|
||||
// private_key:
|
||||
// '035f8aa4c86658a36d995df47c8e3d1e9a7a2a2f3efdcbdc1451ed4354350660'
|
||||
// };
|
||||
// pair2 = {
|
||||
// public_key:
|
||||
// '57531faba711e6e9bdea25229e63db4ce6eb79f0872d97cbfec74df0382dbf3a',
|
||||
// private_key:
|
||||
// 'a04c3fbcb4dcf5df44bc433668bb686aac8991f83e993b971e73a0b37ace362c'
|
||||
// };
|
||||
// nonce = '538a2fc024e1ff7a791da88874099709bdb60ad62653529b';
|
||||
// text = '0eedec49906748988b011741c8df4214e4dbeeda76';
|
||||
// return expect(
|
||||
// cryptoLibraryService.decryptDataPublicKey(
|
||||
// text,
|
||||
// nonce,
|
||||
// pair2.public_key,
|
||||
// pair.private_key
|
||||
// )
|
||||
// ).toBe(data);
|
||||
// });
|
||||
//
|
||||
// it('encryptDataPublicKey works', function() {
|
||||
// let bytes_nonce, data, encrypted_data, encrypted_data2, pair, pair2;
|
||||
// bytes_nonce = 24;
|
||||
// data = '12345';
|
||||
// pair = {
|
||||
// public_key:
|
||||
// 'ed7293c239164855aca4c2e6edb19e09bba41e3451603ec427782d45f2d57b39',
|
||||
// private_key:
|
||||
// '035f8aa4c86658a36d995df47c8e3d1e9a7a2a2f3efdcbdc1451ed4354350660'
|
||||
// };
|
||||
// pair2 = {
|
||||
// public_key:
|
||||
// '57531faba711e6e9bdea25229e63db4ce6eb79f0872d97cbfec74df0382dbf3a',
|
||||
// private_key:
|
||||
// 'a04c3fbcb4dcf5df44bc433668bb686aac8991f83e993b971e73a0b37ace362c'
|
||||
// };
|
||||
// encrypted_data = cryptoLibraryService.encryptDataPublicKey(
|
||||
// data,
|
||||
// pair.public_key,
|
||||
// pair2.private_key
|
||||
// );
|
||||
// expect(encrypted_data.text).not.toBe(void 0);
|
||||
// expect(encrypted_data.nonce).not.toBe(void 0);
|
||||
// expect(converterService.fromHex(encrypted_data.text).length).toBeGreaterThan(
|
||||
// 0
|
||||
// );
|
||||
// expect(converterService.fromHex(encrypted_data.nonce).length).toBe(
|
||||
// bytes_nonce
|
||||
// );
|
||||
// expect(
|
||||
// cryptoLibraryService.decryptDataPublicKey(
|
||||
// encrypted_data.text,
|
||||
// encrypted_data.nonce,
|
||||
// pair2.public_key,
|
||||
// pair.private_key
|
||||
// )
|
||||
// ).toBe(data);
|
||||
// encrypted_data2 = cryptoLibraryService.encryptDataPublicKey(
|
||||
// data,
|
||||
// pair.public_key,
|
||||
// pair2.private_key
|
||||
// );
|
||||
// return expect(encrypted_data.nonce).not.toBe(encrypted_data2.nonce);
|
||||
// });
|
||||
//
|
||||
// it('generateUuid', function() {
|
||||
// const regex = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i;
|
||||
// expect(regex.test(cryptoLibraryService.generateUuid())).toBe(true);
|
||||
// });
|
||||
//
|
||||
// it("nacl's signing.verify works", function() {
|
||||
// const nacl = require('ecma-nacl');
|
||||
// // signing key pair can be generated from some seed array, which can
|
||||
// // either be random itself, or be generated from a password
|
||||
// const pair = nacl.signing.generate_keypair(
|
||||
// cryptoLibraryService.randomBytes(32)
|
||||
// );
|
||||
//
|
||||
// // make signature bytes, for msg
|
||||
// const msgSig = nacl.signing.signature(
|
||||
// converterService.encodeUtf8(
|
||||
// 'test message that is some nice text or whatever that needs to be encrypted'
|
||||
// ),
|
||||
// pair.skey
|
||||
// );
|
||||
//
|
||||
// // verify signature
|
||||
// const sigIsOK = nacl.signing.verify(
|
||||
// msgSig,
|
||||
// converterService.encodeUtf8(
|
||||
// 'test message that is some nice text or whatever that needs to be encrypted'
|
||||
// ),
|
||||
// pair.pkey
|
||||
// );
|
||||
// expect(sigIsOK).toBe(true);
|
||||
// });
|
||||
//
|
||||
// it('validate_signature', function() {
|
||||
// expect(
|
||||
// await cryptoLibraryService.validateSignature(
|
||||
// 'test message that is some nice text or whatever that needs to be encrypted',
|
||||
// '6e3302a696092fe3893d971391f94f2cb850d19fbbae9978122f0f465593bc06e65440e0ec929805b58e63fe719983201754a2a578c906c18b8ffa71e3234502',
|
||||
// '967fd5c3c8386609c1ac57209a6f68a147a56518a7ed5df3285beea58d671f62'
|
||||
// )
|
||||
// ).toBe(true);
|
||||
// });
|
||||
|
||||
it('decryptSecret', async function () {
|
||||
jest.useFakeTimers();
|
||||
jest.spyOn(global, 'setTimeout');
|
||||
|
||||
let data, nonce, password, text, user_sauce;
|
||||
data = '12345';
|
||||
password = 'myPassword';
|
||||
user_sauce =
|
||||
'6168de45af90c335967a8f9eae76f8f19bcb42fb8c3f602fee35f7617acdc489';
|
||||
nonce = 'ff786149d8242bb7802379bc5fd2f9ccc744a2e1f18bb0a8';
|
||||
text = 'a92528f78ca1f0812a4fb2ee5de4d16eb75d434318';
|
||||
|
||||
const result = await cryptoLibraryService.decryptSecret(text, nonce, password, user_sauce);
|
||||
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 60000);
|
||||
|
||||
return expect(
|
||||
result
|
||||
).toBe(data);
|
||||
});
|
||||
|
||||
it('encryptSecret', function() {
|
||||
let bytes_nonce,
|
||||
data,
|
||||
encrypted_data,
|
||||
encrypted_data2,
|
||||
password,
|
||||
user_sauce;
|
||||
bytes_nonce = 24;
|
||||
data = '12345';
|
||||
password = 'myPassword';
|
||||
user_sauce =
|
||||
'6168de45af90c335967a8f9eae76f8f19bcb42fb8c3f602fee35f7617acdc489';
|
||||
encrypted_data = cryptoLibraryService.encryptSecret(
|
||||
data,
|
||||
password,
|
||||
user_sauce
|
||||
);
|
||||
expect(encrypted_data.text).not.toBe(void 0);
|
||||
expect(encrypted_data.nonce).not.toBe(void 0);
|
||||
expect(converterService.fromHex(encrypted_data.text).length).toBeGreaterThan(
|
||||
0
|
||||
);
|
||||
expect(converterService.fromHex(encrypted_data.nonce).length).toBe(
|
||||
bytes_nonce
|
||||
);
|
||||
expect(
|
||||
cryptoLibraryService.decryptSecret(
|
||||
encrypted_data.text,
|
||||
encrypted_data.nonce,
|
||||
password,
|
||||
user_sauce
|
||||
)
|
||||
).toBe(data);
|
||||
encrypted_data2 = cryptoLibraryService.encryptSecret(
|
||||
data,
|
||||
password,
|
||||
user_sauce
|
||||
);
|
||||
return expect(encrypted_data.nonce).not.toBe(encrypted_data2.nonce);
|
||||
});
|
||||
|
||||
it('decryptData works', function() {
|
||||
let data, nonce, secret_key, text;
|
||||
data = '12345';
|
||||
secret_key =
|
||||
'9f3edbf7760d8ec1e8fd4a9c623b4fe569f324bf42c78770ef0a40a56495f92d';
|
||||
nonce = 'd65673e9abcf379493bba61a576535a82bcf8d735a915390';
|
||||
text = '9429f56f028a82ec44651bb7ea6b9f8baab3cd137e';
|
||||
return expect(cryptoLibraryService.decryptData(text, nonce, secret_key)).toBe(
|
||||
data
|
||||
);
|
||||
});
|
||||
|
||||
it('encryptData works', function() {
|
||||
let bytes_nonce, data, encrypted_data, encrypted_data2, secret_key;
|
||||
bytes_nonce = 24;
|
||||
data = '12345';
|
||||
secret_key =
|
||||
'9f3edbf7760d8ec1e8fd4a9c623b4fe569f324bf42c78770ef0a40a56495f92d';
|
||||
encrypted_data = cryptoLibraryService.encryptData(data, secret_key);
|
||||
expect(encrypted_data.text).not.toBe(void 0);
|
||||
expect(encrypted_data.nonce).not.toBe(void 0);
|
||||
expect(converterService.fromHex(encrypted_data.text).length).toBeGreaterThan(
|
||||
0
|
||||
);
|
||||
expect(converterService.fromHex(encrypted_data.nonce).length).toBe(
|
||||
bytes_nonce
|
||||
);
|
||||
expect(
|
||||
cryptoLibraryService.decryptData(
|
||||
encrypted_data.text,
|
||||
encrypted_data.nonce,
|
||||
secret_key
|
||||
)
|
||||
).toBe(data);
|
||||
encrypted_data2 = cryptoLibraryService.encryptData(data, secret_key);
|
||||
return expect(encrypted_data.nonce).not.toBe(encrypted_data2.nonce);
|
||||
});
|
||||
|
||||
it('decryptDataPublicKey works', function() {
|
||||
let data, nonce, pair, pair2, text;
|
||||
data = '12345';
|
||||
pair = {
|
||||
public_key:
|
||||
'ed7293c239164855aca4c2e6edb19e09bba41e3451603ec427782d45f2d57b39',
|
||||
private_key:
|
||||
'035f8aa4c86658a36d995df47c8e3d1e9a7a2a2f3efdcbdc1451ed4354350660'
|
||||
};
|
||||
pair2 = {
|
||||
public_key:
|
||||
'57531faba711e6e9bdea25229e63db4ce6eb79f0872d97cbfec74df0382dbf3a',
|
||||
private_key:
|
||||
'a04c3fbcb4dcf5df44bc433668bb686aac8991f83e993b971e73a0b37ace362c'
|
||||
};
|
||||
nonce = '538a2fc024e1ff7a791da88874099709bdb60ad62653529b';
|
||||
text = '0eedec49906748988b011741c8df4214e4dbeeda76';
|
||||
return expect(
|
||||
cryptoLibraryService.decryptDataPublicKey(
|
||||
text,
|
||||
nonce,
|
||||
pair2.public_key,
|
||||
pair.private_key
|
||||
)
|
||||
).toBe(data);
|
||||
});
|
||||
|
||||
it('encryptDataPublicKey works', function() {
|
||||
let bytes_nonce, data, encrypted_data, encrypted_data2, pair, pair2;
|
||||
bytes_nonce = 24;
|
||||
data = '12345';
|
||||
pair = {
|
||||
public_key:
|
||||
'ed7293c239164855aca4c2e6edb19e09bba41e3451603ec427782d45f2d57b39',
|
||||
private_key:
|
||||
'035f8aa4c86658a36d995df47c8e3d1e9a7a2a2f3efdcbdc1451ed4354350660'
|
||||
};
|
||||
pair2 = {
|
||||
public_key:
|
||||
'57531faba711e6e9bdea25229e63db4ce6eb79f0872d97cbfec74df0382dbf3a',
|
||||
private_key:
|
||||
'a04c3fbcb4dcf5df44bc433668bb686aac8991f83e993b971e73a0b37ace362c'
|
||||
};
|
||||
encrypted_data = cryptoLibraryService.encryptDataPublicKey(
|
||||
data,
|
||||
pair.public_key,
|
||||
pair2.private_key
|
||||
);
|
||||
expect(encrypted_data.text).not.toBe(void 0);
|
||||
expect(encrypted_data.nonce).not.toBe(void 0);
|
||||
expect(converterService.fromHex(encrypted_data.text).length).toBeGreaterThan(
|
||||
0
|
||||
);
|
||||
expect(converterService.fromHex(encrypted_data.nonce).length).toBe(
|
||||
bytes_nonce
|
||||
);
|
||||
expect(
|
||||
cryptoLibraryService.decryptDataPublicKey(
|
||||
encrypted_data.text,
|
||||
encrypted_data.nonce,
|
||||
pair2.public_key,
|
||||
pair.private_key
|
||||
)
|
||||
).toBe(data);
|
||||
encrypted_data2 = cryptoLibraryService.encryptDataPublicKey(
|
||||
data,
|
||||
pair.public_key,
|
||||
pair2.private_key
|
||||
);
|
||||
return expect(encrypted_data.nonce).not.toBe(encrypted_data2.nonce);
|
||||
});
|
||||
|
||||
it('generateUuid', function() {
|
||||
const regex = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i;
|
||||
expect(regex.test(cryptoLibraryService.generateUuid())).toBe(true);
|
||||
});
|
||||
|
||||
it("nacl's signing.verify works", function() {
|
||||
const nacl = require('ecma-nacl');
|
||||
// signing key pair can be generated from some seed array, which can
|
||||
// either be random itself, or be generated from a password
|
||||
const pair = nacl.signing.generate_keypair(
|
||||
cryptoLibraryService.randomBytes(32)
|
||||
);
|
||||
|
||||
// make signature bytes, for msg
|
||||
const msgSig = nacl.signing.signature(
|
||||
converterService.encodeUtf8(
|
||||
'test message that is some nice text or whatever that needs to be encrypted'
|
||||
),
|
||||
pair.skey
|
||||
);
|
||||
|
||||
// verify signature
|
||||
const sigIsOK = nacl.signing.verify(
|
||||
msgSig,
|
||||
converterService.encodeUtf8(
|
||||
'test message that is some nice text or whatever that needs to be encrypted'
|
||||
),
|
||||
pair.pkey
|
||||
);
|
||||
expect(sigIsOK).toBe(true);
|
||||
});
|
||||
|
||||
it('validate_signature', function() {
|
||||
expect(
|
||||
cryptoLibraryService.validateSignature(
|
||||
'test message that is some nice text or whatever that needs to be encrypted',
|
||||
'6e3302a696092fe3893d971391f94f2cb850d19fbbae9978122f0f465593bc06e65440e0ec929805b58e63fe719983201754a2a578c906c18b8ffa71e3234502',
|
||||
'967fd5c3c8386609c1ac57209a6f68a147a56518a7ed5df3285beea58d671f62'
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -108,8 +108,8 @@ function getDatastoreWithId(datastoreId) {
|
||||
// pass
|
||||
};
|
||||
|
||||
const onSuccess = async function (result) {
|
||||
const datastore_secret_key = await cryptoLibrary.decryptSecretKey(
|
||||
const onSuccess = function (result) {
|
||||
const datastore_secret_key = cryptoLibrary.decryptSecretKey(
|
||||
result.data.secret_key,
|
||||
result.data.secret_key_nonce
|
||||
);
|
||||
@ -119,7 +119,7 @@ function getDatastoreWithId(datastoreId) {
|
||||
let datastore = {};
|
||||
|
||||
if (result.data.data !== "") {
|
||||
const data = await cryptoLibrary.decryptData(result.data.data, result.data.data_nonce, datastore_secret_key);
|
||||
const data = cryptoLibrary.decryptData(result.data.data, result.data.data_nonce, datastore_secret_key);
|
||||
|
||||
datastore = JSON.parse(data);
|
||||
}
|
||||
@ -141,13 +141,13 @@ function getDatastoreWithId(datastoreId) {
|
||||
*
|
||||
* @returns {Promise} A promise with result of the operation
|
||||
*/
|
||||
async function createDatastore(type, description, isDefault) {
|
||||
function createDatastore(type, description, isDefault) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
//datastore does really not exist, lets create one and return it
|
||||
const secretKey = cryptoLibrary.generateSecretKey();
|
||||
const cipher = await cryptoLibrary.encryptSecretKey(secretKey);
|
||||
const cipher = cryptoLibrary.encryptSecretKey(secretKey);
|
||||
|
||||
const onError = function (result) {
|
||||
// pass
|
||||
@ -193,14 +193,13 @@ async function createDatastore(type, description, isDefault) {
|
||||
*
|
||||
* @returns {Promise} A promise with result of the operation
|
||||
*/
|
||||
async function deleteDatastore(datastoreId, password) {
|
||||
function deleteDatastore(datastoreId, password) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const authkey = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, password);
|
||||
const authkey = cryptoLibrary.generateAuthkey(getStore().getState().user.username, password);
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
|
@ -26,8 +26,7 @@ function createDuo(useSystemWideDuo, title, integration_key, secret_key, host) {
|
||||
uri: request.data["activation_code"],
|
||||
};
|
||||
};
|
||||
const onError = async function (request) {
|
||||
request = await request;
|
||||
const onError = function (request) {
|
||||
return Promise.reject(request.data);
|
||||
};
|
||||
return apiClient
|
||||
@ -86,8 +85,7 @@ function deleteDuo(duoId) {
|
||||
const onSuccess = function () {
|
||||
return true;
|
||||
};
|
||||
const onError = async function (data) {
|
||||
data = await data;
|
||||
const onError = function (data) {
|
||||
return Promise.reject(data.data);
|
||||
};
|
||||
return apiClient.deleteDuo(token, sessionSecretKey, duoId).then(onSuccess, onError);
|
||||
|
@ -33,12 +33,12 @@ function readEmergencyCodes() {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the emergency code
|
||||
*/
|
||||
async function createEmergencyCode(title, leadTime) {
|
||||
function createEmergencyCode(title, leadTime) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const emergencyPassword = cryptoLibrary.generateRecoveryCode();
|
||||
const emergencyAuthkey = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, emergencyPassword["base58"]);
|
||||
const emergencyAuthkey = cryptoLibrary.generateAuthkey(getStore().getState().user.username, emergencyPassword["base58"]);
|
||||
const emergencySauce = cryptoLibrary.generateUserSauce();
|
||||
|
||||
const emergencyDataDec = {
|
||||
@ -46,7 +46,7 @@ async function createEmergencyCode(title, leadTime) {
|
||||
user_secret_key: getStore().getState().user.userSecretKey,
|
||||
};
|
||||
|
||||
const emergency_data = await cryptoLibrary.encryptSecret(
|
||||
const emergency_data = cryptoLibrary.encryptSecret(
|
||||
JSON.stringify(emergencyDataDec),
|
||||
emergencyPassword["base58"],
|
||||
emergencySauce
|
||||
@ -59,8 +59,7 @@ async function createEmergencyCode(title, leadTime) {
|
||||
emergency_words: emergencyPassword["words"].join(" "),
|
||||
};
|
||||
};
|
||||
const onError = async function (request) {
|
||||
request = await request;
|
||||
const onError = function (request) {
|
||||
return Promise.reject(request.data);
|
||||
};
|
||||
return apiClient
|
||||
|
@ -446,9 +446,9 @@ function fetchDatastore(type, id, includeTrashBinItems, includeSharedItems) {
|
||||
*/
|
||||
function exportDatastore(type, includeTrashBinItems, includeSharedItems, password) {
|
||||
return fetchDatastore(type, undefined, includeTrashBinItems, includeSharedItems)
|
||||
.then(async function (data) {
|
||||
.then(function (data) {
|
||||
if (password) {
|
||||
data = JSON.stringify(await cryptoLibraryService.encryptSecret(data, password, ""))
|
||||
data = JSON.stringify(cryptoLibraryService.encryptSecret(data, password, ""))
|
||||
}
|
||||
return downloadExport(data, type, !!password);
|
||||
})
|
||||
|
@ -30,8 +30,7 @@ const registrations = {};
|
||||
function readFile(fileId) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -58,8 +57,7 @@ function readFile(fileId) {
|
||||
function createFile(shardId, fileRepositoryId, size, chunkCount, linkId, parentDatastoreId, parentShareId) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -94,13 +92,13 @@ function createFile(shardId, fileRepositoryId, size, chunkCount, linkId, parentD
|
||||
*
|
||||
* @returns {Promise} promise
|
||||
*/
|
||||
async function uploadShard(chunk, fileTransferId, fileTransferSecretKey, chunkPosition, shard, hashChecksum) {
|
||||
function uploadShard(chunk, fileTransferId, fileTransferSecretKey, chunkPosition, shard, hashChecksum) {
|
||||
const ticket = {
|
||||
chunk_position: chunkPosition,
|
||||
hash_checksum: hashChecksum,
|
||||
};
|
||||
|
||||
const ticketEncrypted = await cryptoLibrary.encryptData(JSON.stringify(ticket), fileTransferSecretKey);
|
||||
const ticketEncrypted = cryptoLibrary.encryptData(JSON.stringify(ticket), fileTransferSecretKey);
|
||||
|
||||
let fileserver;
|
||||
if (shard["fileserver"].length > 1) {
|
||||
@ -111,8 +109,7 @@ async function uploadShard(chunk, fileTransferId, fileTransferSecretKey, chunkPo
|
||||
fileserver = shard["fileserver"][0];
|
||||
}
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -145,14 +142,12 @@ function uploadFileRepositoryGcpCloudStorage(
|
||||
chunkPosition,
|
||||
hashChecksum
|
||||
) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -188,14 +183,12 @@ function uploadFileRepositoryAwsS3(
|
||||
chunkPosition,
|
||||
hashChecksum
|
||||
) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -231,14 +224,12 @@ function uploadFileRepositoryAzureBlob(
|
||||
chunkPosition,
|
||||
hashChecksum
|
||||
) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -274,14 +265,12 @@ function uploadFileRepositoryBackblaze(
|
||||
chunkPosition,
|
||||
hashChecksum
|
||||
) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -317,14 +306,12 @@ function uploadFileRepositoryOtherS3(
|
||||
chunkPosition,
|
||||
hashChecksum
|
||||
) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -360,14 +347,12 @@ function uploadFileRepositoryDoSpaces(
|
||||
chunkPosition,
|
||||
hashChecksum
|
||||
) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -474,8 +459,7 @@ function upload(
|
||||
function readShards() {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -580,14 +564,14 @@ function createShardReadDict(shards) {
|
||||
*
|
||||
* @returns {PromiseLike<T | void> | Promise<T | void> | *}
|
||||
*/
|
||||
async function shardDownload(fileTransferId, fileTransferSecretKey, shard, hashChecksum) {
|
||||
function shardDownload(fileTransferId, fileTransferSecretKey, shard, hashChecksum) {
|
||||
registrations["download_step_complete"]("DOWNLOADING_FILE_CHUNK");
|
||||
|
||||
const ticket = {
|
||||
hash_checksum: hashChecksum,
|
||||
};
|
||||
|
||||
const ticketEncrypted = await cryptoLibrary.encryptData(JSON.stringify(ticket), fileTransferSecretKey);
|
||||
const ticketEncrypted = cryptoLibrary.encryptData(JSON.stringify(ticket), fileTransferSecretKey);
|
||||
let fileserver;
|
||||
if (shard["fileserver"].length > 1) {
|
||||
// math random should be good enough here, don't use for crypto!
|
||||
@ -597,8 +581,7 @@ async function shardDownload(fileTransferId, fileTransferSecretKey, shard, hashC
|
||||
fileserver = shard["fileserver"][0];
|
||||
}
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
console.log(result);
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
@ -624,15 +607,13 @@ async function shardDownload(fileTransferId, fileTransferSecretKey, shard, hashC
|
||||
function fileRepositoryDownload(fileTransferId, fileTransferSecretKey, hashChecksum) {
|
||||
registrations["download_step_complete"]("DOWNLOADING_FILE_CHUNK");
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
console.log(result);
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
const onSuccess = function (result) {
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
console.log(result);
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
@ -92,8 +92,7 @@ function deleteGa(googleAuthenticatorId) {
|
||||
const onSuccess = function () {
|
||||
return true;
|
||||
};
|
||||
const onError = async function (data) {
|
||||
data = await data;
|
||||
const onError = function (data) {
|
||||
return Promise.reject(data.data);
|
||||
};
|
||||
return apiClientService.deleteGa(token, sessionSecretKey, googleAuthenticatorId).then(onSuccess, onError);
|
||||
|
@ -21,9 +21,9 @@ const group_private_key_cache = {};
|
||||
* @param {string} groupSecretKeyType The type of the encryption
|
||||
* @param {string} groupPublicKey The group's public key (necessary if the encryption is asymmetric)
|
||||
*
|
||||
* @returns {Promise<String>} Returns the secret key of a group
|
||||
* @returns {string} Returns the secret key of a group
|
||||
*/
|
||||
async function getGroupSecretKey(groupId, groupSecretKey, groupSecretKeyNonce, groupSecretKeyType, groupPublicKey) {
|
||||
function getGroupSecretKey(groupId, groupSecretKey, groupSecretKeyNonce, groupSecretKeyType, groupPublicKey) {
|
||||
if (group_secret_key_cache.hasOwnProperty(groupId)) {
|
||||
return group_secret_key_cache[groupId];
|
||||
}
|
||||
@ -42,9 +42,9 @@ async function getGroupSecretKey(groupId, groupSecretKey, groupSecretKeyNonce, g
|
||||
}
|
||||
}
|
||||
if (groupSecretKeyType === "symmetric") {
|
||||
group_secret_key_cache[groupId] = await cryptoLibraryService.decryptSecretKey(groupSecretKey, groupSecretKeyNonce);
|
||||
group_secret_key_cache[groupId] = cryptoLibraryService.decryptSecretKey(groupSecretKey, groupSecretKeyNonce);
|
||||
} else {
|
||||
group_secret_key_cache[groupId] = await cryptoLibraryService.decryptPrivateKey(
|
||||
group_secret_key_cache[groupId] = cryptoLibraryService.decryptPrivateKey(
|
||||
groupSecretKey,
|
||||
groupSecretKeyNonce,
|
||||
groupPublicKey
|
||||
@ -63,16 +63,16 @@ async function getGroupSecretKey(groupId, groupSecretKey, groupSecretKeyNonce, g
|
||||
* @param {string} groupPrivateKeyType The type of the encryption
|
||||
* @param {string} groupPublicKey The group's public key (necessary if the encryption is asymmetric)
|
||||
*
|
||||
* @returns {Promise<String>} Returns the private key of a group
|
||||
* @returns {string} Returns the private key of a group
|
||||
*/
|
||||
async function getGroupPrivateKey(groupId, groupPrivateKey, groupPrivateKeyNonce, groupPrivateKeyType, groupPublicKey) {
|
||||
function getGroupPrivateKey(groupId, groupPrivateKey, groupPrivateKeyNonce, groupPrivateKeyType, groupPublicKey) {
|
||||
if (group_private_key_cache.hasOwnProperty(groupId)) {
|
||||
return group_private_key_cache[groupId];
|
||||
}
|
||||
if (groupPrivateKeyType === "symmetric") {
|
||||
group_private_key_cache[groupId] = await cryptoLibraryService.decryptSecretKey(groupPrivateKey, groupPrivateKeyNonce);
|
||||
group_private_key_cache[groupId] = cryptoLibraryService.decryptSecretKey(groupPrivateKey, groupPrivateKeyNonce);
|
||||
} else {
|
||||
group_private_key_cache[groupId] = await cryptoLibraryService.decryptPrivateKey(
|
||||
group_private_key_cache[groupId] = cryptoLibraryService.decryptPrivateKey(
|
||||
groupPrivateKey,
|
||||
groupPrivateKeyNonce,
|
||||
groupPublicKey
|
||||
@ -90,11 +90,11 @@ async function getGroupPrivateKey(groupId, groupPrivateKey, groupPrivateKeyNonce
|
||||
* @param {string} encryptedMessage The encrypted message
|
||||
* @param {string} encryptedMessageNonce The nonce of the encrypted message
|
||||
*
|
||||
* @returns {Promise<String>} Returns the decrypted message
|
||||
* @returns {string} Returns the decrypted message
|
||||
*/
|
||||
async function decryptSecretKey(groupId, encryptedMessage, encryptedMessageNonce) {
|
||||
const secretKey = await getGroupSecretKey(groupId);
|
||||
return await cryptoLibraryService.decryptData(encryptedMessage, encryptedMessageNonce, secretKey);
|
||||
function decryptSecretKey(groupId, encryptedMessage, encryptedMessageNonce) {
|
||||
const secretKey = getGroupSecretKey(groupId);
|
||||
return cryptoLibraryService.decryptData(encryptedMessage, encryptedMessageNonce, secretKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,11 +106,11 @@ async function decryptSecretKey(groupId, encryptedMessage, encryptedMessageNonce
|
||||
* @param {string} encryptedMessageNonce The nonce of the encrypted message
|
||||
* @param {string} publicKey The corresponding public key
|
||||
*
|
||||
* @returns {Promise<String>} Returns the decrypted secret
|
||||
* @returns {string} Returns the decrypted secret
|
||||
*/
|
||||
async function decrypt_private_key(groupId, encryptedMessage, encryptedMessageNonce, publicKey) {
|
||||
const private_key = await getGroupPrivateKey(groupId);
|
||||
return await cryptoLibraryService.decryptDataPublicKey(encryptedMessage, encryptedMessageNonce, publicKey, private_key);
|
||||
function decrypt_private_key(groupId, encryptedMessage, encryptedMessageNonce, publicKey) {
|
||||
const private_key = getGroupPrivateKey(groupId);
|
||||
return cryptoLibraryService.decryptDataPublicKey(encryptedMessage, encryptedMessageNonce, publicKey, private_key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,7 +169,7 @@ function readGroups(forceFresh) {
|
||||
*
|
||||
* @returns {Promise} Returns whether the creation was successful or not
|
||||
*/
|
||||
async function createGroup(name) {
|
||||
function createGroup(name) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
@ -183,9 +183,9 @@ async function createGroup(name) {
|
||||
};
|
||||
|
||||
const group_secret_key = cryptoLibraryService.generateSecretKey();
|
||||
const group_secret_key_enc = await cryptoLibraryService.encryptSecretKey(group_secret_key);
|
||||
const group_key_pair = await cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
const group_private_key_enc = await cryptoLibraryService.encryptSecretKey(group_key_pair["private_key"]);
|
||||
const group_secret_key_enc = cryptoLibraryService.encryptSecretKey(group_secret_key);
|
||||
const group_key_pair = cryptoLibraryService.generatePublicPrivateKeypair();
|
||||
const group_private_key_enc = cryptoLibraryService.encryptSecretKey(group_key_pair["private_key"]);
|
||||
const group_public_key = group_key_pair["public_key"];
|
||||
|
||||
return apiClient
|
||||
@ -320,7 +320,7 @@ function getOutstandingGroupShares() {
|
||||
*
|
||||
* @returns {Promise} Returns whether the creation was successful or not
|
||||
*/
|
||||
async function createMembership(user, group, groupAdmin, shareAdmin) {
|
||||
function createMembership(user, group, groupAdmin, shareAdmin) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
@ -328,12 +328,11 @@ async function createMembership(user, group, groupAdmin, shareAdmin) {
|
||||
return request.data;
|
||||
};
|
||||
|
||||
const onError = async function (request) {
|
||||
request = await request;
|
||||
const onError = function (request) {
|
||||
return Promise.reject(request);
|
||||
};
|
||||
|
||||
const groupSecretKey = await getGroupSecretKey(
|
||||
const groupSecretKey = getGroupSecretKey(
|
||||
group.group_id,
|
||||
group.secret_key,
|
||||
group.secret_key_nonce,
|
||||
@ -341,7 +340,7 @@ async function createMembership(user, group, groupAdmin, shareAdmin) {
|
||||
group.public_key
|
||||
);
|
||||
|
||||
const groupPrivateKey = await getGroupPrivateKey(
|
||||
const groupPrivateKey = getGroupPrivateKey(
|
||||
group.group_id,
|
||||
group.private_key,
|
||||
group.private_key_nonce,
|
||||
@ -349,12 +348,12 @@ async function createMembership(user, group, groupAdmin, shareAdmin) {
|
||||
group.public_key
|
||||
);
|
||||
|
||||
const groupSecretKeyEncrypted = await cryptoLibraryService.encryptDataPublicKey(
|
||||
const groupSecretKeyEncrypted = cryptoLibraryService.encryptDataPublicKey(
|
||||
groupSecretKey,
|
||||
user.public_key,
|
||||
groupPrivateKey
|
||||
);
|
||||
const groupPrivateKeyEncrypted = await cryptoLibraryService.encryptDataPublicKey(
|
||||
const groupPrivateKeyEncrypted = cryptoLibraryService.encryptDataPublicKey(
|
||||
groupPrivateKey,
|
||||
user.public_key,
|
||||
groupPrivateKey
|
||||
@ -432,18 +431,18 @@ function deleteMembership(membershipId) {
|
||||
* @param {uuid} groupId The group id
|
||||
* @param {object} share The encrypted share
|
||||
*
|
||||
* @returns {Promise<object>} The decrypted sahre
|
||||
* @returns {object} The decrypted sahre
|
||||
*/
|
||||
async function decryptGroupShare(groupId, share) {
|
||||
const share_secret_key = await decryptSecretKey(groupId, share.share_key, share.share_key_nonce);
|
||||
function decryptGroupShare(groupId, share) {
|
||||
const share_secret_key = decryptSecretKey(groupId, share.share_key, share.share_key_nonce);
|
||||
const decrypted_share = shareService.decryptShare(share, share_secret_key);
|
||||
|
||||
if (typeof decrypted_share.name === "undefined") {
|
||||
decrypted_share.name = await decryptSecretKey(groupId, share.share_title, share.share_title_nonce);
|
||||
decrypted_share.name = decryptSecretKey(groupId, share.share_title, share.share_title_nonce);
|
||||
}
|
||||
|
||||
if (typeof decrypted_share.type === "undefined" && typeof share.share_type !== "undefined") {
|
||||
const type = await decryptSecretKey(groupId, share.share_type, share.share_type_nonce);
|
||||
const type = decryptSecretKey(groupId, share.share_type, share.share_type_nonce);
|
||||
|
||||
if (type !== "folder") {
|
||||
decrypted_share.type = type;
|
||||
@ -459,7 +458,7 @@ async function decryptGroupShare(groupId, share) {
|
||||
* @param {uuid} groupId The group id
|
||||
* @param {Array} shares A list of encrypted shares
|
||||
*
|
||||
* @returns {Promise<Array>} A list of decrypted shares
|
||||
* @returns {Array} A list of decrypted shares
|
||||
*/
|
||||
function decryptGroupShares(groupId, shares) {
|
||||
const decrypted_shares = [];
|
||||
@ -468,7 +467,7 @@ function decryptGroupShares(groupId, shares) {
|
||||
decrypted_shares.push(decrypted_share);
|
||||
}
|
||||
|
||||
return Promise.all(decrypted_shares);
|
||||
return decrypted_shares;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,9 +40,9 @@ function readHistory(secretHistoryId, secretKey) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const onSuccess = async function (content) {
|
||||
const onSuccess = function (content) {
|
||||
const secret = JSON.parse(
|
||||
await cryptoLibraryService.decryptData(content.data.data, content.data.data_nonce, secretKey)
|
||||
cryptoLibraryService.decryptData(content.data.data, content.data.data_nonce, secretKey)
|
||||
);
|
||||
secret["create_date"] = content.data["create_date"];
|
||||
secret["write_date"] = content.data["write_date"];
|
||||
|
@ -98,7 +98,7 @@ function info() {
|
||||
* @returns {Promise} Result of the check
|
||||
*/
|
||||
function checkHost(server, preApprovedVerifyKey) {
|
||||
const onSuccess = async function (response) {
|
||||
const onSuccess = function (response) {
|
||||
let checkResult;
|
||||
const data = response.data;
|
||||
const serverUrl = server.toLowerCase();
|
||||
@ -107,7 +107,7 @@ function checkHost(server, preApprovedVerifyKey) {
|
||||
info.version = "v" + splitVersion[0];
|
||||
info.build = splitVersion[2].replace(")", "");
|
||||
|
||||
if (!await cryptoLibrary.validateSignature(data["info"], data["signature"], data["verify_key"])) {
|
||||
if (!cryptoLibrary.validateSignature(data["info"], data["signature"], data["verify_key"])) {
|
||||
return {
|
||||
server_url: serverUrl,
|
||||
status: "invalid_signature",
|
||||
|
@ -1,306 +0,0 @@
|
||||
/**
|
||||
* Service which handles the actual parsing of the exported JSON
|
||||
*/
|
||||
|
||||
const Papa = require('papaparse');
|
||||
import helperService from './helper';
|
||||
import cryptoLibrary from './crypto-library';
|
||||
|
||||
let INDEX_URL = 0;
|
||||
let INDEX_URLS = 1;
|
||||
let INDEX_USERNAME = 2;
|
||||
let INDEX_PASSWORD = 3;
|
||||
let INDEX_NOTES = 4;
|
||||
let INDEX_NAME = 5;
|
||||
let INDEX_TYPE = 6;
|
||||
let INDEX_OTHERS = []
|
||||
|
||||
/**
|
||||
* Takes the first line of the csv and checks the columns and sets the indexes correctly for later field extraction.
|
||||
*
|
||||
* @param {[]} line First line of the CSV
|
||||
*
|
||||
* @returns {*} The secrets object
|
||||
*/
|
||||
function identifyRows(line) {
|
||||
for (let i = 0; i < line.length; i++) {
|
||||
const column_description = line[i].toLowerCase();
|
||||
if (column_description === "notes") {
|
||||
INDEX_NOTES = i;
|
||||
} else if(column_description === "password") {
|
||||
INDEX_PASSWORD = i;
|
||||
} else if(column_description === "title") {
|
||||
INDEX_NAME = i;
|
||||
} else if(column_description === "type") {
|
||||
INDEX_TYPE = i;
|
||||
} else if(column_description === "url") {
|
||||
INDEX_URL = i;
|
||||
} else if(column_description === "urls") {
|
||||
INDEX_URLS = i;
|
||||
} else if(column_description === "username") {
|
||||
INDEX_USERNAME = i;
|
||||
} else {
|
||||
INDEX_OTHERS.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getNoteExtras(line) {
|
||||
let extras = ''
|
||||
for (let i = 0; i < INDEX_OTHERS.length; i++) {
|
||||
if (!line[INDEX_OTHERS[i]]) {
|
||||
continue
|
||||
}
|
||||
extras = extras + "\n" + line[INDEX_OTHERS[i]];
|
||||
}
|
||||
return extras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of a line.
|
||||
*
|
||||
* Known types are:
|
||||
* Secure Note -> note
|
||||
* Identity
|
||||
* Password
|
||||
* Login
|
||||
* Credit Card
|
||||
* Server
|
||||
*
|
||||
* @param {[]} line One line of the CSV import
|
||||
*
|
||||
* @returns {string} Returns the appropriate type (note or website_password)
|
||||
*/
|
||||
function getType(line) {
|
||||
const contains_url = line[INDEX_URL] || line[INDEX_URLS] ;
|
||||
const contains_username = line[INDEX_USERNAME];
|
||||
const contains_password = line[INDEX_PASSWORD];
|
||||
|
||||
if (contains_url && (contains_username || contains_password)) {
|
||||
return "website_password";
|
||||
}
|
||||
if (contains_url) {
|
||||
return "bookmark";
|
||||
}
|
||||
if (contains_username || contains_password) {
|
||||
return "application_password";
|
||||
}
|
||||
|
||||
return "note";
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line that should represent a note and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a note
|
||||
*
|
||||
* @returns {*} The note secret object
|
||||
*/
|
||||
function transferIntoNote(line) {
|
||||
|
||||
let note_notes = '';
|
||||
if (line[INDEX_NOTES]) {
|
||||
note_notes = note_notes + line[INDEX_NOTES] + "\n";
|
||||
}
|
||||
|
||||
note_notes = note_notes + getNoteExtras(line);
|
||||
|
||||
if (! line[INDEX_NAME] && ! note_notes) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "note",
|
||||
name : line[INDEX_NAME],
|
||||
note_title: line[INDEX_NAME],
|
||||
note_notes: note_notes
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line that should represent a bookmark and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a website password
|
||||
*
|
||||
* @returns {*} The website_password secret object
|
||||
*/
|
||||
function transferIntoBookmark(line) {
|
||||
const url = line[INDEX_URL] || line[INDEX_URLS];
|
||||
const parsed_url = helperService.parseUrl(url);
|
||||
|
||||
return {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "bookmark",
|
||||
name : line[INDEX_NAME],
|
||||
"urlfilter" : parsed_url.authority || undefined,
|
||||
"bookmark_url_filter" : parsed_url.authority || undefined,
|
||||
"bookmark_notes" : line[INDEX_NOTES] + getNoteExtras(line),
|
||||
"bookmark_url" : url,
|
||||
"bookmark_title" : line[INDEX_NAME]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line that should represent a website passwords and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a website password
|
||||
*
|
||||
* @returns {*} The website_password secret object
|
||||
*/
|
||||
function transferIntoWebsitePassword(line) {
|
||||
|
||||
const url = line[INDEX_URL] || line[INDEX_URLS];
|
||||
const parsed_url = helperService.parseUrl(url);
|
||||
|
||||
return {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "website_password",
|
||||
name : line[INDEX_NAME],
|
||||
"urlfilter" : parsed_url.authority || undefined,
|
||||
"website_password_url_filter" : parsed_url.authority || undefined,
|
||||
"website_password_password" : line[INDEX_PASSWORD],
|
||||
"website_password_username" : line[INDEX_USERNAME],
|
||||
"website_password_notes" : line[INDEX_NOTES] + getNoteExtras(line),
|
||||
"website_password_url" : url,
|
||||
"website_password_title" : line[INDEX_NAME]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line that should represent an application passwords and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a application password
|
||||
*
|
||||
* @returns {*} The application_password secret object
|
||||
*/
|
||||
function transferIntoApplicationPassword(line) {
|
||||
|
||||
return {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "application_password",
|
||||
name : line[INDEX_NAME],
|
||||
"application_password_password" : line[INDEX_PASSWORD],
|
||||
"application_password_username" : line[INDEX_USERNAME],
|
||||
"application_password_notes" : line[INDEX_NOTES] + getNoteExtras(line),
|
||||
"application_password_title" : line[INDEX_NAME]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line, checks its type and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV
|
||||
*
|
||||
* @returns {*} The secrets object
|
||||
*/
|
||||
function transformToSecret(line) {
|
||||
const type = getType(line);
|
||||
if (type === 'note') {
|
||||
return transferIntoNote(line);
|
||||
} else if (type === 'bookmark') {
|
||||
return transferIntoBookmark(line);
|
||||
} else if (type === 'website_password') {
|
||||
return transferIntoWebsitePassword(line);
|
||||
} else if (type === 'application_password') {
|
||||
return transferIntoApplicationPassword(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fills the datastore with folders their content and together with the secrets object
|
||||
*
|
||||
* @param {object} datastore The datastore structure to search recursive
|
||||
* @param {[]} secrets The array containing all the found secrets
|
||||
* @param {[]} csv The array containing all the found secrets
|
||||
*/
|
||||
function gather_secrets(datastore, secrets, csv) {
|
||||
|
||||
let line;
|
||||
|
||||
for (let i = 0; i < csv.length; i++) {
|
||||
line = csv[i];
|
||||
|
||||
if (i === 0) {
|
||||
identifyRows(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.length < 2) {
|
||||
continue
|
||||
}
|
||||
|
||||
const secret = transformToSecret(line);
|
||||
|
||||
if (secret === null) {
|
||||
//empty line
|
||||
continue;
|
||||
}
|
||||
secrets.push(secret);
|
||||
datastore['items'].push(secret);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw data into an array of arrays
|
||||
*
|
||||
* @param {string} data The raw data to parse
|
||||
* @returns {Array} The array of arrays representing the CSV
|
||||
*/
|
||||
function parse_csv(data) {
|
||||
const csv = Papa.parse(data);
|
||||
|
||||
if (csv['errors'].length > 0) {
|
||||
throw new Error(csv['errors'][0]['message']);
|
||||
}
|
||||
|
||||
return csv['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function of this parser. Will take the content of the JSON export of a psono.pw client and will
|
||||
* return the usual output of a parser (or null):
|
||||
* {
|
||||
* datastore: {
|
||||
* name: 'Import TIMESTAMP'
|
||||
* },
|
||||
* secrets: Array
|
||||
* }
|
||||
*
|
||||
* @param {string} data The JSON export of a psono.pw client
|
||||
*
|
||||
* @returns {{datastore, secrets: Array} | null}
|
||||
*/
|
||||
function parser(data) {
|
||||
|
||||
const d = new Date();
|
||||
const n = d.toISOString();
|
||||
|
||||
const secrets = [];
|
||||
const datastore = {
|
||||
'id': cryptoLibrary.generateUuid(),
|
||||
'name': 'Import ' + n,
|
||||
'items': []
|
||||
};
|
||||
|
||||
let csv;
|
||||
try {
|
||||
csv = parse_csv(data);
|
||||
} catch(err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
gather_secrets(datastore, secrets, csv);
|
||||
|
||||
return {
|
||||
datastore: datastore,
|
||||
secrets: secrets
|
||||
}
|
||||
}
|
||||
|
||||
const import1passwordCsvService = {
|
||||
parser,
|
||||
};
|
||||
|
||||
export default import1passwordCsvService;
|
@ -1,104 +0,0 @@
|
||||
import React from 'react';
|
||||
import import1PasswordV7Csv from './import-1password-v7-csv';
|
||||
import cryptoLibrary from "../services/crypto-library";
|
||||
|
||||
|
||||
describe('Service: import1PasswordV7Csv test suite', function () {
|
||||
|
||||
it('helper exists', function() {
|
||||
expect(import1PasswordV7Csv).toBeDefined();
|
||||
});
|
||||
|
||||
it('parse', function () {
|
||||
|
||||
const generic_uuid = '1fce01f4-6411-47a9-885c-a80bf4c654aa'
|
||||
cryptoLibrary.generateUuid = jest.fn();
|
||||
cryptoLibrary.generateUuid.mockImplementation(() => generic_uuid);
|
||||
|
||||
const input = "\"UUID\",\"TITLE\",\"USERNAME\",\"PASSWORD\",\"SCOPE\",\"AUTOSUBMIT\",\"NOTES\",\"URL\",\"URLS\",\"SECTION_UNAZHCO2FJN3VMOVECXJ6VAPVQ 1: ONE-TIME PASSWORD\",\"SECTION_OCAAN7KL7H3NBCG4MS5U32HK4I 1: ONE-TIME PASSWORD\",\"SECTION_HMDIBYQYZTOO3T7VHQNL6RWD5Q 1: ONE-TIME PASSWORD\",\"SECTION_HMDIBYQYZTOO3T7VHQNL6RWD5Q 2: TOTP EMEA\",\"SECTION_25UMUV5BFEIKPG3CIR7GJZDZ2Q 1: ONE-TIME PASSWORD\",\"SECTION_EKCTDUQ7IY3LEL5Z3W7V6WSRYY 1: ONE-TIME PASSWORD\",\"SECTION_PNMULQU23IIE3APZCB47HX7NYY 1: ONE-TIME PASSWORD\",\"SECTION_2YB726SMDTKVK5BS2LLJG3C3EU 1: ONE-TIME PASSWORD\",\"SECTION_7NYM44Q42TTUKZZ7XQV3KJZJT4 1: ONE-TIME PASSWORD\",\"SECTION_ARWON2SMNJJB3DGYAYUDSSZG7I 1: ONE-TIME PASSWORD\",\"SECTION_I3U3L7I7VK2LQVJR2XYU6QMK2Y 1: ONE-TIME PASSWORD\"\n" +
|
||||
"\"ujidqjyjh4joibs7n6fn5tidha\",\"[Customer A] Password Entry 1\",\"seroczynski@discord.com\",\"StrongPassword123\",\"Default\",\"Default\",\"Uses another website\n" +
|
||||
"\n" +
|
||||
"Environment: Test/Prod\n" +
|
||||
"\n" +
|
||||
"Also works on GitLab.\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"\n" +
|
||||
"\"gnimeglnfrr6h4nvdvlzh63zba\",\"[Customer B] Password Entry 1\",\"seroczynski@discord.com\",\"AnotherStrongPassword123\",\"Default\",\"Default\",\"Note: authenticate with username, not email.\",\"https://discord.com/login\",\"https://psono.com/login\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"\n" +
|
||||
"\"wuzqa7o4ovpeboo2npneobb254\",\"[Customer B] Password Entry 2\",\"seroczynski@discord.com\",\"AnEvenStrongerPassword123\",\"Default\",\"Default\",\"1) Secret Question Answer 1\n" +
|
||||
"2) Secret Question Answer 2\n" +
|
||||
"3) Secret Question Answer 3\",\"https://discord/login\",\"https://psono.com/login\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"\n";
|
||||
|
||||
|
||||
const output = import1PasswordV7Csv.parser(input);
|
||||
|
||||
const expected_output = {
|
||||
"datastore": {
|
||||
"id": generic_uuid,
|
||||
"name": output.datastore.name,
|
||||
"items": [{
|
||||
"id": generic_uuid,
|
||||
"type": "application_password",
|
||||
"name": "[Customer A] Password Entry 1",
|
||||
"application_password_password": "StrongPassword123",
|
||||
"application_password_username": "seroczynski@discord.com",
|
||||
"application_password_notes": "Uses another website\n\nEnvironment: Test/Prod\n\nAlso works on GitLab.\nujidqjyjh4joibs7n6fn5tidha\nDefault\nDefault",
|
||||
"application_password_title": "[Customer A] Password Entry 1"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "website_password",
|
||||
"name": "[Customer B] Password Entry 1",
|
||||
"urlfilter": "discord.com",
|
||||
"website_password_url_filter": "discord.com",
|
||||
"website_password_password": "AnotherStrongPassword123",
|
||||
"website_password_username": "seroczynski@discord.com",
|
||||
"website_password_notes": "Note: authenticate with username, not email.\ngnimeglnfrr6h4nvdvlzh63zba\nDefault\nDefault",
|
||||
"website_password_url": "https://discord.com/login",
|
||||
"website_password_title": "[Customer B] Password Entry 1"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "website_password",
|
||||
"name": "[Customer B] Password Entry 2",
|
||||
"urlfilter": "discord",
|
||||
"website_password_url_filter": "discord",
|
||||
"website_password_password": "AnEvenStrongerPassword123",
|
||||
"website_password_username": "seroczynski@discord.com",
|
||||
"website_password_notes": "1) Secret Question Answer 1\n2) Secret Question Answer 2\n3) Secret Question Answer 3\nwuzqa7o4ovpeboo2npneobb254\nDefault\nDefault",
|
||||
"website_password_url": "https://discord/login",
|
||||
"website_password_title": "[Customer B] Password Entry 2"
|
||||
}]
|
||||
},
|
||||
"secrets": [{
|
||||
"id": generic_uuid,
|
||||
"type": "application_password",
|
||||
"name": "[Customer A] Password Entry 1",
|
||||
"application_password_password": "StrongPassword123",
|
||||
"application_password_username": "seroczynski@discord.com",
|
||||
"application_password_notes": "Uses another website\n\nEnvironment: Test/Prod\n\nAlso works on GitLab.\nujidqjyjh4joibs7n6fn5tidha\nDefault\nDefault",
|
||||
"application_password_title": "[Customer A] Password Entry 1"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "website_password",
|
||||
"name": "[Customer B] Password Entry 1",
|
||||
"urlfilter": "discord.com",
|
||||
"website_password_url_filter": "discord.com",
|
||||
"website_password_password": "AnotherStrongPassword123",
|
||||
"website_password_username": "seroczynski@discord.com",
|
||||
"website_password_notes": "Note: authenticate with username, not email.\ngnimeglnfrr6h4nvdvlzh63zba\nDefault\nDefault",
|
||||
"website_password_url": "https://discord.com/login",
|
||||
"website_password_title": "[Customer B] Password Entry 1"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "website_password",
|
||||
"name": "[Customer B] Password Entry 2",
|
||||
"urlfilter": "discord",
|
||||
"website_password_url_filter": "discord",
|
||||
"website_password_password": "AnEvenStrongerPassword123",
|
||||
"website_password_username": "seroczynski@discord.com",
|
||||
"website_password_notes": "1) Secret Question Answer 1\n2) Secret Question Answer 2\n3) Secret Question Answer 3\nwuzqa7o4ovpeboo2npneobb254\nDefault\nDefault",
|
||||
"website_password_url": "https://discord/login",
|
||||
"website_password_title": "[Customer B] Password Entry 2"
|
||||
}]
|
||||
};
|
||||
|
||||
expect(JSON.parse(JSON.stringify(output))).toEqual(expected_output);
|
||||
});
|
||||
|
||||
});
|
@ -1,405 +0,0 @@
|
||||
/**
|
||||
* Service which handles the actual parsing of a proton pass CSV export
|
||||
*/
|
||||
import * as OTPAuth from "otpauth";
|
||||
|
||||
const Papa = require('papaparse');
|
||||
import helperService from './helper';
|
||||
import cryptoLibrary from './crypto-library';
|
||||
|
||||
let INDEX_TYPE = 0;
|
||||
let INDEX_NAME = 1;
|
||||
let INDEX_URL = 2;
|
||||
let INDEX_EMAIL = 3;
|
||||
let INDEX_USERNAME = 4;
|
||||
let INDEX_PASSWORD = 5;
|
||||
let INDEX_NOTE = 6;
|
||||
let INDEX_TOTP = 7;
|
||||
let INDEX_OTHERS = []
|
||||
|
||||
/**
|
||||
* Takes the first line of the csv and checks the columns and sets the indexes correctly for later field extraction.
|
||||
*
|
||||
* @param {[]} line First line of the CSV
|
||||
*
|
||||
* @returns {*} The secrets object
|
||||
*/
|
||||
function identifyRows(line) {
|
||||
for (let i = 0; i < line.length; i++) {
|
||||
const column_description = line[i].toLowerCase();
|
||||
if (column_description === "note") {
|
||||
INDEX_NOTE = i;
|
||||
} else if(column_description === "password") {
|
||||
INDEX_PASSWORD = i;
|
||||
} else if(column_description === "name") {
|
||||
INDEX_NAME = i;
|
||||
} else if(column_description === "type") {
|
||||
INDEX_TYPE = i;
|
||||
} else if(column_description === "url") {
|
||||
INDEX_URL = i;
|
||||
} else if(column_description === "username") {
|
||||
INDEX_USERNAME = i;
|
||||
} else if(column_description === "email") {
|
||||
INDEX_EMAIL = i;
|
||||
} else {
|
||||
INDEX_OTHERS.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of a line.
|
||||
*
|
||||
* Known types are:
|
||||
* Secure Note -> note
|
||||
* Identity
|
||||
* Password
|
||||
* Login
|
||||
* Credit Card
|
||||
* Server
|
||||
*
|
||||
* @param {[]} line One line of the CSV import
|
||||
*
|
||||
* @returns {string} Returns the appropriate type (note or website_password)
|
||||
*/
|
||||
function getType(line) {
|
||||
|
||||
if (line[INDEX_TYPE] === 'alias') {
|
||||
return "note";
|
||||
}
|
||||
if (line[INDEX_TYPE] === 'note') {
|
||||
return "note";
|
||||
}
|
||||
if (line[INDEX_TYPE] === 'login' && line[INDEX_URL]) {
|
||||
return "website_password";
|
||||
}
|
||||
if (line[INDEX_TYPE] === 'login' && !line[INDEX_URL]) {
|
||||
return "application_password";
|
||||
}
|
||||
if (line[INDEX_TYPE] === 'creditCard') {
|
||||
return "credit_card";
|
||||
}
|
||||
|
||||
return "note";
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line that should represent a note and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a note
|
||||
*
|
||||
* @returns {*} The note secret object
|
||||
*/
|
||||
function transferIntoNote(line) {
|
||||
|
||||
let note_notes = '';
|
||||
if (line[INDEX_NOTE]) {
|
||||
note_notes = note_notes + line[INDEX_NOTE] + "\n";
|
||||
}
|
||||
|
||||
return {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "note",
|
||||
name : line[INDEX_NAME],
|
||||
note_title: line[INDEX_NAME],
|
||||
note_notes: note_notes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes a line that should represent a website passwords and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a website password
|
||||
*
|
||||
* @returns {*} The website_password secret object
|
||||
*/
|
||||
function transferIntoWebsitePassword(line) {
|
||||
|
||||
const url = line[INDEX_URL];
|
||||
const parsed_url = helperService.parseUrl(url);
|
||||
|
||||
let note = line[INDEX_NOTE];
|
||||
if (line[INDEX_NOTE]) {
|
||||
note = note + line[INDEX_NOTE] + "\n";
|
||||
}
|
||||
if (line[INDEX_USERNAME] && line[INDEX_EMAIL]) {
|
||||
note = note + "Email: " + line[INDEX_EMAIL] + "\n";
|
||||
}
|
||||
|
||||
const websitePassword = {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "website_password",
|
||||
name : line[INDEX_NAME],
|
||||
"urlfilter" : parsed_url.authority || undefined,
|
||||
"website_password_url_filter" : parsed_url.authority || undefined,
|
||||
"website_password_password" : line[INDEX_PASSWORD],
|
||||
"website_password_username" : line[INDEX_USERNAME] || line[INDEX_EMAIL],
|
||||
"website_password_notes" : note,
|
||||
"website_password_url" : url,
|
||||
"website_password_title" : line[INDEX_NAME]
|
||||
}
|
||||
|
||||
if (line[INDEX_TOTP]) {
|
||||
try {
|
||||
let parsedTotp = OTPAuth.URI.parse(line[INDEX_TOTP]);
|
||||
|
||||
websitePassword['website_password_totp_period'] = parsedTotp.period;
|
||||
websitePassword['website_password_totp_algorithm'] = parsedTotp.algorithm;
|
||||
websitePassword['website_password_totp_digits'] = parsedTotp.digits;
|
||||
websitePassword['website_password_totp_code'] = parsedTotp.secret.base32;
|
||||
} catch (e) {
|
||||
// pass.
|
||||
}
|
||||
}
|
||||
|
||||
return websitePassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line that should represent an application passwords and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a application password
|
||||
*
|
||||
* @returns {*} The application_password secret object
|
||||
*/
|
||||
function transferIntoApplicationPassword(line) {
|
||||
|
||||
let note = line[INDEX_NOTE];
|
||||
if (line[INDEX_NOTE]) {
|
||||
note = note + line[INDEX_NOTE] + "\n";
|
||||
}
|
||||
if (line[INDEX_USERNAME] && line[INDEX_EMAIL]) {
|
||||
note = note + "Email: " + line[INDEX_EMAIL] + "\n";
|
||||
}
|
||||
|
||||
return {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "application_password",
|
||||
name : line[INDEX_NAME],
|
||||
"application_password_password" : line[INDEX_PASSWORD],
|
||||
"application_password_username" : line[INDEX_USERNAME] || line[INDEX_EMAIL],
|
||||
"application_password_notes" : note,
|
||||
"application_password_title" : line[INDEX_NAME]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line that should represent an application passwords and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV that represents a application password
|
||||
*
|
||||
* @returns {*} The application_password secret object
|
||||
*/
|
||||
function transferIntoCreditCard(line) {
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(line[INDEX_NOTE])
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
if (!data.hasOwnProperty('cardholderName') ||!data.hasOwnProperty('number') ||!data.hasOwnProperty('verificationNumber') ||!data.hasOwnProperty('expirationDate') ||!data.hasOwnProperty('pin')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let note = '';
|
||||
if ( !data.hasOwnProperty('note')) {
|
||||
note = data['note'] + "\n";
|
||||
}
|
||||
|
||||
let expirationDate = '';
|
||||
if (data['expirationDate'] && data['expirationDate'].includes('-') && data['expirationDate'].length === 7) {
|
||||
const expirationDateParts = data['expirationDate'].split('-');
|
||||
expirationDate = expirationDateParts[1] + expirationDateParts[0].slice(2);
|
||||
} else {
|
||||
note = note + "Expiration date:" + data['expirationDate'] + "\n";
|
||||
}
|
||||
|
||||
return {
|
||||
id : cryptoLibrary.generateUuid(),
|
||||
type : "credit_card",
|
||||
name : line[INDEX_NAME],
|
||||
"credit_card_number" : data['number'].replace(/\s/g,''),
|
||||
"credit_card_name" : data['cardholderName'],
|
||||
"credit_card_cvc" : data['verificationNumber'],
|
||||
"credit_card_valid_through" : expirationDate,
|
||||
"credit_card_pin" : data['pin'],
|
||||
"credit_card_notes" : note,
|
||||
"credit_card_title" : line[INDEX_NAME]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes an item and transforms it into a note
|
||||
*
|
||||
* @param {[]} item One item of the json
|
||||
*
|
||||
* @returns {*} The secrets object
|
||||
*/
|
||||
function transformToTotpCode(item) {
|
||||
let name = line[INDEX_NAME] + ' TOTP';
|
||||
let totp_notes = "";
|
||||
let totp_period = 30;
|
||||
let totp_algorithm = "SHA1";
|
||||
let totp_digits = "6";
|
||||
let totp_code = "";
|
||||
let totp_title = line[INDEX_NAME] + ' TOTP';
|
||||
|
||||
try {
|
||||
let parsedTotp = OTPAuth.URI.parse(line[INDEX_TOTP]);
|
||||
totp_period = parsedTotp.period;
|
||||
totp_algorithm = parsedTotp.algorithm;
|
||||
totp_digits = parsedTotp.digits;
|
||||
totp_code = parsedTotp.secret.base32;
|
||||
} catch (e) {
|
||||
// pass.
|
||||
}
|
||||
|
||||
return {
|
||||
id: cryptoLibrary.generateUuid(),
|
||||
type: "totp",
|
||||
name: name,
|
||||
totp_notes: totp_notes,
|
||||
totp_code: totp_code,
|
||||
totp_digits: totp_digits,
|
||||
totp_algorithm: totp_algorithm,
|
||||
totp_period: totp_period,
|
||||
totp_title: totp_title,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a line, checks its type and transforms it into a proper secret object
|
||||
*
|
||||
* @param {[]} line One line of the CSV
|
||||
*
|
||||
* @returns {*} The secrets object
|
||||
*/
|
||||
function transformToSecret(line) {
|
||||
const type = getType(line);
|
||||
|
||||
if (type === 'note') {
|
||||
return transferIntoNote(line);
|
||||
} else if (type === 'website_password') {
|
||||
return transferIntoWebsitePassword(line);
|
||||
} else if (type === 'application_password') {
|
||||
return transferIntoApplicationPassword(line);
|
||||
} else if (type === 'credit_card') {
|
||||
return transferIntoCreditCard(line);
|
||||
}
|
||||
}
|
||||
|
||||
function needsSeparateTotp(line) {
|
||||
const type = getType(line);
|
||||
const hasTotp = Boolean(line[INDEX_TOTP]);
|
||||
|
||||
return hasTotp && type !== "website_password"
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fills the datastore with folders their content and together with the secrets object
|
||||
*
|
||||
* @param {object} datastore The datastore structure to search recursive
|
||||
* @param {[]} secrets The array containing all the found secrets
|
||||
* @param {[]} csv The array containing all the found secrets
|
||||
*/
|
||||
function gather_secrets(datastore, secrets, csv) {
|
||||
|
||||
let line;
|
||||
|
||||
for (let i = 0; i < csv.length; i++) {
|
||||
line = csv[i];
|
||||
|
||||
if (i === 0) {
|
||||
identifyRows(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.length < 2) {
|
||||
continue
|
||||
}
|
||||
|
||||
const secret = transformToSecret(line);
|
||||
|
||||
if (needsSeparateTotp(line)) {
|
||||
const totpEntry = transformToTotpCode(line);
|
||||
if (totpEntry !== null) {
|
||||
secrets.push(totpEntry);
|
||||
datastore['items'].push(totpEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if (secret === null) {
|
||||
//empty line
|
||||
continue;
|
||||
}
|
||||
secrets.push(secret);
|
||||
datastore['items'].push(secret);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw data into an array of arrays
|
||||
*
|
||||
* @param {string} data The raw data to parse
|
||||
* @returns {Array} The array of arrays representing the CSV
|
||||
*/
|
||||
function parse_csv(data) {
|
||||
const csv = Papa.parse(data);
|
||||
|
||||
if (csv['errors'].length > 0) {
|
||||
throw new Error(csv['errors'][0]['message']);
|
||||
}
|
||||
|
||||
return csv['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function of this parser. Will take the content of the JSON export of a psono.pw client and will
|
||||
* return the usual output of a parser (or null):
|
||||
* {
|
||||
* datastore: {
|
||||
* name: 'Import TIMESTAMP'
|
||||
* },
|
||||
* secrets: Array
|
||||
* }
|
||||
*
|
||||
* @param {string} data The JSON export of a psono.pw client
|
||||
*
|
||||
* @returns {{datastore, secrets: Array} | null}
|
||||
*/
|
||||
function parser(data) {
|
||||
|
||||
const d = new Date();
|
||||
const n = d.toISOString();
|
||||
|
||||
const secrets = [];
|
||||
const datastore = {
|
||||
'id': cryptoLibrary.generateUuid(),
|
||||
'name': 'Import ' + n,
|
||||
'items': []
|
||||
};
|
||||
|
||||
let csv;
|
||||
try {
|
||||
csv = parse_csv(data);
|
||||
} catch(err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
gather_secrets(datastore, secrets, csv);
|
||||
|
||||
return {
|
||||
datastore: datastore,
|
||||
secrets: secrets
|
||||
}
|
||||
}
|
||||
|
||||
const importProtonPassCsvService = {
|
||||
parser,
|
||||
};
|
||||
|
||||
export default importProtonPassCsvService;
|
@ -1,115 +0,0 @@
|
||||
import React from 'react';
|
||||
import importProtonPassCsv from './import-protonpass-csv';
|
||||
import cryptoLibrary from "../services/crypto-library";
|
||||
|
||||
|
||||
describe('Service: importProtonPassCsv test suite', function () {
|
||||
|
||||
it('helper exists', function() {
|
||||
expect(importProtonPassCsv).toBeDefined();
|
||||
});
|
||||
|
||||
it('parse', function () {
|
||||
|
||||
const generic_uuid = '1fce01f4-6411-47a9-885c-a80bf4c654aa'
|
||||
cryptoLibrary.generateUuid = jest.fn();
|
||||
cryptoLibrary.generateUuid.mockImplementation(() => generic_uuid);
|
||||
|
||||
const input = "type,name,url,email,username,password,note,totp,createTime,modifyTime,vault\n" +
|
||||
"alias,Alias name,,test@domain.com,,,login note or empty,,1710968710,1720675211,Personal\n" +
|
||||
"login,example.com,https://example.com/login,test@domain.com,,testpassword,,otpauth://totp/ACME%20Co:john.doe@email.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30,1717796629,1717796629,Personal\n" +
|
||||
"creditCard,TEST CARD,,,,,\"{\"\"cardholderName\"\":\"\"TEST\"\",\"\"cardType\"\":0,\"\"number\"\":\"\"123456789000\"\",\"\"verificationNumber\"\":\"\"123\"\",\"\"expirationDate\"\":\"\"2022-12\"\",\"\"pin\"\":\"\"1234\"\",\"\"note\"\":\"\"Test card\"\"}\",,1721903817,1721903817,Personal\n" +
|
||||
"note,Test note,,,,,Note content,,1721903847,1721903847,Personal";
|
||||
|
||||
|
||||
const output = importProtonPassCsv.parser(input);
|
||||
|
||||
const expected_output = {
|
||||
"datastore": {
|
||||
"id": generic_uuid,
|
||||
"name": output.datastore.name,
|
||||
"items": [{
|
||||
"id": generic_uuid,
|
||||
"type": "note",
|
||||
"name": "Alias name",
|
||||
"note_title": "Alias name",
|
||||
"note_notes": "login note or empty\n"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "website_password",
|
||||
"name": "example.com",
|
||||
"urlfilter": "example.com",
|
||||
"website_password_url_filter": "example.com",
|
||||
"website_password_password": "testpassword",
|
||||
"website_password_username": "test@domain.com",
|
||||
"website_password_notes": "",
|
||||
"website_password_url": "https://example.com/login",
|
||||
"website_password_title": "example.com",
|
||||
"website_password_totp_algorithm": "SHA1",
|
||||
"website_password_totp_code": "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ",
|
||||
"website_password_totp_digits": 6,
|
||||
"website_password_totp_period": 30
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "credit_card",
|
||||
"name": "TEST CARD",
|
||||
"credit_card_number": "123456789000",
|
||||
"credit_card_name": "TEST",
|
||||
"credit_card_cvc": "123",
|
||||
"credit_card_valid_through": "1222",
|
||||
"credit_card_pin": "1234",
|
||||
"credit_card_notes": "",
|
||||
"credit_card_title": "TEST CARD"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "note",
|
||||
"name": "Test note",
|
||||
"note_title": "Test note",
|
||||
"note_notes": "Note content\n"
|
||||
}]
|
||||
},
|
||||
"secrets": [{
|
||||
"id": generic_uuid,
|
||||
"type": "note",
|
||||
"name": "Alias name",
|
||||
"note_title": "Alias name",
|
||||
"note_notes": "login note or empty\n"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "website_password",
|
||||
"name": "example.com",
|
||||
"urlfilter": "example.com",
|
||||
"website_password_url_filter": "example.com",
|
||||
"website_password_password": "testpassword",
|
||||
"website_password_username": "test@domain.com",
|
||||
"website_password_notes": "",
|
||||
"website_password_url": "https://example.com/login",
|
||||
"website_password_title": "example.com",
|
||||
"website_password_totp_algorithm": "SHA1",
|
||||
"website_password_totp_code": "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ",
|
||||
"website_password_totp_digits": 6,
|
||||
"website_password_totp_period": 30
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "credit_card",
|
||||
"name": "TEST CARD",
|
||||
"credit_card_number": "123456789000",
|
||||
"credit_card_name": "TEST",
|
||||
"credit_card_cvc": "123",
|
||||
"credit_card_valid_through": "1222",
|
||||
"credit_card_pin": "1234",
|
||||
"credit_card_notes": "",
|
||||
"credit_card_title": "TEST CARD"
|
||||
}, {
|
||||
"id": generic_uuid,
|
||||
"type": "note",
|
||||
"name": "Test note",
|
||||
"note_title": "Test note",
|
||||
"note_notes": "Note content\n"
|
||||
}]
|
||||
};
|
||||
|
||||
expect(JSON.parse(JSON.stringify(output))).toEqual(expected_output);
|
||||
});
|
||||
|
||||
});
|
@ -19,11 +19,8 @@ import importLastpassComCsv from "./import-lastpass-com-csv";
|
||||
import importPwsafeOrgCsv from "./import-pwsafe-org-csv";
|
||||
import importTeampassNetCsv from "./import-teampass-net-csv";
|
||||
import importNextcloudCsvService from "./import-nextcloud-csv";
|
||||
import import1passwordV7CsvService from "./import-1password-v7-csv";
|
||||
import import1passwordV8CsvService from "./import-1password-v8-csv";
|
||||
import cryptoLibraryService from "./crypto-library";
|
||||
import i18n from "../i18n";
|
||||
import importProtonPassCsvService from "./import-protonpass-csv";
|
||||
|
||||
const _importer = {
|
||||
psono_pw_json: {
|
||||
@ -31,16 +28,6 @@ const _importer = {
|
||||
value: "psono_pw_json",
|
||||
parser: importPsonoJson.parser,
|
||||
},
|
||||
one_password_v8: {
|
||||
name: "1Password v8 (CSV)",
|
||||
value: "one_password_v8",
|
||||
parser: import1passwordV8CsvService.parser,
|
||||
},
|
||||
one_password_v7: {
|
||||
name: "1Password v7 (CSV)",
|
||||
value: "one_password_v7",
|
||||
parser: import1passwordV7CsvService.parser,
|
||||
},
|
||||
chrome_csv: {
|
||||
name: "Chrome (CSV)",
|
||||
help: function () {
|
||||
@ -57,11 +44,6 @@ const _importer = {
|
||||
value: "firefox_csv",
|
||||
parser: importFirefoxCsvService.parser,
|
||||
},
|
||||
protonpass_csv: {
|
||||
name: "Proton Pass (CSV)",
|
||||
value: "protonpass_csv",
|
||||
parser: importProtonPassCsvService.parser,
|
||||
},
|
||||
safari_csv: {
|
||||
name: "Safari (CSV)",
|
||||
value: "safari_csv",
|
||||
@ -269,8 +251,7 @@ function createSecrets(parsedData) {
|
||||
})
|
||||
emit("create-secret-complete", {});
|
||||
return parsedData;
|
||||
}, async function (result) {
|
||||
result = await result;
|
||||
}, function (result) {
|
||||
return Promise.reject(result)
|
||||
});
|
||||
});
|
||||
@ -318,7 +299,7 @@ function getImporterHelp(type) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the result of the import
|
||||
*/
|
||||
async function importDatastore(type, data, password) {
|
||||
function importDatastore(type, data, password) {
|
||||
emit("import-started", {});
|
||||
|
||||
if (password) {
|
||||
@ -329,20 +310,20 @@ async function importDatastore(type, data, password) {
|
||||
// datastore was not json encoded and as such cannot be an encrypted Export
|
||||
}
|
||||
if (decryptedJson && decryptedJson.hasOwnProperty("text") && decryptedJson.hasOwnProperty("nonce")) {
|
||||
try {
|
||||
data = await cryptoLibraryService.decryptSecret(decryptedJson['text'], decryptedJson['nonce'], password, "")
|
||||
} catch (e) {
|
||||
return Promise.reject({errors: ["DECRYPTION_OF_EXPORT_FAILED_WRONG_PASSWORD"]})
|
||||
try{
|
||||
data = cryptoLibraryService.decryptSecret(decryptedJson['text'], decryptedJson['nonce'], password, "")
|
||||
} catch(e) {
|
||||
return Promise.reject({ errors: ["DECRYPTION_OF_EXPORT_FAILED_WRONG_PASSWORD"] })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve({type: type, data: data})
|
||||
return Promise.resolve({ type: type, data: data })
|
||||
.then(parseExport)
|
||||
.then(createSecrets)
|
||||
.then(updateDatastore)
|
||||
.then(function () {
|
||||
return {msgs: ["IMPORT_SUCCESSFUL"]};
|
||||
return { msgs: ["IMPORT_SUCCESSFUL"] };
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,9 @@ import helper from "./helper";
|
||||
// const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
//
|
||||
// const onSuccess = function (result) {
|
||||
// result.data.private_key = await cryptoLibrary.decryptSecretKey(result.data.private_key, result.data.private_key_nonce);
|
||||
// result.data.private_key = cryptoLibrary.decryptSecretKey(result.data.private_key, result.data.private_key_nonce);
|
||||
// delete result.data.private_key_nonce;
|
||||
// result.data.secret_key = await cryptoLibrary.decryptSecretKey(result.data.secret_key, result.data.secret_key_nonce);
|
||||
// result.data.secret_key = cryptoLibrary.decryptSecretKey(result.data.secret_key, result.data.secret_key_nonce);
|
||||
// delete result.data.secret_key_nonce;
|
||||
//
|
||||
// return result.data;
|
||||
@ -61,10 +61,10 @@ function readLinkShares() {
|
||||
*
|
||||
* @returns {Object} Promise with the secret
|
||||
*/
|
||||
async function readSecretWithLinkShare(encryptedSecret, item) {
|
||||
function readSecretWithLinkShare(encryptedSecret, item) {
|
||||
// normal secret
|
||||
const data = JSON.parse(
|
||||
await cryptoLibrary.decryptData(encryptedSecret.secret_data, encryptedSecret.secret_data_nonce, item.secret_key)
|
||||
cryptoLibrary.decryptData(encryptedSecret.secret_data, encryptedSecret.secret_data_nonce, item.secret_key)
|
||||
);
|
||||
|
||||
const newItem = helper.duplicateObject(item);
|
||||
@ -107,9 +107,9 @@ function readFileWithLinkShare(encryptedFileMeta, shareLinkData) {
|
||||
* @returns {Promise} Promise with the secret
|
||||
*/
|
||||
function linkShareAccessRead(linkShareId, linkShareSecret, passphrase) {
|
||||
const onSuccess = async function (result) {
|
||||
const onSuccess = function (result) {
|
||||
const share_link_data = JSON.parse(
|
||||
await cryptoLibrary.decryptData(result.data.node, result.data.node_nonce, linkShareSecret)
|
||||
cryptoLibrary.decryptData(result.data.node, result.data.node_nonce, linkShareSecret)
|
||||
);
|
||||
|
||||
if (share_link_data.type === "file") {
|
||||
@ -119,8 +119,8 @@ function linkShareAccessRead(linkShareId, linkShareSecret, passphrase) {
|
||||
return readSecretWithLinkShare(result.data, share_link_data);
|
||||
}
|
||||
};
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
console.log(result);
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -138,17 +138,17 @@ function linkShareAccessRead(linkShareId, linkShareSecret, passphrase) {
|
||||
*
|
||||
* @returns {Promise} Promise with the secret
|
||||
*/
|
||||
async function linkShareAccessWrite(linkShareId, linkShareSecret, secretKey, content, passphrase) {
|
||||
function linkShareAccessWrite(linkShareId, linkShareSecret, secretKey, content, passphrase) {
|
||||
|
||||
const jsonContent = JSON.stringify(content);
|
||||
|
||||
const c = await cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
const c = cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
|
||||
const onSuccess = function (result) {
|
||||
return result.data
|
||||
};
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
console.log(result);
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
@ -177,8 +177,7 @@ function createLinkShare(secretId, fileId, node, nodeNonce, publicTitle, allowed
|
||||
const onSuccess = function (result) {
|
||||
return result.data;
|
||||
};
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result);
|
||||
};
|
||||
|
||||
@ -217,8 +216,7 @@ function updateLinkShare(linkShareId, publicTitle, allowedReads, passphrase, val
|
||||
const onSuccess = function (result) {
|
||||
return result.data;
|
||||
};
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
|
@ -70,7 +70,7 @@ function isLocked() {
|
||||
*
|
||||
* @returns {boolean} locked status
|
||||
*/
|
||||
async function unlock(password) {
|
||||
function unlock(password) {
|
||||
if (typeof password === "undefined") {
|
||||
password = "";
|
||||
}
|
||||
@ -81,7 +81,7 @@ async function unlock(password) {
|
||||
}
|
||||
let newEncryptionKey;
|
||||
try {
|
||||
newEncryptionKey = await cryptoLibrary.decryptSecret(
|
||||
newEncryptionKey = cryptoLibrary.decryptSecret(
|
||||
encryptionKeyEncrypted.text,
|
||||
encryptionKeyEncrypted.nonce,
|
||||
password,
|
||||
@ -91,7 +91,7 @@ async function unlock(password) {
|
||||
return false;
|
||||
}
|
||||
setEncryptionKey(newEncryptionKey);
|
||||
browserClient.emitSec("set-offline-cache-encryption-key", {encryption_key: newEncryptionKey});
|
||||
browserClient.emitSec("set-offline-cache-encryption-key", { encryption_key: newEncryptionKey });
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -122,17 +122,17 @@ function setEncryptionKey(newEncryptionKey) {
|
||||
*
|
||||
* @param {string} password The password
|
||||
*/
|
||||
async function setEncryptionPassword(password) {
|
||||
function setEncryptionPassword(password) {
|
||||
const new_encryption_key = cryptoLibrary.generateSecretKey();
|
||||
setEncryptionKey(new_encryption_key);
|
||||
const offlineCacheEncryptionSalt = cryptoLibrary.generateSecretKey();
|
||||
const offlineCacheEncryptionKey = await cryptoLibrary.encryptSecret(
|
||||
const offlineCacheEncryptionKey = cryptoLibrary.encryptSecret(
|
||||
new_encryption_key,
|
||||
password,
|
||||
offlineCacheEncryptionSalt
|
||||
);
|
||||
action().setOfflineCacheEncryptionInfo(offlineCacheEncryptionKey, offlineCacheEncryptionSalt);
|
||||
browserClient.emitSec("set-offline-cache-encryption-key", {encryption_key: new_encryption_key});
|
||||
browserClient.emitSec("set-offline-cache-encryption-key", { encryption_key: new_encryption_key });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,7 +144,7 @@ async function setEncryptionPassword(password) {
|
||||
*
|
||||
* @returns {Promise} promise
|
||||
*/
|
||||
async function set(url, method, data) {
|
||||
function set(url, method, data) {
|
||||
if (method !== "GET" || !isActive()) {
|
||||
return;
|
||||
}
|
||||
@ -152,10 +152,10 @@ async function set(url, method, data) {
|
||||
let value = JSON.stringify(data);
|
||||
|
||||
if (encryptionKey) {
|
||||
value = await cryptoLibrary.encryptData(value, encryptionKey);
|
||||
value = cryptoLibrary.encryptData(value, encryptionKey);
|
||||
}
|
||||
|
||||
storage.upsert("offline-cache", {key: url.toLowerCase(), value: value});
|
||||
storage.upsert("offline-cache", { key: url.toLowerCase(), value: value });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +178,7 @@ function get(url, method) {
|
||||
});
|
||||
}
|
||||
|
||||
return storage.findKey("offline-cache", url.toLowerCase()).then(async (storageEntry) => {
|
||||
return storage.findKey("offline-cache", url.toLowerCase()).then((storageEntry) => {
|
||||
if (storageEntry === null) {
|
||||
return null;
|
||||
}
|
||||
@ -186,7 +186,7 @@ function get(url, method) {
|
||||
let value = storageEntry.value;
|
||||
|
||||
if (encryptionKey) {
|
||||
value = await cryptoLibrary.decryptData(value.text, value.nonce, encryptionKey);
|
||||
value = cryptoLibrary.decryptData(value.text, value.nonce, encryptionKey);
|
||||
}
|
||||
|
||||
return JSON.parse(value);
|
||||
|
@ -12,12 +12,12 @@ import cryptoLibrary from "./crypto-library";
|
||||
*
|
||||
* @returns {promise} Returns a promise with the username, recovery_code_id and private_key to decrypt the saved data
|
||||
*/
|
||||
async function recoveryGenerateInformation() {
|
||||
function recoveryGenerateInformation() {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const recoveryPassword = cryptoLibrary.generateRecoveryCode();
|
||||
const recoveryAuthkey = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, recoveryPassword["base58"]);
|
||||
const recoveryAuthkey = cryptoLibrary.generateAuthkey(getStore().getState().user.username, recoveryPassword["base58"]);
|
||||
const recoverySauce = cryptoLibrary.generateUserSauce();
|
||||
|
||||
const recovery_data_dec = {
|
||||
@ -25,7 +25,7 @@ async function recoveryGenerateInformation() {
|
||||
user_secret_key: getStore().getState().user.userSecretKey,
|
||||
};
|
||||
|
||||
const recovery_data = await cryptoLibrary.encryptSecret(
|
||||
const recovery_data = cryptoLibrary.encryptSecret(
|
||||
JSON.stringify(recovery_data_dec),
|
||||
recoveryPassword["base58"],
|
||||
recoverySauce
|
||||
|
@ -21,19 +21,19 @@ import { getStore } from "./store";
|
||||
*
|
||||
* @returns {Promise} Returns a promise with a list of dictionaries with the new secret_id and provided link_ids
|
||||
*/
|
||||
async function createSecretBulk(objects, parentDatastoreId, parentShareId) {
|
||||
function createSecretBulk(objects, parentDatastoreId, parentShareId) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const encryptionKeyLookup = {};
|
||||
|
||||
const bulkObjects = await Promise.all(objects.map(async function (o) {
|
||||
const bulkObjects = objects.map(function(o) {
|
||||
|
||||
const secretKey = cryptoLibrary.generateSecretKey();
|
||||
encryptionKeyLookup[o.linkId] = secretKey;
|
||||
const jsonContent = JSON.stringify(o.content);
|
||||
|
||||
const c = await cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
const c = cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
|
||||
return {
|
||||
'data': c.text,
|
||||
@ -43,16 +43,16 @@ async function createSecretBulk(objects, parentDatastoreId, parentShareId) {
|
||||
'callback_user': o.callbackUser,
|
||||
'callback_pass': o.callbackPass,
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result);
|
||||
};
|
||||
|
||||
const onSuccess = function (response) {
|
||||
return response.data.secrets.map(function (s) {
|
||||
return {secret_id: s.secret_id, secret_key: encryptionKeyLookup[s.link_id], link_id: s.link_id}
|
||||
return response.data.secrets.map(function(s) {
|
||||
return { secret_id: s.secret_id, secret_key: encryptionKeyLookup[s.link_id], link_id: s.link_id }
|
||||
})
|
||||
};
|
||||
|
||||
@ -79,21 +79,21 @@ async function createSecretBulk(objects, parentDatastoreId, parentShareId) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the new secret_id
|
||||
*/
|
||||
async function createSecret(content, linkId, parentDatastoreId, parentShareId, callbackUrl, callbackUser, callbackPass) {
|
||||
function createSecret(content, linkId, parentDatastoreId, parentShareId, callbackUrl, callbackUser, callbackPass) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
const secretKey = cryptoLibrary.generateSecretKey();
|
||||
|
||||
const jsonContent = JSON.stringify(content);
|
||||
|
||||
const c = await cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
const c = cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
|
||||
const onError = function (result) {
|
||||
// pass
|
||||
};
|
||||
|
||||
const onSuccess = function (response) {
|
||||
return {secret_id: response.data.secret_id, secret_key: secretKey};
|
||||
return { secret_id: response.data.secret_id, secret_key: secretKey };
|
||||
};
|
||||
|
||||
return apiClient
|
||||
@ -123,13 +123,12 @@ async function createSecret(content, linkId, parentDatastoreId, parentShareId, c
|
||||
function readSecret(secretId, secretKey) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result);
|
||||
};
|
||||
|
||||
const onSuccess = async function (content) {
|
||||
const secret = JSON.parse(await cryptoLibrary.decryptData(content.data.data, content.data.data_nonce, secretKey));
|
||||
const onSuccess = function (content) {
|
||||
const secret = JSON.parse(cryptoLibrary.decryptData(content.data.data, content.data.data_nonce, secretKey));
|
||||
if (content.data) {
|
||||
secret["read_count"] = content.data["read_count"];
|
||||
}
|
||||
@ -155,20 +154,20 @@ function readSecret(secretId, secretKey) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the secret id
|
||||
*/
|
||||
async function writeSecret(secretId, secretKey, content, callbackUrl, callbackUser, callbackPass) {
|
||||
function writeSecret(secretId, secretKey, content, callbackUrl, callbackUser, callbackPass) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const jsonContent = JSON.stringify(content);
|
||||
|
||||
const c = await cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
const c = cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
|
||||
const onError = function (result) {
|
||||
console.log(result);
|
||||
};
|
||||
|
||||
const onSuccess = function (response) {
|
||||
return {secret_id: response.data.secret_id};
|
||||
return { secret_id: response.data.secret_id };
|
||||
};
|
||||
|
||||
return apiClient
|
||||
|
@ -609,13 +609,13 @@ function generateSecurityReport(password, checkHaveibeenpwned) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise to indicate the success of this or not
|
||||
*/
|
||||
async function sendToServer(analysis, checkHaveibeenpwned, masterPassword) {
|
||||
function sendToServer(analysis, checkHaveibeenpwned, masterPassword) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const entries = [];
|
||||
|
||||
const authkey = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, masterPassword);
|
||||
const authkey = cryptoLibrary.generateAuthkey(getStore().getState().user.username, masterPassword);
|
||||
|
||||
for (let i = 0; i < analysis["passwords"].length; i++) {
|
||||
entries.push({
|
||||
@ -633,8 +633,7 @@ async function sendToServer(analysis, checkHaveibeenpwned, masterPassword) {
|
||||
});
|
||||
}
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
|
||||
|
@ -23,8 +23,8 @@ function createServerSecret() {
|
||||
return data.data;
|
||||
};
|
||||
|
||||
const onError = async function (error) {
|
||||
error = await error;
|
||||
const onError = function (error) {
|
||||
//pass
|
||||
console.log(error)
|
||||
return Promise.reject(error);
|
||||
};
|
||||
@ -39,7 +39,7 @@ function createServerSecret() {
|
||||
*
|
||||
* @returns {Promise} Returns a list of history items
|
||||
*/
|
||||
async function deleteServerSecret(password) {
|
||||
function deleteServerSecret(password) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
@ -48,17 +48,17 @@ async function deleteServerSecret(password) {
|
||||
const userPrivateKey = getStore().getState().user.userPrivateKey;
|
||||
const userSauce = getStore().getState().user.userSauce;
|
||||
|
||||
const privateKeyEnc = await cryptoLibrary.encryptSecret(userPrivateKey, password, userSauce);
|
||||
const secretKeyEnc = await cryptoLibrary.encryptSecret(userSecretKey, password, userSauce);
|
||||
const authkey = await cryptoLibrary.generateAuthkey(username, password);
|
||||
const privateKeyEnc = cryptoLibrary.encryptSecret(userPrivateKey, password, userSauce);
|
||||
const secretKeyEnc = cryptoLibrary.encryptSecret(userSecretKey, password, userSauce);
|
||||
const authkey = cryptoLibrary.generateAuthkey(username, password);
|
||||
|
||||
const onSuccess = function (content) {
|
||||
action().setServerSecretExists(false);
|
||||
return content.data;
|
||||
};
|
||||
|
||||
const onError = async function (error) {
|
||||
error = await error;
|
||||
const onError = function (error) {
|
||||
//pass
|
||||
console.log(error)
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
@ -29,9 +29,9 @@ function readShare(shareId, secretKey) {
|
||||
// pass
|
||||
};
|
||||
|
||||
const onSuccess = async function (content) {
|
||||
const onSuccess = function (content) {
|
||||
return {
|
||||
data: JSON.parse(await cryptoLibrary.decryptData(content.data.data, content.data.data_nonce, secretKey)),
|
||||
data: JSON.parse(cryptoLibrary.decryptData(content.data.data, content.data.data_nonce, secretKey)),
|
||||
rights: content.data.rights,
|
||||
};
|
||||
};
|
||||
@ -52,13 +52,13 @@ function readShares() {
|
||||
// pass
|
||||
};
|
||||
|
||||
const onSuccess = async function (content) {
|
||||
const onSuccess = function (content) {
|
||||
for (let i = content.data.shares.length - 1; i >= 0; i--) {
|
||||
if (
|
||||
content.data.shares[i].share_right_title !== "" &&
|
||||
content.data.shares[i].share_right_create_user_public_key
|
||||
) {
|
||||
content.data.shares[i].share_right_title = await cryptoLibrary.decryptPrivateKey(
|
||||
content.data.shares[i].share_right_title = cryptoLibrary.decryptPrivateKey(
|
||||
content.data.shares[i].share_right_title,
|
||||
content.data.shares[i].share_right_title_nonce,
|
||||
content.data.shares[i].share_right_create_user_public_key
|
||||
@ -69,7 +69,7 @@ function readShares() {
|
||||
content.data.shares[i].share_right_type !== "" &&
|
||||
content.data.shares[i].share_right_create_user_public_key
|
||||
) {
|
||||
content.data.shares[i].share_right_type = await cryptoLibrary.decryptPrivateKey(
|
||||
content.data.shares[i].share_right_type = cryptoLibrary.decryptPrivateKey(
|
||||
content.data.shares[i].share_right_type,
|
||||
content.data.shares[i].share_right_type_nonce,
|
||||
content.data.shares[i].share_right_create_user_public_key
|
||||
@ -92,7 +92,7 @@ function readShares() {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the status of the update
|
||||
*/
|
||||
async function writeShare(shareId, content, secretKey) {
|
||||
function writeShare(shareId, content, secretKey) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
@ -109,7 +109,7 @@ async function writeShare(shareId, content, secretKey) {
|
||||
|
||||
const jsonContent = JSON.stringify(duplicate);
|
||||
|
||||
const encryptedData = await cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
const encryptedData = cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
return apiClient.writeShare(token, sessionSecretKey, shareId, encryptedData.text, encryptedData.nonce);
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ async function writeShare(shareId, content, secretKey) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the status and the new share id
|
||||
*/
|
||||
async function createShare(content, parentShareId, parentDatastoreId, linkId, onOpenRequest, onClosedRequest) {
|
||||
function createShare(content, parentShareId, parentDatastoreId, linkId, onOpenRequest, onClosedRequest) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
@ -145,8 +145,8 @@ async function createShare(content, parentShareId, parentDatastoreId, linkId, on
|
||||
|
||||
const jsonContent = JSON.stringify(filteredContent);
|
||||
|
||||
const encryptedData = await cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
const encryptedKey = await cryptoLibrary.encryptSecretKey(secretKey);
|
||||
const encryptedData = cryptoLibrary.encryptData(jsonContent, secretKey);
|
||||
const encryptedKey = cryptoLibrary.encryptSecretKey(secretKey);
|
||||
|
||||
const onError = function (result) {
|
||||
// pass
|
||||
@ -172,7 +172,7 @@ async function createShare(content, parentShareId, parentDatastoreId, linkId, on
|
||||
shareLinkService.moveShareLink(child_shares[i]["share"]["id"], content.data.share_id, undefined);
|
||||
}
|
||||
|
||||
return {share_id: content.data.share_id, secret_key: secretKey};
|
||||
return { share_id: content.data.share_id, secret_key: secretKey };
|
||||
};
|
||||
|
||||
return apiClient
|
||||
@ -249,28 +249,27 @@ function readShareRightsOverview() {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the new share right id
|
||||
*/
|
||||
async function createShareRight(title, type, shareId, userId, groupId, publicKey, secretKey, key, read, write, grant) {
|
||||
function createShareRight(title, type, shareId, userId, groupId, publicKey, secretKey, key, read, write, grant) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
let encrypted_key, encrypted_title, encrypted_type;
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result);
|
||||
};
|
||||
|
||||
const onSuccess = function (content) {
|
||||
return {share_right_id: content.data.share_right_id};
|
||||
return { share_right_id: content.data.share_right_id };
|
||||
};
|
||||
|
||||
if (typeof publicKey !== "undefined") {
|
||||
encrypted_key = await cryptoLibrary.encryptPrivateKey(key, publicKey);
|
||||
encrypted_title = await cryptoLibrary.encryptPrivateKey(title, publicKey);
|
||||
encrypted_type = await cryptoLibrary.encryptPrivateKey(type, publicKey);
|
||||
encrypted_key = cryptoLibrary.encryptPrivateKey(key, publicKey);
|
||||
encrypted_title = cryptoLibrary.encryptPrivateKey(title, publicKey);
|
||||
encrypted_type = cryptoLibrary.encryptPrivateKey(type, publicKey);
|
||||
} else {
|
||||
encrypted_key = await cryptoLibrary.encryptData(key, secretKey);
|
||||
encrypted_title = await cryptoLibrary.encryptData(title, secretKey);
|
||||
encrypted_type = await cryptoLibrary.encryptData(type, secretKey);
|
||||
encrypted_key = cryptoLibrary.encryptData(key, secretKey);
|
||||
encrypted_title = cryptoLibrary.encryptData(title, secretKey);
|
||||
encrypted_type = cryptoLibrary.encryptData(type, secretKey);
|
||||
}
|
||||
|
||||
return apiClient
|
||||
@ -309,8 +308,7 @@ function updateShareRight(shareId, userId, groupId, read, write, grant) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
// pass
|
||||
return Promise.reject(result.data);
|
||||
};
|
||||
@ -357,12 +355,12 @@ function deleteShareRight(userShareRightId, groupShareRightId) {
|
||||
*
|
||||
* @returns {object} The decrypted share
|
||||
*/
|
||||
async function decryptShare(encryptedShare, secretKey) {
|
||||
function decryptShare(encryptedShare, secretKey) {
|
||||
let share = {};
|
||||
|
||||
if (typeof encryptedShare.share_data !== "undefined") {
|
||||
share = JSON.parse(
|
||||
await cryptoLibrary.decryptData(encryptedShare.share_data, encryptedShare.share_data_nonce, secretKey)
|
||||
cryptoLibrary.decryptData(encryptedShare.share_data, encryptedShare.share_data_nonce, secretKey)
|
||||
);
|
||||
}
|
||||
|
||||
@ -382,21 +380,21 @@ async function decryptShare(encryptedShare, secretKey) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the share content
|
||||
*/
|
||||
async function acceptShareRight(shareRightId, text, nonce, publicKey) {
|
||||
function acceptShareRight(shareRightId, text, nonce, publicKey) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const secret_key = await cryptoLibrary.decryptPrivateKey(text, nonce, publicKey);
|
||||
const secret_key = cryptoLibrary.decryptPrivateKey(text, nonce, publicKey);
|
||||
|
||||
const onError = function (result) {
|
||||
// pass
|
||||
};
|
||||
|
||||
const onSuccess = async function (content) {
|
||||
const onSuccess = function (content) {
|
||||
const decrypted_share = decryptShare(content.data, secret_key);
|
||||
|
||||
if (typeof decrypted_share.type === "undefined" && typeof content.data.share_type !== "undefined") {
|
||||
const type = await cryptoLibrary.decryptPrivateKey(
|
||||
const type = cryptoLibrary.decryptPrivateKey(
|
||||
content.data.share_type,
|
||||
content.data.share_type_nonce,
|
||||
publicKey
|
||||
@ -410,7 +408,7 @@ async function acceptShareRight(shareRightId, text, nonce, publicKey) {
|
||||
return decrypted_share;
|
||||
};
|
||||
|
||||
const encrypted_key = await cryptoLibrary.encryptSecretKey(secret_key);
|
||||
const encrypted_key = cryptoLibrary.encryptSecretKey(secret_key);
|
||||
|
||||
return apiClient
|
||||
.acceptShareRight(token, sessionSecretKey, shareRightId, encrypted_key.text, encrypted_key.nonce)
|
||||
|
@ -88,17 +88,16 @@ function initiateLogin(username, server, rememberMe, trustDevice, twoFaRedirect)
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async function samlLogin(samlTokenId) {
|
||||
function samlLogin(samlTokenId) {
|
||||
const serverPublicKey = getStore().getState().server.publicKey;
|
||||
const sessionKeys = await cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const sessionKeys = cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const password = '';
|
||||
|
||||
const onSuccess = function (response) {
|
||||
return handleLoginResponse(response, password, sessionKeys, serverPublicKey, 'SAML');
|
||||
};
|
||||
|
||||
const onError = async function (response) {
|
||||
response = await response;
|
||||
const onError = function (response) {
|
||||
return Promise.reject(response.data.non_field_errors);
|
||||
};
|
||||
|
||||
@ -112,7 +111,7 @@ async function samlLogin(samlTokenId) {
|
||||
login_info = JSON.stringify(login_info);
|
||||
|
||||
// encrypt the login infos
|
||||
const loginInfoEnc = await cryptoLibrary.encryptDataPublicKey(login_info, serverPublicKey, sessionKeys.private_key);
|
||||
const loginInfoEnc = cryptoLibrary.encryptDataPublicKey(login_info, serverPublicKey, sessionKeys.private_key);
|
||||
|
||||
let sessionDuration = 24 * 60 * 60;
|
||||
const trustDevice = getStore().getState().user.trustDevice;
|
||||
@ -169,17 +168,16 @@ function getSamlRedirectUrl(providerId) {
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async function oidcLogin(oidcTokenId) {
|
||||
function oidcLogin(oidcTokenId) {
|
||||
const serverPublicKey = getStore().getState().server.publicKey;
|
||||
const sessionKeys = await cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const sessionKeys = cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const password = '';
|
||||
|
||||
const onSuccess = function (response) {
|
||||
return handleLoginResponse(response, password, sessionKeys, serverPublicKey, 'OIDC');
|
||||
};
|
||||
|
||||
const onError = async function (response) {
|
||||
response = await response;
|
||||
const onError = function (response) {
|
||||
return Promise.reject(response.data.non_field_errors);
|
||||
};
|
||||
|
||||
@ -193,7 +191,7 @@ async function oidcLogin(oidcTokenId) {
|
||||
login_info = JSON.stringify(login_info);
|
||||
|
||||
// encrypt the login infos
|
||||
const loginInfoEnc = await cryptoLibrary.encryptDataPublicKey(login_info, serverPublicKey, sessionKeys.private_key);
|
||||
const loginInfoEnc = cryptoLibrary.encryptDataPublicKey(login_info, serverPublicKey, sessionKeys.private_key);
|
||||
|
||||
let sessionDuration = 24 * 60 * 60;
|
||||
const trustDevice = getStore().getState().user.trustDevice;
|
||||
@ -253,8 +251,7 @@ function gaVerify(gaToken) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
return apiClient.gaVerify(token, gaToken, sessionSecretKey).catch(async (response) => {
|
||||
response = await response;
|
||||
return apiClient.gaVerify(token, gaToken, sessionSecretKey).catch((response) => {
|
||||
if (response.hasOwnProperty("data") && response.data.hasOwnProperty("non_field_errors")) {
|
||||
return Promise.reject(response.data.non_field_errors);
|
||||
} else {
|
||||
@ -274,8 +271,7 @@ function duoVerify(duoToken) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
return apiClient.duoVerify(token, duoToken, sessionSecretKey).catch(async (response) => {
|
||||
response = await response;
|
||||
return apiClient.duoVerify(token, duoToken, sessionSecretKey).catch((response) => {
|
||||
if (response.hasOwnProperty("data") && response.data.hasOwnProperty("non_field_errors")) {
|
||||
return Promise.reject(response.data.non_field_errors);
|
||||
} else {
|
||||
@ -295,8 +291,7 @@ function yubikeyOtpVerify(yubikeyOtp) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
return apiClient.yubikeyOtpVerify(token, yubikeyOtp, sessionSecretKey).catch(async (response) => {
|
||||
response = await response;
|
||||
return apiClient.yubikeyOtpVerify(token, yubikeyOtp, sessionSecretKey).catch((response) => {
|
||||
if (response.hasOwnProperty("data") && response.data.hasOwnProperty("non_field_errors")) {
|
||||
return Promise.reject(response.data.non_field_errors);
|
||||
} else {
|
||||
@ -315,9 +310,9 @@ function activateToken() {
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
const userSauce = getStore().getState().user.userSauce;
|
||||
|
||||
const onSuccess = async function (activationData) {
|
||||
const onSuccess = function (activationData) {
|
||||
// decrypt user secret key
|
||||
const userSecretKey = await cryptoLibrary.decryptSecret(
|
||||
const userSecretKey = cryptoLibrary.decryptSecret(
|
||||
activationData.data.user.secret_key,
|
||||
activationData.data.user.secret_key_nonce,
|
||||
sessionPassword,
|
||||
@ -358,9 +353,9 @@ function activateToken() {
|
||||
*
|
||||
* @returns {Array} The list of required multifactor challenges to solve
|
||||
*/
|
||||
async function handleLoginResponse(response, password, sessionKeys, serverPublicKey, defaultAuthentication) {
|
||||
function handleLoginResponse(response, password, sessionKeys, serverPublicKey, defaultAuthentication) {
|
||||
let decrypted_response_data = JSON.parse(
|
||||
await cryptoLibrary.decryptDataPublicKey(
|
||||
cryptoLibrary.decryptDataPublicKey(
|
||||
response.data.login_info,
|
||||
response.data.login_info_nonce,
|
||||
serverPublicKey,
|
||||
@ -371,7 +366,7 @@ async function handleLoginResponse(response, password, sessionKeys, serverPublic
|
||||
|
||||
if (decrypted_response_data.hasOwnProperty('data') && decrypted_response_data.hasOwnProperty('data_nonce')) {
|
||||
decrypted_response_data = JSON.parse(
|
||||
await cryptoLibrary.decryptDataPublicKey(
|
||||
cryptoLibrary.decryptDataPublicKey(
|
||||
decrypted_response_data.data,
|
||||
decrypted_response_data.data_nonce,
|
||||
server_session_public_key,
|
||||
@ -384,7 +379,7 @@ async function handleLoginResponse(response, password, sessionKeys, serverPublic
|
||||
// decrypt the session key
|
||||
let sessionSecretKey = decrypted_response_data.session_secret_key;
|
||||
if (decrypted_response_data.hasOwnProperty('session_secret_key_nonce')) {
|
||||
sessionSecretKey = await cryptoLibrary.decryptDataPublicKey(
|
||||
sessionSecretKey = cryptoLibrary.decryptDataPublicKey(
|
||||
decrypted_response_data.session_secret_key,
|
||||
decrypted_response_data.session_secret_key_nonce,
|
||||
decrypted_response_data.session_public_key,
|
||||
@ -398,7 +393,7 @@ async function handleLoginResponse(response, password, sessionKeys, serverPublic
|
||||
try {
|
||||
// decrypt user private key which may fail if the user server's password isn't correct and the user
|
||||
// needs to enter one
|
||||
user_private_key = await cryptoLibrary.decryptSecret(
|
||||
user_private_key = cryptoLibrary.decryptSecret(
|
||||
decrypted_response_data.user.private_key,
|
||||
decrypted_response_data.user.private_key_nonce,
|
||||
sessionPassword,
|
||||
@ -411,7 +406,7 @@ async function handleLoginResponse(response, password, sessionKeys, serverPublic
|
||||
}
|
||||
|
||||
// decrypt the user_validator
|
||||
const user_validator = await cryptoLibrary.decryptDataPublicKey(
|
||||
const user_validator = cryptoLibrary.decryptDataPublicKey(
|
||||
decrypted_response_data.user_validator,
|
||||
decrypted_response_data.user_validator_nonce,
|
||||
server_session_public_key,
|
||||
@ -419,7 +414,7 @@ async function handleLoginResponse(response, password, sessionKeys, serverPublic
|
||||
);
|
||||
|
||||
// encrypt the validator as verification
|
||||
verification = await cryptoLibrary.encryptData(user_validator, sessionSecretKey);
|
||||
verification = cryptoLibrary.encryptData(user_validator, sessionSecretKey);
|
||||
|
||||
action().setUserUsername(decrypted_response_data.user.username);
|
||||
|
||||
@ -434,8 +429,7 @@ async function handleLoginResponse(response, password, sessionKeys, serverPublic
|
||||
|
||||
if (decrypted_response_data.user.hasOwnProperty('language') && i18n.options.supportedLngs.includes(decrypted_response_data.user.language)) {
|
||||
i18n.changeLanguage(decrypted_response_data.user.language).then(() => {
|
||||
browserClientService.emitSec("language-changed", decrypted_response_data.user.language, function () {
|
||||
});
|
||||
browserClientService.emitSec("language-changed", decrypted_response_data.user.language, function () {});
|
||||
});
|
||||
}
|
||||
|
||||
@ -448,20 +442,19 @@ async function handleLoginResponse(response, password, sessionKeys, serverPublic
|
||||
return decrypted_response_data;
|
||||
}
|
||||
|
||||
async function login(password, serverInfo, sendPlain) {
|
||||
function login(password, serverInfo, sendPlain) {
|
||||
const username = getStore().getState().user.username;
|
||||
const trustDevice = getStore().getState().user.trustDevice;
|
||||
const serverPublicKey = serverInfo.info.public_key;
|
||||
|
||||
const authkey = await cryptoLibrary.generateAuthkey(username, password);
|
||||
const sessionKeys = await cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const authkey = cryptoLibrary.generateAuthkey(username, password);
|
||||
const sessionKeys = cryptoLibrary.generatePublicPrivateKeypair();
|
||||
|
||||
const onSuccess = function (response) {
|
||||
return handleLoginResponse(response, password, sessionKeys, serverPublicKey, 'AUTHKEY');
|
||||
};
|
||||
|
||||
const onError = async function (response) {
|
||||
response = await response;
|
||||
const onError = function (response) {
|
||||
if (response.hasOwnProperty("data") && response.data.hasOwnProperty("non_field_errors")) {
|
||||
return Promise.reject(response.data.non_field_errors);
|
||||
} else {
|
||||
@ -484,7 +477,7 @@ async function login(password, serverInfo, sendPlain) {
|
||||
loginInfo = JSON.stringify(loginInfo);
|
||||
|
||||
// encrypt the login infos
|
||||
const loginInfoEnc = await cryptoLibrary.encryptDataPublicKey(loginInfo, serverPublicKey, sessionKeys.private_key);
|
||||
const loginInfoEnc = cryptoLibrary.encryptDataPublicKey(loginInfo, serverPublicKey, sessionKeys.private_key);
|
||||
|
||||
let sessionDuration = 24 * 60 * 60;
|
||||
if (trustDevice) {
|
||||
@ -568,18 +561,17 @@ function isLoggedIn() {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the result
|
||||
*/
|
||||
async function deleteAccount(password) {
|
||||
function deleteAccount(password) {
|
||||
const token = getStore().getState().user.token;
|
||||
const sessionSecretKey = getStore().getState().user.sessionSecretKey;
|
||||
|
||||
const authkey = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, password);
|
||||
const authkey = cryptoLibrary.generateAuthkey(getStore().getState().user.username, password);
|
||||
|
||||
const onSuccess = function () {
|
||||
logout();
|
||||
};
|
||||
|
||||
const onError = async function (data) {
|
||||
data = await data;
|
||||
const onError = function (data) {
|
||||
return Promise.reject(data.data);
|
||||
};
|
||||
|
||||
@ -633,7 +625,7 @@ function updateUser(email, authkey, authkeyOld, privateKey, privateKeyNonce, sec
|
||||
*/
|
||||
function saveNewPassword(newPassword, newPasswordRepeat, oldPassword) {
|
||||
return host.info().then(
|
||||
async function (info) {
|
||||
function (info) {
|
||||
let authkeyOld,
|
||||
newAuthkey,
|
||||
userPrivateKey,
|
||||
@ -650,27 +642,27 @@ function saveNewPassword(newPassword, newPasswordRepeat, oldPassword) {
|
||||
info.data["decoded_info"]["compliance_min_master_password_complexity"]
|
||||
);
|
||||
if (test_error) {
|
||||
return Promise.reject({errors: [test_error]});
|
||||
return Promise.reject({ errors: [test_error] });
|
||||
}
|
||||
|
||||
if (oldPassword === null || oldPassword.length === 0) {
|
||||
return Promise.reject({errors: ["OLD_PASSWORD_REQUIRED"]});
|
||||
return Promise.reject({ errors: ["OLD_PASSWORD_REQUIRED"] });
|
||||
}
|
||||
|
||||
authkeyOld = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, oldPassword);
|
||||
newAuthkey = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, newPassword);
|
||||
authkeyOld = cryptoLibrary.generateAuthkey(getStore().getState().user.username, oldPassword);
|
||||
newAuthkey = cryptoLibrary.generateAuthkey(getStore().getState().user.username, newPassword);
|
||||
userPrivateKey = getStore().getState().user.userPrivateKey;
|
||||
userSecretKey = getStore().getState().user.userSecretKey;
|
||||
userSauce = getStore().getState().user.userSauce;
|
||||
|
||||
privKeyEnc = await cryptoLibrary.encryptSecret(userPrivateKey, newPassword, userSauce);
|
||||
secretKeyEnc = await cryptoLibrary.encryptSecret(userSecretKey, newPassword, userSauce);
|
||||
privKeyEnc = cryptoLibrary.encryptSecret(userPrivateKey, newPassword, userSauce);
|
||||
secretKeyEnc = cryptoLibrary.encryptSecret(userSecretKey, newPassword, userSauce);
|
||||
|
||||
onSuccess = function (data) {
|
||||
return {msgs: ["SAVE_SUCCESS"]};
|
||||
return { msgs: ["SAVE_SUCCESS"] };
|
||||
};
|
||||
onError = function () {
|
||||
return Promise.reject({errors: ["OLD_PASSWORD_INCORRECT"]});
|
||||
return Promise.reject({ errors: ["OLD_PASSWORD_INCORRECT"] });
|
||||
};
|
||||
|
||||
return updateUser(
|
||||
@ -700,19 +692,19 @@ function saveNewPassword(newPassword, newPasswordRepeat, oldPassword) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the result
|
||||
*/
|
||||
async function saveNewEmail(newEmail, verificationPassword) {
|
||||
function saveNewEmail(newEmail, verificationPassword) {
|
||||
if (verificationPassword === null || verificationPassword.length === 0) {
|
||||
return Promise.reject({errors: ["OLD_PASSWORD_REQUIRED"]});
|
||||
return Promise.reject({ errors: ["OLD_PASSWORD_REQUIRED"] });
|
||||
}
|
||||
|
||||
const authkeyOld = await cryptoLibrary.generateAuthkey(getStore().getState().user.username, verificationPassword);
|
||||
const authkeyOld = cryptoLibrary.generateAuthkey(getStore().getState().user.username, verificationPassword);
|
||||
|
||||
const onSuccess = function (data) {
|
||||
action().setEmail(newEmail);
|
||||
return {msgs: ["SAVE_SUCCESS"]};
|
||||
return { msgs: ["SAVE_SUCCESS"] };
|
||||
};
|
||||
const onError = function () {
|
||||
return Promise.reject({errors: ["OLD_PASSWORD_INCORRECT"]});
|
||||
return Promise.reject({ errors: ["OLD_PASSWORD_INCORRECT"] });
|
||||
};
|
||||
return updateUser(
|
||||
newEmail,
|
||||
@ -723,7 +715,7 @@ async function saveNewEmail(newEmail, verificationPassword) {
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
).then(onSuccess, onError);
|
||||
).then(onSuccess, onError);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -737,8 +729,7 @@ function saveNewLanguage(language) {
|
||||
const onSuccess = function (data) {
|
||||
return { msgs: ["SAVE_SUCCESS"] };
|
||||
};
|
||||
const onError = async function (result) {
|
||||
result = await result;
|
||||
const onError = function (result) {
|
||||
return Promise.reject(result);
|
||||
};
|
||||
return updateUser(
|
||||
@ -762,13 +753,13 @@ function saveNewLanguage(language) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the recovery_enable status
|
||||
*/
|
||||
async function recoveryEnable(username, recoveryCode, server) {
|
||||
function recoveryEnable(username, recoveryCode, server) {
|
||||
action().setUserUsername(username);
|
||||
action().setServerUrl(server);
|
||||
|
||||
const onSuccess = async function (data) {
|
||||
const onSuccess = function (data) {
|
||||
const recovery_data = JSON.parse(
|
||||
await cryptoLibrary.decryptSecret(
|
||||
cryptoLibrary.decryptSecret(
|
||||
data.data.recovery_data,
|
||||
data.data.recovery_data_nonce,
|
||||
recoveryCode,
|
||||
@ -788,7 +779,7 @@ async function recoveryEnable(username, recoveryCode, server) {
|
||||
verifier_time_valid: data.data.verifier_time_valid,
|
||||
};
|
||||
};
|
||||
const recoveryAuthkey = await cryptoLibrary.generateAuthkey(username, recoveryCode);
|
||||
const recoveryAuthkey = cryptoLibrary.generateAuthkey(username, recoveryCode);
|
||||
|
||||
return apiClient.enableRecoverycode(username, recoveryAuthkey).then(onSuccess);
|
||||
}
|
||||
@ -806,19 +797,19 @@ async function recoveryEnable(username, recoveryCode, server) {
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the set_password status
|
||||
*/
|
||||
async function setPassword(username, recoveryCode, password, userPrivateKey, userSecretKey, userSauce, verifierPublicKey) {
|
||||
const privKeyEnc = await cryptoLibrary.encryptSecret(userPrivateKey, password, userSauce);
|
||||
const secretKeyEnc = await cryptoLibrary.encryptSecret(userSecretKey, password, userSauce);
|
||||
function setPassword(username, recoveryCode, password, userPrivateKey, userSecretKey, userSauce, verifierPublicKey) {
|
||||
const privKeyEnc = cryptoLibrary.encryptSecret(userPrivateKey, password, userSauce);
|
||||
const secretKeyEnc = cryptoLibrary.encryptSecret(userSecretKey, password, userSauce);
|
||||
|
||||
const updateRequest = JSON.stringify({
|
||||
authkey: await cryptoLibrary.generateAuthkey(username, password),
|
||||
authkey: cryptoLibrary.generateAuthkey(username, password),
|
||||
private_key: privKeyEnc.text,
|
||||
private_key_nonce: privKeyEnc.nonce,
|
||||
secret_key: secretKeyEnc.text,
|
||||
secret_key_nonce: secretKeyEnc.nonce,
|
||||
});
|
||||
|
||||
const updateRequestEnc = await cryptoLibrary.encryptDataPublicKey(updateRequest, verifierPublicKey, userPrivateKey);
|
||||
const updateRequestEnc = cryptoLibrary.encryptDataPublicKey(updateRequest, verifierPublicKey, userPrivateKey);
|
||||
|
||||
const onSuccess = function (data) {
|
||||
return data;
|
||||
@ -828,7 +819,7 @@ async function setPassword(username, recoveryCode, password, userPrivateKey, use
|
||||
return data;
|
||||
};
|
||||
|
||||
const recovery_authkey = await cryptoLibrary.generateAuthkey(username, recoveryCode);
|
||||
const recovery_authkey = cryptoLibrary.generateAuthkey(username, recoveryCode);
|
||||
|
||||
return apiClient
|
||||
.setPassword(username, recovery_authkey, updateRequestEnc.text, updateRequestEnc.nonce)
|
||||
@ -846,7 +837,7 @@ async function setPassword(username, recoveryCode, password, userPrivateKey, use
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the emergency code activation status
|
||||
*/
|
||||
async function armEmergencyCode(username, emergencyCode, server, serverInfo, verifyKey) {
|
||||
function armEmergencyCode(username, emergencyCode, server, serverInfo, verifyKey) {
|
||||
action().setUserUsername(username);
|
||||
action().setServerUrl(server);
|
||||
|
||||
@ -854,15 +845,15 @@ async function armEmergencyCode(username, emergencyCode, server, serverInfo, ver
|
||||
let policies;
|
||||
let userSecretKey;
|
||||
|
||||
const emergencyAuthkey = await cryptoLibrary.generateAuthkey(username, emergencyCode);
|
||||
const emergencyAuthkey = cryptoLibrary.generateAuthkey(username, emergencyCode);
|
||||
|
||||
const onSuccess = async function (data) {
|
||||
const onSuccess = function (data) {
|
||||
if (data.data.status === "started" || data.data.status === "waiting") {
|
||||
return data.data;
|
||||
}
|
||||
|
||||
const emergency_data = JSON.parse(
|
||||
await cryptoLibrary.decryptSecret(
|
||||
cryptoLibrary.decryptSecret(
|
||||
data.data.emergency_data,
|
||||
data.data.emergency_data_nonce,
|
||||
emergencyCode,
|
||||
@ -875,7 +866,7 @@ async function armEmergencyCode(username, emergencyCode, server, serverInfo, ver
|
||||
policies = data.data.policies;
|
||||
const authentication = data.data.authentication ? data.data.authentication : 'AUTHKEY';
|
||||
|
||||
const sessionKey = await cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const sessionKey = cryptoLibrary.generatePublicPrivateKeypair();
|
||||
|
||||
const loginInfo = JSON.stringify({
|
||||
device_time: new Date().toISOString(),
|
||||
@ -884,15 +875,15 @@ async function armEmergencyCode(username, emergencyCode, server, serverInfo, ver
|
||||
session_public_key: sessionKey.public_key,
|
||||
});
|
||||
|
||||
const update_request_enc = await cryptoLibrary.encryptDataPublicKey(
|
||||
const update_request_enc = cryptoLibrary.encryptDataPublicKey(
|
||||
loginInfo,
|
||||
data.data.verifier_public_key,
|
||||
emergency_data.user_private_key
|
||||
);
|
||||
|
||||
const onSuccess = async function (data) {
|
||||
const onSuccess = function (data) {
|
||||
const loginInfo = JSON.parse(
|
||||
await cryptoLibrary.decryptDataPublicKey(
|
||||
cryptoLibrary.decryptDataPublicKey(
|
||||
data.data.login_info,
|
||||
data.data.login_info_nonce,
|
||||
serverInfo["public_key"],
|
||||
@ -1053,7 +1044,7 @@ function deleteSession(sessionId) {
|
||||
*/
|
||||
function register(email, username, password, server) {
|
||||
|
||||
const onSuccess = async function (base_url) {
|
||||
const onSuccess = function(base_url){
|
||||
|
||||
//managerBase.delete_local_data();
|
||||
|
||||
@ -1061,11 +1052,11 @@ function register(email, username, password, server) {
|
||||
// storage.upsert('config', {key: 'user_username', value: username});
|
||||
// storage.upsert('config', {key: 'server', value: server});
|
||||
|
||||
const pair = await cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const pair = cryptoLibrary.generatePublicPrivateKeypair();
|
||||
const userSauce = cryptoLibrary.generateUserSauce();
|
||||
|
||||
const privateKeyEncrypted = await cryptoLibrary.encryptSecret(pair.private_key, password, userSauce);
|
||||
const secretKeyEncrypted = await cryptoLibrary
|
||||
const privateKeyEncrypted = cryptoLibrary.encryptSecret(pair.private_key, password, userSauce);
|
||||
const secretKeyEncrypted = cryptoLibrary
|
||||
.encryptSecret(cryptoLibrary.generateSecretKey(), password, userSauce);
|
||||
|
||||
const onSuccess = function () {
|
||||
@ -1073,23 +1064,23 @@ function register(email, username, password, server) {
|
||||
storage.save();
|
||||
|
||||
return {
|
||||
response: "success"
|
||||
response:"success"
|
||||
};
|
||||
};
|
||||
|
||||
const onError = function (response) {
|
||||
const onError = function(response){
|
||||
|
||||
// storage.remove('config', storage.find_key('config', 'user_email'));
|
||||
// storage.remove('config', storage.find_key('config', 'server'));
|
||||
storage.save();
|
||||
|
||||
return {
|
||||
response: "error",
|
||||
response:"error",
|
||||
error_data: response.data
|
||||
};
|
||||
};
|
||||
|
||||
return apiClient.register(email, username, await cryptoLibrary.generateAuthkey(username, password), pair.public_key,
|
||||
return apiClient.register(email, username, cryptoLibrary.generateAuthkey(username, password), pair.public_key,
|
||||
privateKeyEncrypted.text, privateKeyEncrypted.nonce, secretKeyEncrypted.text, secretKeyEncrypted.nonce, userSauce,
|
||||
base_url)
|
||||
.then(onSuccess, onError);
|
||||
|
@ -92,8 +92,7 @@ function deleteWebauthn(webauthnId) {
|
||||
const onSuccess = function () {
|
||||
return true;
|
||||
};
|
||||
const onError = async function (data) {
|
||||
data = await data;
|
||||
const onError = function (data) {
|
||||
return Promise.reject(data.data);
|
||||
};
|
||||
return apiClientService.deleteWebauthn(token, sessionSecretKey, webauthnId).then(onSuccess, onError);
|
||||
@ -111,8 +110,7 @@ function verifyWebauthnInit() {
|
||||
const onSuccess = function (request) {
|
||||
return request.data;
|
||||
};
|
||||
const onError = async function (request) {
|
||||
request = await request;
|
||||
const onError = function (request) {
|
||||
return Promise.reject(request.data);
|
||||
};
|
||||
return apiClientService.webauthnVerifyInit(token, sessionSecretKey, getOrigin()).then(onSuccess, onError);
|
||||
@ -132,8 +130,7 @@ function verifyWebauthn(credential) {
|
||||
const onSuccess = function (request) {
|
||||
return request.data;
|
||||
};
|
||||
const onError = async function (request) {
|
||||
request = await request;
|
||||
const onError = function (request) {
|
||||
return Promise.reject(request.data);
|
||||
};
|
||||
return apiClientService.webauthnVerify(token, sessionSecretKey, credential).then(onSuccess, onError);
|
||||
|
@ -23,8 +23,7 @@ function createYubikeyOtp(title, otp) {
|
||||
id: request.data["id"],
|
||||
};
|
||||
};
|
||||
const onError = async function (error) {
|
||||
error = await error;
|
||||
const onError = function (error) {
|
||||
return Promise.reject(error.data);
|
||||
};
|
||||
return apiClient.createYubikeyOtp(token, sessionSecretKey, title, otp).then(onSuccess, onError);
|
||||
@ -82,8 +81,7 @@ function deleteYubikeyOtp(yubikeyOtpId) {
|
||||
const onSuccess = function () {
|
||||
return true;
|
||||
};
|
||||
const onError = async function (data) {
|
||||
data = await data;
|
||||
const onError = function (data) {
|
||||
return Promise.reject(data.data);
|
||||
};
|
||||
return apiClient.deleteYubikeyOtp(token, sessionSecretKey, yubikeyOtpId).then(onSuccess, onError);
|
||||
|
@ -25,7 +25,6 @@ const AccountChangeEmailView = (props) => {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [errors, setErrors] = useState([]);
|
||||
const [msgs, setMsgs] = useState([]);
|
||||
|
||||
const save = (event) => {
|
||||
setErrors([]);
|
||||
@ -33,7 +32,6 @@ const AccountChangeEmailView = (props) => {
|
||||
function (data) {
|
||||
setEmail("");
|
||||
setPassword("");
|
||||
setMsgs(["SAVE_SUCCESS"])
|
||||
},
|
||||
function (data) {
|
||||
setPassword("");
|
||||
@ -87,7 +85,6 @@ const AccountChangeEmailView = (props) => {
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<GridContainerErrors errors={msgs} setErrors={setMsgs} severity={"info"} />
|
||||
<GridContainerErrors errors={errors} setErrors={setErrors} />
|
||||
<Grid container style={{ marginBottom: "8px" }}>
|
||||
<Grid item xs={12} sm={12} md={12}>
|
||||
|
@ -25,7 +25,6 @@ const AccountChangePasswordView = (props) => {
|
||||
const [oldPassword, setOldPassword] = useState("");
|
||||
const [passwordRepeat, setPasswordRepeat] = useState("");
|
||||
const [errors, setErrors] = useState([]);
|
||||
const [msgs, setMsgs] = useState([]);
|
||||
|
||||
const save = (event) => {
|
||||
setErrors([]);
|
||||
@ -34,7 +33,6 @@ const AccountChangePasswordView = (props) => {
|
||||
setPassword("");
|
||||
setOldPassword("");
|
||||
setPasswordRepeat("");
|
||||
setMsgs(["SAVE_SUCCESS"])
|
||||
},
|
||||
function (data) {
|
||||
setOldPassword("");
|
||||
@ -108,7 +106,6 @@ const AccountChangePasswordView = (props) => {
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<GridContainerErrors errors={msgs} setErrors={setMsgs} severity={"info"} />
|
||||
<GridContainerErrors errors={errors} setErrors={setErrors} />
|
||||
<Grid container style={{ marginBottom: "8px" }}>
|
||||
<Grid item xs={12} sm={12} md={12}>
|
||||
|
@ -1,7 +1,5 @@
|
||||
import React, { useState, useRef } from 'react';
|
||||
import {useTranslation} from "react-i18next";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
Badge,
|
||||
@ -73,7 +71,6 @@ function ProfilePicture() {
|
||||
const fileInputRef = useRef(null); // Reference to the file input
|
||||
const [errors, setErrors] = useState([]);
|
||||
const [serverSupportsAvatars, setServerSupportsAvatars] = useState(true);
|
||||
const userEmail = useSelector((state) => state.user.userEmail);
|
||||
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -263,7 +260,7 @@ function ProfilePicture() {
|
||||
label={t("E_MAIL")}
|
||||
name="userEmail"
|
||||
autoComplete="off"
|
||||
value={userEmail}
|
||||
value={getStore().getState().user.userEmail}
|
||||
readOnly
|
||||
InputProps={{
|
||||
classes: {
|
||||
|
@ -22,7 +22,6 @@ import action from "../../actions/bound-action-creators";
|
||||
import GridContainerErrors from "../../components/grid-container-errors";
|
||||
import FooterLinks from "../../components/footer-links";
|
||||
import datastoreSettingService from "../../services/datastore-setting";
|
||||
import TextWithLineBreaks from "../../components/text-with-linebreaks";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
textField: {
|
||||
@ -104,7 +103,6 @@ const LoginViewForm = (props) => {
|
||||
const [ldapEnabled, setLdapEnabled] = useState(false);
|
||||
const [samlEnabled, setSamlEnabled] = useState(false);
|
||||
const [oidcEnabled, setOidcEnabled] = useState(false);
|
||||
const [loginInfoText, setLoginInfoText] = useState("");
|
||||
const [serverCheck, setServerCheck] = useState({});
|
||||
const [samlProvider, setSamlProvider] = useState([]);
|
||||
const [oidcProvider, setOidcProvider] = useState([]);
|
||||
@ -149,8 +147,8 @@ const LoginViewForm = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
const decryptData = async () => {
|
||||
const loginDetails = await decryptLoginDataFunction(password);
|
||||
const decryptData = () => {
|
||||
const loginDetails = decryptLoginDataFunction(password);
|
||||
if (loginDetails.hasOwnProperty("required_multifactors")) {
|
||||
const requiredMultifactors = loginDetails["required_multifactors"];
|
||||
action().setHasTwoFactor(requiredMultifactors.length > 0);
|
||||
@ -506,7 +504,6 @@ const LoginViewForm = (props) => {
|
||||
const ldapEnabled = configJson["authentication_methods"].indexOf("LDAP") !== -1;
|
||||
const samlEnabled = configJson["authentication_methods"].indexOf("SAML") !== -1;
|
||||
const oidcEnabled = configJson["authentication_methods"].indexOf("OIDC") !== -1;
|
||||
const loginInfoText = configJson["login_info_text"];
|
||||
|
||||
setPlainPasswordWhitelistedServerUrls(plainPasswordWhitelistedServerUrls);
|
||||
setAllowLostPassword(allowLostPassword);
|
||||
@ -526,7 +523,6 @@ const LoginViewForm = (props) => {
|
||||
setLdapEnabled(ldapEnabled);
|
||||
setSamlEnabled(samlEnabled);
|
||||
setOidcEnabled(oidcEnabled);
|
||||
setLoginInfoText(loginInfoText);
|
||||
if (!authkeyEnabled && !ldapEnabled && configJson.hasOwnProperty('auto_login') && configJson['auto_login']) {
|
||||
setTimeout(function () {
|
||||
if (!props.samlTokenId && !props.oidcTokenId) {
|
||||
@ -1507,18 +1503,6 @@ const LoginViewForm = (props) => {
|
||||
|
||||
<FooterLinks />
|
||||
</div>
|
||||
{loginInfoText && (
|
||||
<MuiAlert
|
||||
icon={false}
|
||||
severity="info"
|
||||
style={{
|
||||
marginTop: "5px",
|
||||
fontSize: "10px",
|
||||
}}
|
||||
>
|
||||
<TextWithLineBreaks text={loginInfoText} />
|
||||
</MuiAlert>
|
||||
)}
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
@ -17,6 +17,7 @@ module.exports = () => {
|
||||
const config= merge(webclient, developConfig)
|
||||
config['entry'] = {
|
||||
'js/bundle.min.js': './src/js/index.js',
|
||||
'js/crypto-worker.js': './src/js/crypto-worker.js',
|
||||
}
|
||||
return config
|
||||
};
|
||||
|
@ -36,13 +36,13 @@ module.exports = () => {
|
||||
// should be last so all files are cached
|
||||
new InjectManifest({
|
||||
swSrc: './src/webclient/service-worker.js',
|
||||
swDest: './service-worker.js',
|
||||
swDest: './webclient/service-worker.js',
|
||||
exclude: [
|
||||
/authenticate\.html/
|
||||
],
|
||||
modifyURLPrefix: {
|
||||
'/': './',
|
||||
'././': './',
|
||||
'webclient/': './',
|
||||
'./webclient/': './',
|
||||
},
|
||||
compileSrc: true,
|
||||
maximumFileSizeToCacheInBytes: 30000000,
|
||||
|
@ -21,14 +21,9 @@ module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
entry: {
|
||||
'js/bundle.min.js': './src/js/index.js',
|
||||
'js/background-chrome.js': './src/js/background-chrome.js',
|
||||
},
|
||||
output: {
|
||||
filename: '[name]',
|
||||
path: path.resolve(__dirname, 'build', 'chrome', 'data'),
|
||||
chunkFilename: 'js/[name].js',
|
||||
publicPath: '/data/',
|
||||
'chrome/data/js/bundle.min.js': './src/js/index.js',
|
||||
'chrome/data/js/crypto-worker.js': './src/js/crypto-worker.js',
|
||||
'chrome/data/js/background-chrome.js': './src/js/background-chrome.js',
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
@ -51,7 +46,7 @@ module.exports = merge(common, {
|
||||
|
||||
new JsonPostProcessPlugin({
|
||||
matchers: [{
|
||||
matcher: /^\.\.\/manifest.json$/,
|
||||
matcher: /^chrome\/manifest.json$/,
|
||||
action: (currentJsonContent) => ({ ...currentJsonContent, version: version })
|
||||
}]
|
||||
}),
|
||||
|
@ -20,13 +20,8 @@ module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
entry: {
|
||||
'js/bundle.min.js': './src/js/index.js',
|
||||
},
|
||||
output: {
|
||||
filename: '[name]',
|
||||
path: path.resolve(__dirname, 'build', 'electron'),
|
||||
chunkFilename: 'js/[name].js',
|
||||
publicPath: '/',
|
||||
'electron/js/bundle.min.js': './src/js/index.js',
|
||||
'electron/js/crypto-worker.js': './src/js/crypto-worker.js',
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
|
@ -21,13 +21,8 @@ module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
entry: {
|
||||
'js/bundle.min.js': './src/js/index.js',
|
||||
},
|
||||
output: {
|
||||
filename: '[name]',
|
||||
path: path.resolve(__dirname, 'build', 'firefox', 'data'),
|
||||
chunkFilename: 'js/[name].js',
|
||||
publicPath: '/data/',
|
||||
'firefox/data/js/bundle.min.js': './src/js/index.js',
|
||||
'firefox/data/js/crypto-worker.js': './src/js/crypto-worker.js',
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
@ -50,7 +45,7 @@ module.exports = merge(common, {
|
||||
|
||||
new JsonPostProcessPlugin({
|
||||
matchers: [{
|
||||
matcher: /^\.\.\/manifest.json$/,
|
||||
matcher: /^firefox\/manifest.json$/,
|
||||
action: (currentJsonContent) => ({ ...currentJsonContent, version: version })
|
||||
}]
|
||||
}),
|
||||
|
@ -8,18 +8,9 @@ const path = require('path');
|
||||
module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
// entry: {
|
||||
// 'webclient/js/bundle.min.js': './src/js/index.js',
|
||||
// },
|
||||
//
|
||||
entry: {
|
||||
'js/bundle.min.js': './src/js/index.js',
|
||||
},
|
||||
output: {
|
||||
filename: '[name]',
|
||||
path: path.resolve(__dirname, 'build', 'webclient'),
|
||||
chunkFilename: 'js/[name].js',
|
||||
publicPath: '/',
|
||||
'webclient/js/bundle.min.js': './src/js/index.js',
|
||||
'webclient/js/crypto-worker.js': './src/js/crypto-worker.js',
|
||||
},
|
||||
devServer: {
|
||||
static: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user