diff --git a/javascript/src/CryptoData.js b/javascript/src/CryptoData.js index 9261a2d92c9f12334b2388a9224f90b2e2653b19..9e784357dfda4fafc2013c6617cb1d439d884269 100644 --- a/javascript/src/CryptoData.js +++ b/javascript/src/CryptoData.js @@ -1,58 +1,58 @@ function CryptoData() {} CryptoData.prototype.set = function(obj) { - for(var member in obj) { - this[member] = JSON.parse(JSON.stringify(obj[member])) + for (var member in obj) { + this[member] = JSON.parse(JSON.stringify(obj[member])); } }; CryptoData.prototype.serialize = function() { - return JSON.stringify(this) + return JSON.stringify(this); }; CryptoData.prototype.deserialize = function(serialized) { var obj = JSON.parse(serialized); - this.set(obj) + this.set(obj); }; CryptoData.prototype.setPublicKey = function(publicKey) { - this["publicKey"] = publicKey + this["publicKey"] = publicKey; }; CryptoData.prototype.getPublicKey = function() { - return this["publicKey"] + return this["publicKey"]; }; CryptoData.prototype.setPrivateKey = function(privateKey) { - this["privateKey"] = privateKey + this["privateKey"] = privateKey; }; CryptoData.prototype.getPrivateKey = function() { - return this["privateKey"] + return this["privateKey"]; }; CryptoData.prototype.setx509Certificate = function(x509Certificate) { - this["x509Certificate"] = x509Certificate + this["x509Certificate"] = x509Certificate; }; CryptoData.prototype.getx509Certificate = function() { - return this["x509Certificate"] + return this["x509Certificate"]; }; CryptoData.prototype.setKeyUUID = function(keyUUID) { - this["keyUUID"] = keyUUID + this["keyUUID"] = keyUUID; }; CryptoData.prototype.getKeyUUID = function() { - return this["keyUUID"] + return this["keyUUID"]; }; CryptoData.prototype.setChain = function(chain) { - this["chain"] = chain + this["chain"] = chain; }; CryptoData.prototype.getChain = function() { - return this["chain"] + return this["chain"]; }; -export default CryptoData; \ No newline at end of file +export default CryptoData; diff --git a/javascript/src/constants/authentication.js b/javascript/src/constants/authentication.js index e00c27fa1dd9acd046795061a019a054a7e56af8..aff4861f605a9cdc8c1882f67019d61c8e5a7836 100644 --- a/javascript/src/constants/authentication.js +++ b/javascript/src/constants/authentication.js @@ -1,5 +1,5 @@ export const LOGIN_MODES = { - SMS: 'sms', - PREVIOUSLY_ADDED_DEVICE: 'previousaddeddevice', - NEW_DEVICE: 'newdevice' + SMS: "sms", + PREVIOUSLY_ADDED_DEVICE: "previousaddeddevice", + NEW_DEVICE: "newdevice" }; diff --git a/javascript/src/helpers/mailparser.js b/javascript/src/helpers/mailparser.js index 2e9142e21e517709e4da7d32eb35321374853ab3..9bd873ff9ba1d20c06bd890a4bd525e640c378ec 100644 --- a/javascript/src/helpers/mailparser.js +++ b/javascript/src/helpers/mailparser.js @@ -347,5 +347,5 @@ export function getAttachment(mime, part) { base64 = window.btoa(body); } - return { contentType, base64 } + return { contentType, base64 }; } diff --git a/javascript/src/iframe/collaboraapi-iframe.js b/javascript/src/iframe/collaboraapi-iframe.js index 6dde19dfdb308c4f1291e49b3bd0780d9d906127..af29c89d5a4959592d50e3058bd7974e7f1192b7 100644 --- a/javascript/src/iframe/collaboraapi-iframe.js +++ b/javascript/src/iframe/collaboraapi-iframe.js @@ -1,30 +1,32 @@ -const axios = require('axios'); +const axios = require("axios"); function CollaboraAPI() {} -CollaboraAPI.prototype.discovery = function () { +CollaboraAPI.prototype.discovery = function() { const requestConfig = { url: `${window.COLLABORA_URL}hosting/discovery`, - method: 'GET' + method: "GET" }; return axios(requestConfig).then(response => { - const apps = response.request.responseXML.querySelectorAll("net-zone[name='external-http'] app"); + const apps = response.request.responseXML.querySelectorAll( + "net-zone[name='external-http'] app" + ); const results = []; for (let i = 0; i < apps.length; i++) { const app = apps[i]; - const action = app.querySelector('action'); - const mimeType = app.getAttribute('name'); - const ext = action.getAttribute('ext'); - const urlsrc = action.getAttribute('urlsrc'); + const action = app.querySelector("action"); + const mimeType = app.getAttribute("name"); + const ext = action.getAttribute("ext"); + const urlsrc = action.getAttribute("urlsrc"); results.push({ mimeType, ext, urlsrc }); } - return results + return results; }); }; diff --git a/javascript/src/iframe/viamapi-iframe.js b/javascript/src/iframe/viamapi-iframe.js index 2c7de95a5eb47082ff97299dc5b245132174fb73..29df152526c2953c234e36f5180f6961cf6f793d 100644 --- a/javascript/src/iframe/viamapi-iframe.js +++ b/javascript/src/iframe/viamapi-iframe.js @@ -1,36 +1,38 @@ -import { parseSMIME } from '../utilities/emailUtilities'; +import { parseSMIME } from "../utilities/emailUtilities"; -const QRCode = require('qrcode'); -const Penpal = require('penpal').default; +const QRCode = require("qrcode"); +const Penpal = require("penpal").default; import { createDeviceHash, destroyIdentityFromLocalStorage, encodeResponse, - listIdentitiesFromLocalStorage, makeid -} from '../utilities/appUtility'; -import {LOGIN_MODES} from '../constants/authentication'; + listIdentitiesFromLocalStorage, + makeid +} from "../utilities/appUtility"; +import { LOGIN_MODES } from "../constants/authentication"; import { createOneTimePassportCertificate, createPassportCertificate, decryptMessage, - encryptMessage, signEmail -} from '../utilities/signingUtilities'; -import CryptoData from '../CryptoData'; -import Identity from '../Identity'; -import {STATUS_DEVICE_REVOKED} from '../constants/statuses'; - -const penpalMethods = require('../../temp/penpal-methods').default; -const WopiAPI = require('./wopiapi-iframe'); -const CollaboraAPI = require('./collaboraapi-iframe'); -const ViamAPI = require('../../temp/viamapi'); + encryptMessage, + signEmail +} from "../utilities/signingUtilities"; +import CryptoData from "../CryptoData"; +import Identity from "../Identity"; +import { STATUS_DEVICE_REVOKED } from "../constants/statuses"; + +const penpalMethods = require("../../temp/penpal-methods").default; +const WopiAPI = require("./wopiapi-iframe"); +const CollaboraAPI = require("./collaboraapi-iframe"); +const ViamAPI = require("../../temp/viamapi"); var identityColors = ["#994392", "#cb0767", "#e51d31", "#ec671b", "#fab610"]; function getNextColor() { var colorIndex = localStorage.getItem("colorIndex"); if (colorIndex == null || colorIndex === "") { - colorIndex = 0 + colorIndex = 0; } var color = identityColors[colorIndex]; @@ -41,27 +43,31 @@ function getNextColor() { localStorage.setItem("colorIndex", colorIndex); - return color + return color; } function setKeyForUUID(uuid, key) { var storedIdentityForUuid = localStorage.getItem("keyperuuid/" + uuid); - if(storedIdentityForUuid !== key && storedIdentityForUuid != null && storedIdentityForUuid !== "") { - destroyIdentityFromLocalStorage(storedIdentityForUuid) + if ( + storedIdentityForUuid !== key && + storedIdentityForUuid != null && + storedIdentityForUuid !== "" + ) { + destroyIdentityFromLocalStorage(storedIdentityForUuid); } - localStorage.setItem("keyperuuid/" + uuid, key) + localStorage.setItem("keyperuuid/" + uuid, key); } function getColorForIdentity(key) { var storedColor = localStorage.getItem("colors/" + key); - if(storedColor == null || storedColor === "") { + if (storedColor == null || storedColor === "") { storedColor = getNextColor(); - localStorage.setItem("colors/" + key, storedColor) + localStorage.setItem("colors/" + key, storedColor); } - return storedColor + return storedColor; } function setIdentityInLocalStorage(identityToStore, extendKey = true) { @@ -69,49 +75,60 @@ function setIdentityInLocalStorage(identityToStore, extendKey = true) { const serializedIdentity = JSON.stringify(identityToStore); const key = identityToStore.authentication.publicKey; - if(pinCode == null || pinCode === "") { - pinCode = getPincode(key) + if (pinCode == null || pinCode === "") { + pinCode = getPincode(key); } - if(pinCode == null || pinCode === "") { + if (pinCode == null || pinCode === "") { return null; } - return encryptMessage(serializedIdentity, pinCode, "identity").then((encryptedIdentity) => { - var success = true; - if(extendKey === true) { - success = extendPinCodeTtl(key, pinCode) - } - if (success === true) { - localStorage.setItem(key, encryptedIdentity); - let serializedIdentitiesList = localStorage.getItem("identities"); - let identities = JSON.parse(serializedIdentitiesList); - identities[key] = true; + return encryptMessage(serializedIdentity, pinCode, "identity").then( + encryptedIdentity => { + var success = true; + if (extendKey === true) { + success = extendPinCodeTtl(key, pinCode); + } + if (success === true) { + localStorage.setItem(key, encryptedIdentity); + let serializedIdentitiesList = localStorage.getItem("identities"); + let identities = JSON.parse(serializedIdentitiesList); + identities[key] = true; - localStorage.setItem("identities", JSON.stringify(identities)) - } else { - console.log("Can not extend pincode ttl"); + localStorage.setItem("identities", JSON.stringify(identities)); + } else { + console.log("Can not extend pincode ttl"); + } } - }); + ); } function getProfileData(identity) { return new Penpal.Promise(executeResultUpper => { - executeRestfulFunction("private", viamApi, - viamApi.identityGetIdentityProfileData, null).then(executeResult => { - if(executeResult.code === "200") { + executeRestfulFunction( + "private", + viamApi, + viamApi.identityGetIdentityProfileData, + null + ).then(executeResult => { + if (executeResult.code === "200") { var listItem = {}; - listItem.identityColor = getColorForIdentity(identity.authentication.publicKey); + listItem.identityColor = getColorForIdentity( + identity.authentication.publicKey + ); listItem.initials = executeResult.data.initials; - if(listItem.initials === null || listItem.initials === "") { + if (listItem.initials === null || listItem.initials === "") { listItem.initials = "JD"; } - localStorage.setItem("profiles/" + identity.authentication.publicKey, JSON.stringify(listItem)); - executeResultUpper(listItem) + localStorage.setItem( + "profiles/" + identity.authentication.publicKey, + JSON.stringify(listItem) + ); + executeResultUpper(listItem); } else { - executeResultUpper({}) + executeResultUpper({}); } }); }); @@ -141,13 +158,13 @@ async function getIdentityFromLocalStorage(key, pinCode, extendTtl = true) { } function extendPinCodeTtl(key, pinCode) { - if(pinCode == null || pinCode === "") { + if (pinCode == null || pinCode === "") { var now = new Date(); var nowMillis = now.getTime(); var ttl = window.sessionStorage.getItem("pincodettls/" + key); if (ttl == null || ttl === "" || nowMillis >= parseInt(ttl)) { clearPinCodeTtl(key); - return false + return false; } else { var ttl = now.getTime() + 4 * 60 * 60 * 1000; window.sessionStorage.setItem("pincodettls/" + key, ttl); @@ -166,7 +183,7 @@ window.extendPinCodeTtl = extendPinCodeTtl; function clearPinCodeTtl(key) { window.sessionStorage.removeItem("pincodettls/" + key); - window.sessionStorage.removeItem("pincodes/" + key) + window.sessionStorage.removeItem("pincodes/" + key); } function getPincode(key) { @@ -174,11 +191,11 @@ function getPincode(key) { var nowMillis = now.getTime(); var ttl = window.sessionStorage.getItem("pincodettls/" + key); if (ttl == null || ttl === "") { - return null + return null; } else { - if(nowMillis >= parseInt(ttl)) { + if (nowMillis >= parseInt(ttl)) { clearPinCodeTtl(key); - return null + return null; } else { return window.sessionStorage.getItem("pincodes/" + key); } @@ -187,11 +204,11 @@ function getPincode(key) { function createEvent(actionId, type, payloads) { return { - "actionID": actionId, - "type": type, - "stamp": new Date().getTime(), - "payloads" : payloads - } + actionID: actionId, + type: type, + stamp: new Date().getTime(), + payloads: payloads + }; } const destroyAuthentication = () => { @@ -247,13 +264,18 @@ const handleIdentityLogin = (identity, uuid, token) => { }; async function executeRestfulFunction(type, that, fn, config, ...args) { - const { currentlyAuthenticatedIdentity, viamApi, currentlyLoadedIdentity } = window; + const { + currentlyAuthenticatedIdentity, + viamApi, + currentlyLoadedIdentity + } = window; const response = await fn.apply(that, [config, ...args]); const identity = currentlyAuthenticatedIdentity || currentlyLoadedIdentity; const { code, status } = response.data; - const deviceRevoked = type === "private" && code === "401" && status === STATUS_DEVICE_REVOKED; + const deviceRevoked = + type === "private" && code === "401" && status === STATUS_DEVICE_REVOKED; if (deviceRevoked) { destroyIdentity(); @@ -263,10 +285,17 @@ async function executeRestfulFunction(type, that, fn, config, ...args) { return response.data; } - const badSession = type === "private" && identity && code === "400" && status === "Bad session"; + const badSession = + type === "private" && + identity && + code === "400" && + status === "Bad session"; if (!badSession) return response.data; - const loginResponse = await viamApi.identityLogin(null, "previousaddeddevice"); + const loginResponse = await viamApi.identityLogin( + null, + "previousaddeddevice" + ); if (loginResponse.data.code !== "200") return loginResponse.data; const uuid = loginResponse.data.data["Uuid"]; @@ -280,76 +309,86 @@ window.executeRestfulFunction = executeRestfulFunction; function loadIdentityInternal(identityKey, pinCode) { return new Penpal.Promise(result => { - getIdentityFromLocalStorage(identityKey, pinCode).then(async (loadedIdentity) => { - if (loadedIdentity == null) { - result({ - "data": "", - "code": "400", - "status": "Please restore or authorize your account via another device." - }); - } - localStorage.removeItem("attempt"); - - window.loadedIdentities[identityKey] = loadedIdentity; - window.currentlyLoadedIdentity = loadedIdentity; - - if (identityKey === localStorage.getItem("authenticatedIdentity")) { - window.currentlyAuthenticatedIdentity = loadedIdentity; - const uuid = localStorage.getItem("uuid"); - const token = localStorage.getItem("token"); - const deviceHash = await createDeviceHash(identityKey); - window.viamApi.setIdentity(identityKey); - window.viamApi.setDeviceHash(deviceHash); - window.viamApi.setSessionData(uuid, token); - } + getIdentityFromLocalStorage(identityKey, pinCode) + .then(async loadedIdentity => { + if (loadedIdentity == null) { + result({ + data: "", + code: "400", + status: + "Please restore or authorize your account via another device." + }); + } + localStorage.removeItem("attempt"); + + window.loadedIdentities[identityKey] = loadedIdentity; + window.currentlyLoadedIdentity = loadedIdentity; + + if (identityKey === localStorage.getItem("authenticatedIdentity")) { + window.currentlyAuthenticatedIdentity = loadedIdentity; + const uuid = localStorage.getItem("uuid"); + const token = localStorage.getItem("token"); + const deviceHash = await createDeviceHash(identityKey); + window.viamApi.setIdentity(identityKey); + window.viamApi.setDeviceHash(deviceHash); + window.viamApi.setSessionData(uuid, token); + } - window.viamAnonymousApi.setIdentity(window.currentlyLoadedIdentity.authentication.publicKey); + window.viamAnonymousApi.setIdentity( + window.currentlyLoadedIdentity.authentication.publicKey + ); - const { publicKey, x509Certificate } = loadedIdentity.authentication; + const { publicKey, x509Certificate } = loadedIdentity.authentication; - result({ - "data": { - authentication: { - publicKey, - x509Certificate - } - }, - "code": "200", - "status": "Identity loaded" - }); - }).catch((e) => { - result({ - "data": "", - "code": "400", - "status": "" + e + result({ + data: { + authentication: { + publicKey, + x509Certificate + } + }, + code: "200", + status: "Identity loaded" + }); + }) + .catch(e => { + result({ + data: "", + code: "400", + status: "" + e + }); }); - }); }); } function getCertificateForPassport(passportUUID, internal) { - return new Penpal.Promise(certificateResult => { if (window.currentlyAuthenticatedIdentity === null) { - return {"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - } + return { data: "", code: "400", status: "Identity not authenticated" }; } const passportIdentity = window.currentlyAuthenticatedIdentity; var passport = passportIdentity.getPassport(passportUUID); - if(passport === undefined || passport === null) { - createPassportCertificate(passportUUID).then(function(keys){ + if (passport === undefined || passport === null) { + createPassportCertificate(passportUUID).then(function(keys) { var cryptoData = new CryptoData(); cryptoData.setPublicKey(keys["publicKeyPEM"]); cryptoData.setPrivateKey(keys["privateKeyPEM"]); var certificate = keys["certificatePEM"]; //download("passportCertificateBeforeSigning.crt", "text/plain", certificate) //cryptoData.setx509Certificate(keys["certificate"]) - executeRestfulFunction("private", viamApi, viamApi.signSignCertificate, null, btoa(certificate), passportUUID).then(executeResult => { - if(executeResult.code === "200") { - var signedCertificate = atob(executeResult.data["SignedCertificate"]); + executeRestfulFunction( + "private", + viamApi, + viamApi.signSignCertificate, + null, + btoa(certificate), + passportUUID + ).then(executeResult => { + if (executeResult.code === "200") { + var signedCertificate = atob( + executeResult.data["SignedCertificate"] + ); //download("passportCertificateAfterSigning.crt", "text/plain", signedCertificate) var keyUUID = executeResult.data["CertificateUUID"]; var encodedChain = executeResult.data["Chain"]; @@ -357,8 +396,8 @@ function getCertificateForPassport(passportUUID, internal) { var chain = []; - for(var i = 0; i < encodedChain.length; i++) { - chain.push(atob(encodedChain[i])) + for (var i = 0; i < encodedChain.length; i++) { + chain.push(atob(encodedChain[i])); } cryptoData.setx509Certificate(signedCertificate); @@ -368,28 +407,32 @@ function getCertificateForPassport(passportUUID, internal) { passportIdentity.setPassport(passportUUID, cryptoData); getProfileData(passportIdentity).then(executeResult1 => { - setIdentityInLocalStorage(passportIdentity).then(() => { - window.currentlyAuthenticatedIdentity = passportIdentity; - window.lastTimeGetProfile = 0; - window.currentlyLoadedIdentity = passportIdentity; - const copyOfCryptoData = JSON.parse(JSON.stringify(cryptoData)); - - if (internal === false) { - copyOfCryptoData["privateKey"] = ""; - } - - certificateResult({ - "data": copyOfCryptoData, - "code": "200", - "status": "Certificate got" + setIdentityInLocalStorage(passportIdentity) + .then(() => { + window.currentlyAuthenticatedIdentity = passportIdentity; + window.lastTimeGetProfile = 0; + window.currentlyLoadedIdentity = passportIdentity; + const copyOfCryptoData = JSON.parse( + JSON.stringify(cryptoData) + ); + + if (internal === false) { + copyOfCryptoData["privateKey"] = ""; + } + + certificateResult({ + data: copyOfCryptoData, + code: "200", + status: "Certificate got" + }); + }) + .catch(e => { + certificateResult({ + data: "", + code: "400", + status: "Can not store certificate " + e + }); }); - }).catch((e) => { - certificateResult({ - "data": "", - "code": "400", - "status": "Can not store certificate " + e - }); - }); }); } else { certificateResult(executeResult); @@ -399,13 +442,14 @@ function getCertificateForPassport(passportUUID, internal) { } else { var copyOfCryptoData = JSON.parse(JSON.stringify(passport)); - if(internal === false) { - copyOfCryptoData["privateKey"] = "" + if (internal === false) { + copyOfCryptoData["privateKey"] = ""; } - certificateResult({"data" : copyOfCryptoData, - "code" : "200", - "status" : "Certificate got" + certificateResult({ + data: copyOfCryptoData, + code: "200", + status: "Certificate got" }); } }); @@ -427,17 +471,24 @@ const connection = Penpal.connectToParent({ if (!collaboraUrl) { collaboraUrl = window.location.origin; - console.warn(`Collabora host URL not specified. Fall back to ${collaboraUrl}`); // eslint-disable-line no-console + console.warn( + `Collabora host URL not specified. Fall back to ${collaboraUrl}` + ); // eslint-disable-line no-console } - window.API_HOST = apiUrl.charAt(apiUrl.length - 1) === "/" ? apiUrl : apiUrl + "/"; - window.WOPI_URL = wopiUrl.charAt(wopiUrl.length - 1) === "/" ? wopiUrl : wopiUrl + "/"; - window.COLLABORA_URL = collaboraUrl.charAt(collaboraUrl.length - 1) === "/" ? collaboraUrl : collaboraUrl + "/"; + window.API_HOST = + apiUrl.charAt(apiUrl.length - 1) === "/" ? apiUrl : apiUrl + "/"; + window.WOPI_URL = + wopiUrl.charAt(wopiUrl.length - 1) === "/" ? wopiUrl : wopiUrl + "/"; + window.COLLABORA_URL = + collaboraUrl.charAt(collaboraUrl.length - 1) === "/" + ? collaboraUrl + : collaboraUrl + "/"; }, ...penpalMethods, createIdentity(pinCode) { return new Penpal.Promise(result => { - createPassportCertificate(makeid()).then(function(keys){ + createPassportCertificate(makeid()).then(function(keys) { var newIdentity = new Identity(); var cryptoData = new CryptoData(); cryptoData.setPublicKey(keys["publicKeyPEM"]); @@ -447,29 +498,31 @@ const connection = Penpal.connectToParent({ newIdentity.setPinCode(pinCode); window.currentlyLoadedIdentity = newIdentity; - window.loadedIdentities[newIdentity.authentication.publicKey] = newIdentity; + window.loadedIdentities[ + newIdentity.authentication.publicKey + ] = newIdentity; extendPinCodeTtl(newIdentity.authentication.publicKey, pinCode); - window.viamAnonymousApi.setIdentity(newIdentity.authentication.publicKey); + window.viamAnonymousApi.setIdentity( + newIdentity.authentication.publicKey + ); - result({"data" : newIdentity, - "code" : "200", - "status" : "Identity created" - }) + result({ + data: newIdentity, + code: "200", + status: "Identity created" + }); }); - }) + }); }, listIdentities() { return new Penpal.Promise(result => { var identities = listIdentitiesFromLocalStorage(); - result({"data" : identities, - "code" : "200", - "status" : "Identities listed" - }) + result({ data: identities, code: "200", status: "Identities listed" }); }); }, loadIdentity(identityKey, pinCode) { - return loadIdentityInternal(identityKey, pinCode) + return loadIdentityInternal(identityKey, pinCode); }, checkIdentityPinCode: async (key, pinCode) => { try { @@ -486,7 +539,11 @@ const connection = Penpal.connectToParent({ }, changeIdentityPinCode: async (key, oldPinCode, newPinCode) => { try { - const identity = await getIdentityFromLocalStorage(key, oldPinCode, false); + const identity = await getIdentityFromLocalStorage( + key, + oldPinCode, + false + ); if (identity) { identity.pinCode = newPinCode; @@ -502,17 +559,17 @@ const connection = Penpal.connectToParent({ }, getIdentityProfile(identityKey) { return new Penpal.Promise(result => { - const serializedProfile = localStorage.getItem("profiles/" + identityKey); + const serializedProfile = localStorage.getItem( + "profiles/" + identityKey + ); if (serializedProfile === null || serializedProfile === "") { - result({"data" : "", - "code" : "400", - "status" : "Profile is empty" - }); + result({ data: "", code: "400", status: "Profile is empty" }); } else { - result({"data" : JSON.parse(serializedProfile), - "code" : "200", - "status" : "Identities cleared" - }) + result({ + data: JSON.parse(serializedProfile), + code: "200", + status: "Identities cleared" + }); } }); }, @@ -530,7 +587,13 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity(identity.authentication.publicKey); - executeRestfulFunction("public", viamApi, viamApi.identityConfirmIdentificator, null, confirmationCodeArg).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.identityConfirmIdentificator, + null, + confirmationCodeArg + ).then(executeResult => { result(executeResult); }); }); @@ -539,7 +602,13 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity(identity.authentication.publicKey); - executeRestfulFunction("public", viamApi, viamApi.identityGetIdentificatorByRegisterToken, null, tokenArg).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.identityGetIdentificatorByRegisterToken, + null, + tokenArg + ).then(executeResult => { result(executeResult); }); }); @@ -548,16 +617,38 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity(identity.authentication.publicKey); - executeRestfulFunction("public", viamApi, viamApi.identitySubmitIdentificator, null, identificatorArg, registerToken).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.identitySubmitIdentificator, + null, + identificatorArg, + registerToken + ).then(executeResult => { result(executeResult); }); }); }, - submitRegisterClaims(identity, givennameArg,familynameArg,emailArg,phonenumberArg) { + submitRegisterClaims( + identity, + givennameArg, + familynameArg, + emailArg, + phonenumberArg + ) { return new Penpal.Promise(result => { viamApi.setIdentity(identity.authentication.publicKey); - executeRestfulFunction("public", viamApi, viamApi.identitySubmitRegisterClaims, null, givennameArg,familynameArg,emailArg,phonenumberArg).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.identitySubmitRegisterClaims, + null, + givennameArg, + familynameArg, + emailArg, + phonenumberArg + ).then(executeResult => { result(executeResult); }); }); @@ -566,23 +657,29 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity(registerIdentity.authentication.publicKey); - executeRestfulFunction("public", viamApi, viamApi.identityAgreeOnRegistration, null).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.identityAgreeOnRegistration, + null + ).then(executeResult => { let sequence = Promise.resolve(); if (executeResult.code === "200") { sequence = sequence.then(() => { - setIdentityInLocalStorage(registerIdentity) - } - ) + setIdentityInLocalStorage(registerIdentity); + }); } - sequence.then(() => { - result(executeResult); - }).catch((e) => { - result({ - "data": "", - "code": "400", - "status": "Can not store identity: " + e + sequence + .then(() => { + result(executeResult); }) - }) + .catch(e => { + result({ + data: "", + code: "400", + status: "Can not store identity: " + e + }); + }); }); }); }, @@ -590,7 +687,13 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity(identity.authentication.publicKey); - executeRestfulFunction("public", viamApi, viamApi.identityResendConfirmationCode, null, identificatorArg).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.identityResendConfirmationCode, + null, + identificatorArg + ).then(executeResult => { result(executeResult); }); }); @@ -604,26 +707,31 @@ const connection = Penpal.connectToParent({ }; } - const deviceHash = await createDeviceHash(loginIdentity.authentication.publicKey); + const deviceHash = await createDeviceHash( + loginIdentity.authentication.publicKey + ); window.viamApi.setSessionData("", ""); window.viamApi.setDeviceHash(deviceHash); window.viamApi.setIdentity(loginIdentity.authentication.publicKey); - const identityLoginResponse = - await executeRestfulFunction( - "public", - window.viamApi, - window.viamApi.identityLogin, - null, - mode, requestCode, - requestActionID - ); + const identityLoginResponse = await executeRestfulFunction( + "public", + window.viamApi, + window.viamApi.identityLogin, + null, + mode, + requestCode, + requestActionID + ); const { code, data } = identityLoginResponse; const responseToClient = Object.assign({}, identityLoginResponse); if (code === "200") { - if (mode === LOGIN_MODES.SMS || mode === LOGIN_MODES.PREVIOUSLY_ADDED_DEVICE) { + if ( + mode === LOGIN_MODES.SMS || + mode === LOGIN_MODES.PREVIOUSLY_ADDED_DEVICE + ) { handleIdentityLogin(loginIdentity, data.Uuid, data.Session); await getProfileData(loginIdentity); @@ -631,7 +739,9 @@ const connection = Penpal.connectToParent({ await setIdentityInLocalStorage(loginIdentity); } } else if (mode === LOGIN_MODES.NEW_DEVICE) { - const dataUrl = await QRCode.toDataURL(`${data.ActionID},${data.QrCode}`); + const dataUrl = await QRCode.toDataURL( + `${data.ActionID},${data.QrCode}` + ); Object.assign(responseToClient.data, { image: dataUrl }); } } @@ -640,39 +750,49 @@ const connection = Penpal.connectToParent({ }, identityAddNewDevice() { return new Penpal.Promise(result => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if (authenticationPublicKey === null) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } if (window.loadedIdentities[authenticationPublicKey] === null) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } var success = extendPinCodeTtl(authenticationPublicKey); - if(success === false) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + if (success === false) { + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } - executeRestfulFunction("private", viamApi, viamApi.identityAddNewDevice, null).then(executeResult => { + executeRestfulFunction( + "private", + viamApi, + viamApi.identityAddNewDevice, + null + ).then(executeResult => { if (executeResult.code === "200") { var actionID = executeResult.data["ActionID"]; var QrCode = executeResult.data["QrCode"]; - QRCode.toDataURL(actionID + "," + QrCode, function (err, url) { + QRCode.toDataURL(actionID + "," + QrCode, function(err, url) { executeResult.data["image"] = url; result(executeResult); - }) + }); } else { result(executeResult); } @@ -681,38 +801,54 @@ const connection = Penpal.connectToParent({ }, identityDestroyKeysForDevice(authenticationPublicKeyArg) { return new Penpal.Promise(result => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if (authenticationPublicKey === null) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } if (window.loadedIdentities[authenticationPublicKey] === null) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } var success = extendPinCodeTtl(authenticationPublicKey); - if(success === false) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + if (success === false) { + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } - executeRestfulFunction("private", viamApi, viamApi.identityDestroyKeysForDevice, null, btoa(authenticationPublicKeyArg)).then(executeResult => { + executeRestfulFunction( + "private", + viamApi, + viamApi.identityDestroyKeysForDevice, + null, + btoa(authenticationPublicKeyArg) + ).then(executeResult => { result(executeResult); }); }); }, logout: async () => { try { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); - if (!authenticationPublicKey || !window.loadedIdentities[authenticationPublicKey]) { + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); + if ( + !authenticationPublicKey || + !window.loadedIdentities[authenticationPublicKey] + ) { return { data: "", code: "400", @@ -722,7 +858,7 @@ const connection = Penpal.connectToParent({ // Clone headers to be able destroy authentication first. // We need it because clients should be able reload page right after logout invocation and not wait until request completed - const headers = {...window.viamApi.getConfig().headers}; + const headers = { ...window.viamApi.getConfig().headers }; destroyAuthentication(); @@ -747,141 +883,149 @@ const connection = Penpal.connectToParent({ viamApi.setSessionData("", ""); viamApi.setIdentity(restoreAccessIdentity.authentication.publicKey); - executeRestfulFunction("public", viamApi, viamApi.identityRestoreAccess, null, identificator).then(executeResult => { - result(executeResult); + executeRestfulFunction( + "public", + viamApi, + viamApi.identityRestoreAccess, + null, + identificator + ).then(executeResult => { + result(executeResult); }); }); }, parseSMIME, getCurrentlyLoggedInUUID() { return new Penpal.Promise(result => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if (authenticationPublicKey === null) { - return {"data" : "", - "code" : "400", - "status" : "Identity not loaded" - } + return { data: "", code: "400", status: "Identity not loaded" }; } if (window.loadedIdentities[authenticationPublicKey] === null) { - return {"data" : "", - "code" : "400", - "status" : "Identity not loaded" - } + return { data: "", code: "400", status: "Identity not loaded" }; } var success = extendPinCodeTtl(authenticationPublicKey); - if(success === false) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + if (success === false) { + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } - if(localStorage.getItem("uuid") === null) { - result({"data" : "", - "code" : "400", - "status" : "Not logged in UUID" - }) + if (localStorage.getItem("uuid") === null) { + result({ data: "", code: "400", status: "Not logged in UUID" }); } - result({"data" : localStorage.getItem("uuid"), - "code" : "200", - "status" : "UUID loaded" - }) + result({ + data: localStorage.getItem("uuid"), + code: "200", + status: "UUID loaded" + }); }); }, getCertificateByPassport(passportUUID) { return new Penpal.Promise(result => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if (authenticationPublicKey === null) { - return {"data" : "", - "code" : "400", - "status" : "Identity not loaded" - } + return { data: "", code: "400", status: "Identity not loaded" }; } if (window.loadedIdentities[authenticationPublicKey] === null) { - return {"data" : "", - "code" : "400", - "status" : "Identity not loaded" - } + return { data: "", code: "400", status: "Identity not loaded" }; } var success = extendPinCodeTtl(authenticationPublicKey); - if(success === false) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + if (success === false) { + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } - getCertificateForPassport(passportUUID, false).then(certificateResult => { - result(certificateResult) - }) + getCertificateForPassport(passportUUID, false).then( + certificateResult => { + result(certificateResult); + } + ); }); }, getOneTimeCertificateByPassport(passportUUID, emailArg) { return new Penpal.Promise(result => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if (authenticationPublicKey === null) { - return {"data" : "", - "code" : "400", - "status" : "Identity not loaded" - } + return { data: "", code: "400", status: "Identity not loaded" }; } if (window.loadedIdentities[authenticationPublicKey] === null) { - return {"data" : "", - "code" : "400", - "status" : "Identity not loaded" - } + return { data: "", code: "400", status: "Identity not loaded" }; } var success = extendPinCodeTtl(authenticationPublicKey); - if(success === false) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + if (success === false) { + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } - getCertificateForPassport(passportUUID, true).then(certificateResult => { - if(certificateResult.code === "200") { - var passportCertificate = certificateResult.data["x509Certificate"]; - var passportPrivateKey = certificateResult.data["privateKey"]; - var passportChain = certificateResult.data["chain"]; - - createOneTimePassportCertificate(makeid() + "-" + passportUUID, emailArg, passportPrivateKey, passportCertificate).then(function(keys){ - var publicKeyOneTime = keys["publicKeyPEM"]; - var privateKeyOneTime = keys["privateKeyPEM"]; - var certificateOneTime = keys["certificatePEM"]; - passportChain.push(passportCertificate); - - var oneTimeCryptoData = new CryptoData(); - oneTimeCryptoData.setx509Certificate(certificateOneTime); - oneTimeCryptoData.setPrivateKey(privateKeyOneTime); - oneTimeCryptoData.setPublicKey(publicKeyOneTime); - oneTimeCryptoData.setChain(passportChain); - - result({"data" : oneTimeCryptoData, - "code" : "200", - "status" : "One time certificate generated" - }) - // Prints PEM formatted signed certificate - // -----BEGIN CERTIFICATE-----MIID....7Hyg==-----END CERTIFICATE----- - - }); - } else { - result({"data" : "", - "code" : "400", - "status" : "Can not generate one time certificate" - }) + getCertificateForPassport(passportUUID, true).then( + certificateResult => { + if (certificateResult.code === "200") { + var passportCertificate = + certificateResult.data["x509Certificate"]; + var passportPrivateKey = certificateResult.data["privateKey"]; + var passportChain = certificateResult.data["chain"]; + + createOneTimePassportCertificate( + makeid() + "-" + passportUUID, + emailArg, + passportPrivateKey, + passportCertificate + ).then(function(keys) { + var publicKeyOneTime = keys["publicKeyPEM"]; + var privateKeyOneTime = keys["privateKeyPEM"]; + var certificateOneTime = keys["certificatePEM"]; + passportChain.push(passportCertificate); + + var oneTimeCryptoData = new CryptoData(); + oneTimeCryptoData.setx509Certificate(certificateOneTime); + oneTimeCryptoData.setPrivateKey(privateKeyOneTime); + oneTimeCryptoData.setPublicKey(publicKeyOneTime); + oneTimeCryptoData.setChain(passportChain); + + result({ + data: oneTimeCryptoData, + code: "200", + status: "One time certificate generated" + }); + // Prints PEM formatted signed certificate + // -----BEGIN CERTIFICATE-----MIID....7Hyg==-----END CERTIFICATE----- + }); + } else { + result({ + data: "", + code: "400", + status: "Can not generate one time certificate" + }); + } } - }) + ); }); }, signEmail: async (passportUUID, emailArg, emailMessage) => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if ( !authenticationPublicKey || @@ -903,25 +1047,48 @@ const connection = Penpal.connectToParent({ chain: passportChain } = response.data; - const keys = - await createOneTimePassportCertificate( - makeid() + "-" + passportUUID, emailArg, passportPrivateKey, passportCertificate); + const keys = await createOneTimePassportCertificate( + makeid() + "-" + passportUUID, + emailArg, + passportPrivateKey, + passportCertificate + ); - const { privateKeyPEM: privateKeyOneTime, certificatePEM: certificateOneTime } = keys; + const { + privateKeyPEM: privateKeyOneTime, + certificatePEM: certificateOneTime + } = keys; passportChain.push(passportCertificate); response = await executeRestfulFunction( - "private", window.viamApi, window.viamApi.passportGetEmailWithHeaderByPassport, null, passportUUID, emailMessage); + "private", + window.viamApi, + window.viamApi.passportGetEmailWithHeaderByPassport, + null, + passportUUID, + emailMessage + ); if (response.code !== "200") { return encodeResponse("400", "", response.status); } - const signedEmail = await signEmail(response.data, certificateOneTime, passportChain, privateKeyOneTime); + const signedEmail = await signEmail( + response.data, + certificateOneTime, + passportChain, + privateKeyOneTime + ); response = await executeRestfulFunction( - "private", window.viamApi, window.viamApi.signResignEmail, null, passportUUID, signedEmail); + "private", + window.viamApi, + window.viamApi.signResignEmail, + null, + passportUUID, + signedEmail + ); if (response.code !== "200") { return encodeResponse("400", "", response.status); @@ -930,7 +1097,9 @@ const connection = Penpal.connectToParent({ return encodeResponse("200", response.data, "Email signed"); }, documentCreateDocument: async (path, passportUUID, contenttype) => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if ( !authenticationPublicKey || !window.loadedIdentities[authenticationPublicKey] || @@ -946,13 +1115,19 @@ const connection = Penpal.connectToParent({ contenttype } }; - const response = await executeRestfulFunction("private", window.viamApi, window.viamApi.documentCreateDocument, - config); + const response = await executeRestfulFunction( + "private", + window.viamApi, + window.viamApi.documentCreateDocument, + config + ); return encodeResponse("200", response.data, "Document created"); }, documentPutDocument: async (passportUUID, resourceid, file) => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if ( !authenticationPublicKey || !window.loadedIdentities[authenticationPublicKey] || @@ -963,43 +1138,58 @@ const connection = Penpal.connectToParent({ const config = { headers: { - 'Content-Type': 'multipart/form-data', + "Content-Type": "multipart/form-data", passportuuid: passportUUID, resourceid } }; const response = await executeRestfulFunction( - "private", window.viamApi, window.viamApi.documentPutDocument, config, file); + "private", + window.viamApi, + window.viamApi.documentPutDocument, + config, + file + ); return encodeResponse("200", response.data, "Document created"); }, hasSession() { return new Penpal.Promise(result => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if (authenticationPublicKey === null) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" + result({ + data: "", + code: "400", + status: "Identity not authenticated" }); } if (window.loadedIdentities[authenticationPublicKey] === null) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" + result({ + data: "", + code: "400", + status: "Identity not authenticated" }); } var success = extendPinCodeTtl(authenticationPublicKey); - if(success === false) { - result({"data" : "", - "code" : "400", - "status" : "Identity not authenticated" - }) + if (success === false) { + result({ + data: "", + code: "400", + status: "Identity not authenticated" + }); } - executeRestfulFunction("private", viamApi, viamApi.identityHasSession, null).then(executeResult => { + executeRestfulFunction( + "private", + viamApi, + viamApi.identityHasSession, + null + ).then(executeResult => { result(executeResult); }); }); @@ -1008,7 +1198,14 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity("marketingapppublickey"); - executeRestfulFunction("public", viamApi, viamApi.marketingSignUpIdentificator, null, identificator, reference).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.marketingSignUpIdentificator, + null, + identificator, + reference + ).then(executeResult => { viamApi.setIdentity(""); viamApi.setSessionData("", ""); result(executeResult); @@ -1019,7 +1216,14 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity("marketingapppublickey"); - executeRestfulFunction("public", viamApi, viamApi.marketingGetIdentificatorProfile, null, identificator, pincode).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.marketingGetIdentificatorProfile, + null, + identificator, + pincode + ).then(executeResult => { viamApi.setIdentity(""); viamApi.setSessionData("", ""); result(executeResult); @@ -1030,7 +1234,15 @@ const connection = Penpal.connectToParent({ return new Penpal.Promise(result => { viamApi.setIdentity("marketingapppublickey"); - executeRestfulFunction("public", viamApi, viamApi.marketingExecuteEventForIdentificator, null, identificator, pincode, event).then(executeResult => { + executeRestfulFunction( + "public", + viamApi, + viamApi.marketingExecuteEventForIdentificator, + null, + identificator, + pincode, + event + ).then(executeResult => { viamApi.setIdentity(""); viamApi.setSessionData("", ""); result(executeResult); @@ -1038,7 +1250,10 @@ const connection = Penpal.connectToParent({ }); }, getCurrentlyAuthenticatedIdentity() { - const { publicKey, x509Certificate } = window.currentlyAuthenticatedIdentity.authentication; + const { + publicKey, + x509Certificate + } = window.currentlyAuthenticatedIdentity.authentication; return encodeResponse( "200", @@ -1052,64 +1267,64 @@ const connection = Penpal.connectToParent({ ); }, stringToUtf8ByteArray(str) { - if (typeof str !== 'string') { - str = str.toString() + if (typeof str !== "string") { + str = str.toString(); } - let res = Buffer.from(str,'utf-8'); + let res = Buffer.from(str, "utf-8"); return new Penpal.Promise(result => { - result(res) - }) + result(res); + }); }, utf8ByteArrayToString(ba) { if (!Buffer.isBuffer(ba)) { - ba = Buffer.from(ba) + ba = Buffer.from(ba); } - let res = ba.toString('utf-8'); + let res = ba.toString("utf-8"); return new Penpal.Promise(result => { - result(res) - }) + result(res); + }); }, stringToUtf8Base64(str) { if (!Buffer.isBuffer(str)) { - if (typeof str !== 'string') { - str = str.toString() + if (typeof str !== "string") { + str = str.toString(); } - str = Buffer.from(str, 'utf-8') + str = Buffer.from(str, "utf-8"); } - let res = str.toString('base64'); + let res = str.toString("base64"); return new Penpal.Promise(result => { - result(res) - }) + result(res); + }); }, utf8Base64ToString(strBase64) { if (!Buffer.isBuffer(strBase64)) { - if (typeof strBase64 !== 'string') { - strBase64 = strBase64.toString() + if (typeof strBase64 !== "string") { + strBase64 = strBase64.toString(); } - strBase64 = Buffer.from(strBase64, 'base64') + strBase64 = Buffer.from(strBase64, "base64"); } - let res = strBase64.toString('utf-8'); + let res = strBase64.toString("utf-8"); return new Penpal.Promise(result => { - result(res) - }) + result(res); + }); }, base64ToByteArray(strBase64) { - if (typeof strBase64 !== 'string') { - strBase64 = strBase64.toString() + if (typeof strBase64 !== "string") { + strBase64 = strBase64.toString(); } - let res = Buffer.from(strBase64, 'base64'); + let res = Buffer.from(strBase64, "base64"); return new Penpal.Promise(result => { - result(res) - }) + result(res); + }); }, byteArrayToBase64(ba) { if (!Buffer.isBuffer(ba)) { - ba = Buffer.from(ba) + ba = Buffer.from(ba); } - let res = ba.toString('base64'); + let res = ba.toString("base64"); return new Penpal.Promise(result => { - result(res) - }) + result(res); + }); }, // Collabora APIs @@ -1119,7 +1334,9 @@ const connection = Penpal.connectToParent({ // WOPI getPassports: async fileId => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if ( !authenticationPublicKey || @@ -1134,7 +1351,9 @@ const connection = Penpal.connectToParent({ }, wopiPutFile: async (path, accessToken, file) => { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if ( !authenticationPublicKey || @@ -1158,9 +1377,10 @@ connection.promise.then(parent => { return; } - window.addEventListener('storage', event => { + window.addEventListener("storage", event => { if (event.key === "authenticatedIdentity" && event.newValue === null) { - const publicKey = window.currentlyAuthenticatedIdentity.authentication.publicKey; + const publicKey = + window.currentlyAuthenticatedIdentity.authentication.publicKey; window.currentlyLoadedIdentity = null; window.currentlyAuthenticatedIdentity = null; const event = createEvent("LogoutFromAnotherTab", "Logout", [publicKey]); @@ -1187,7 +1407,9 @@ connection.promise.then(parent => { localStorage.removeItem("token"); localStorage.removeItem("authenticatedIdentity"); } else { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); const pinCode = getPincode(authenticationPublicKey); if (pinCode === "" || pinCode === null) { @@ -1231,27 +1453,42 @@ connection.promise.then(parent => { let previousLocalStorageToken; let previousLocalStorageIdentity; - setInterval(async function () { + setInterval(async function() { if (window.currentlyAuthenticatedIdentity) { const { authentication } = window.currentlyAuthenticatedIdentity; const pinCode = getPincode(authentication.publicKey); if (pinCode) { - const identity = await getIdentityFromLocalStorage(authentication.publicKey, pinCode, false); + const identity = await getIdentityFromLocalStorage( + authentication.publicKey, + pinCode, + false + ); window.currentlyLoadedIdentity = identity; if (!identityAuthenticatedEvent && identity) { - const event = createEvent("IdentityAuthenticated", "Authenticated", [identity.authentication.publicKey]); + const event = createEvent("IdentityAuthenticated", "Authenticated", [ + identity.authentication.publicKey + ]); parent.onEvent(event); identityAuthenticatedEvent = true; } } else { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); if (authenticationPublicKey) { - const result = await loadIdentityInternal(authenticationPublicKey, "00000000"); + const result = await loadIdentityInternal( + authenticationPublicKey, + "00000000" + ); if (result.code !== "200") { - const event = createEvent("CanNotGetPincodeForAuthenticatedIdentity", "IdentityNotLoaded", [authenticationPublicKey]); + const event = createEvent( + "CanNotGetPincodeForAuthenticatedIdentity", + "IdentityNotLoaded", + [authenticationPublicKey] + ); parent.onEvent(event); clearPinCodeTtl(authenticationPublicKey); window.currentlyAuthenticatedIdentity = null; @@ -1264,12 +1501,21 @@ connection.promise.then(parent => { } if (window.currentlyLoadedIdentity) { - const pinCode = getPincode(window.currentlyLoadedIdentity.authentication.publicKey); + const pinCode = getPincode( + window.currentlyLoadedIdentity.authentication.publicKey + ); if (!pinCode) { if (!identityLoadedEvent) { - const result = await loadIdentityInternal(window.currentlyLoadedIdentity.authentication.publicKey, "00000000"); + const result = await loadIdentityInternal( + window.currentlyLoadedIdentity.authentication.publicKey, + "00000000" + ); if (window.currentlyLoadedIdentity && result.code !== "200") { - const event = createEvent("CanNotLoadPincodeForLoadedIdentity", "IdentityNotLoaded", [window.currentlyLoadedIdentity.authentication.publicKey]); + const event = createEvent( + "CanNotLoadPincodeForLoadedIdentity", + "IdentityNotLoaded", + [window.currentlyLoadedIdentity.authentication.publicKey] + ); parent.onEvent(event); identityLoadedEvent = true; } @@ -1289,11 +1535,13 @@ connection.promise.then(parent => { const currentLocalStorageUUID = localStorage.getItem("uuid"); const currentLocalStorageToken = localStorage.getItem("token"); - const currentLocalStorageIdentity = localStorage.getItem("authenticatedIdentity"); + const currentLocalStorageIdentity = localStorage.getItem( + "authenticatedIdentity" + ); if ( - !currentLocalStorageUUID && previousLocalStorageUUID || - !currentLocalStorageToken && previousLocalStorageToken || - !currentLocalStorageIdentity && previousLocalStorageIdentity + (!currentLocalStorageUUID && previousLocalStorageUUID) || + (!currentLocalStorageToken && previousLocalStorageToken) || + (!currentLocalStorageIdentity && previousLocalStorageIdentity) ) { previousLocalStorageUUID = null; previousLocalStorageToken = null; @@ -1313,34 +1561,42 @@ connection.promise.then(parent => { const getNewEventsWithoutSession = async () => { anynomousDeviceKeyEventsProcessing = true; try { - const executeResult = await executeRestfulFunction("public", viamAnonymousApi, viamAnonymousApi.eventGetNewEventsWithoutSession, null, "devicekey"); - if(executeResult.code === "200") { + const executeResult = await executeRestfulFunction( + "public", + viamAnonymousApi, + viamAnonymousApi.eventGetNewEventsWithoutSession, + null, + "devicekey" + ); + if (executeResult.code === "200") { const eventsLen = executeResult.data.length; let changedMaxDeviceKeyAnonymousEventTime = false; for (let i = 0; i < eventsLen; i++) { const event = executeResult.data[i]; switch (event.type) { - case "DeviceConfirmed" : { + case "DeviceConfirmed": { await setIdentityInLocalStorage(window.currentlyLoadedIdentity); parent.onEvent(event); break; } - case "QRCodeUpdated" : { + case "QRCodeUpdated": { const actionID = event["actionID"]; const QrCode = event["payloads"][1]; const eventCopy = JSON.parse(JSON.stringify(event)); - QRCode.toDataURL(actionID + "," + QrCode, function (err, url) { + QRCode.toDataURL(actionID + "," + QrCode, function(err, url) { eventCopy["payloads"].push(url); parent.onEvent(eventCopy); }); break; } - case "KeyDeleted" : { - const authenticationPublicKey = localStorage.getItem("authenticatedIdentity"); + case "KeyDeleted": { + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); clearPinCodeTtl(authenticationPublicKey); localStorage.removeItem("uuid"); localStorage.removeItem("token"); @@ -1354,17 +1610,26 @@ connection.promise.then(parent => { break; } - default : { + default: { parent.onEvent(event); } } changedMaxDeviceKeyAnonymousEventTime = true; - maxDeviceKeyAnonymousEventTime = Math.max(maxDeviceKeyAnonymousEventTime, event.stamp); + maxDeviceKeyAnonymousEventTime = Math.max( + maxDeviceKeyAnonymousEventTime, + event.stamp + ); } - if(changedMaxDeviceKeyAnonymousEventTime) { - await executeRestfulFunction("public", viamAnonymousApi, viamAnonymousApi.eventUpdateLastViewedWithoutSession, - null, "devicekey", maxDeviceKeyAnonymousEventTime.toString()); + if (changedMaxDeviceKeyAnonymousEventTime) { + await executeRestfulFunction( + "public", + viamAnonymousApi, + viamAnonymousApi.eventUpdateLastViewedWithoutSession, + null, + "devicekey", + maxDeviceKeyAnonymousEventTime.toString() + ); } } } catch (e) { @@ -1376,7 +1641,13 @@ connection.promise.then(parent => { const getNewDeviceEvents = async () => { eventsDeviceEventsProcessing = true; try { - const executeResult = await executeRestfulFunction("private", viamApi, viamApi.eventGetNewEvents, null, "devicekey"); + const executeResult = await executeRestfulFunction( + "private", + viamApi, + viamApi.eventGetNewEvents, + null, + "devicekey" + ); if (executeResult.code === "200") { const eventsLen = executeResult.data.length; const changedMaxDeviceKeyEventTime = false; @@ -1388,7 +1659,7 @@ connection.promise.then(parent => { const eventCopy = JSON.parse(JSON.stringify(event)); - QRCode.toDataURL(actionID + "," + QrCode, function (err, url) { + QRCode.toDataURL(actionID + "," + QrCode, function(err, url) { eventCopy["payloads"].push(url); parent.onEvent(eventCopy); }); @@ -1397,9 +1668,15 @@ connection.promise.then(parent => { } maxDeviceKeyEventTime = Math.max(maxDeviceKeyEventTime, event.stamp); } - if(changedMaxDeviceKeyEventTime) { - await executeRestfulFunction("private", viamApi, viamApi.eventUpdateLastViewed, null, "devicekey", - maxDeviceKeyEventTime.toString()); + if (changedMaxDeviceKeyEventTime) { + await executeRestfulFunction( + "private", + viamApi, + viamApi.eventUpdateLastViewed, + null, + "devicekey", + maxDeviceKeyEventTime.toString() + ); } } } catch (e) { @@ -1411,7 +1688,13 @@ connection.promise.then(parent => { const getNewEntityEvents = async () => { eventsEntityEventsProcessing = true; try { - const executeResult = await executeRestfulFunction("private", viamApi, viamApi.eventGetNewEvents, null, "entity"); + const executeResult = await executeRestfulFunction( + "private", + viamApi, + viamApi.eventGetNewEvents, + null, + "entity" + ); if (executeResult.code === "200") { const eventsLen = executeResult.data.length; @@ -1424,7 +1707,7 @@ connection.promise.then(parent => { const eventCopy = JSON.parse(JSON.stringify(event)); - QRCode.toDataURL(actionID + "," + QrCode, function (err, url) { + QRCode.toDataURL(actionID + "," + QrCode, function(err, url) { eventCopy["payloads"].push(url); parent.onEvent(eventCopy); }); @@ -1436,19 +1719,29 @@ connection.promise.then(parent => { changedMaxEntityEventTime = true; maxEntityEventTime = Math.max(maxEntityEventTime, event.stamp); } - if(changedMaxEntityEventTime) { - await executeRestfulFunction("private", viamApi, viamApi.eventUpdateLastViewed, null, "entity", - maxEntityEventTime.toString()); + if (changedMaxEntityEventTime) { + await executeRestfulFunction( + "private", + viamApi, + viamApi.eventUpdateLastViewed, + null, + "entity", + maxEntityEventTime.toString() + ); } } } catch (e) { console.warn(e); } eventsEntityEventsProcessing = false; - } + }; setInterval(() => { - if (window.currentlyLoadedIdentity && !anynomousDeviceKeyEventsProcessing && !window.currentlyAuthenticatedIdentity) { + if ( + window.currentlyLoadedIdentity && + !anynomousDeviceKeyEventsProcessing && + !window.currentlyAuthenticatedIdentity + ) { getNewEventsWithoutSession(); } diff --git a/javascript/src/iframe/wopiapi-iframe.js b/javascript/src/iframe/wopiapi-iframe.js index 24283fc69c29dd844caf10569679733d18def100..f927dc18722f8e8d33741732bafb6307717efb08 100644 --- a/javascript/src/iframe/wopiapi-iframe.js +++ b/javascript/src/iframe/wopiapi-iframe.js @@ -1,12 +1,17 @@ -const axios = require('axios'); +const axios = require("axios"); function WopiAPI() {} -WopiAPI.prototype.getPassports = function (fileID) { - const { publicKey, uuid, token, deviceHash } = window.viamApi.getConfig().headers; +WopiAPI.prototype.getPassports = function(fileID) { + const { + publicKey, + uuid, + token, + deviceHash + } = window.viamApi.getConfig().headers; const requestConfig = { url: `${window.WOPI_URL}getPassports`, - method: 'POST', + method: "POST", headers: { publicKey, uuid, @@ -19,13 +24,18 @@ WopiAPI.prototype.getPassports = function (fileID) { return axios(requestConfig); }; -WopiAPI.prototype.putDocument = function (path, accessToken, file) { - const { publicKey, uuid, token, deviceHash } = window.viamApi.getConfig().headers; +WopiAPI.prototype.putDocument = function(path, accessToken, file) { + const { + publicKey, + uuid, + token, + deviceHash + } = window.viamApi.getConfig().headers; path = path[0] === "/" ? path : `/${path}`; path = encodeURI(path); const requestConfig = { url: `${window.WOPI_URL}files${path}/contents`, - method: 'POST', + method: "POST", headers: { publicKey, uuid, diff --git a/javascript/src/utilities/appUtility.js b/javascript/src/utilities/appUtility.js index c6090f2558c3a71d5edb8ee60efcb79fc49b27a1..aea06c3b879458feea059e231c59c97382c6b765 100644 --- a/javascript/src/utilities/appUtility.js +++ b/javascript/src/utilities/appUtility.js @@ -1,6 +1,6 @@ -import { getCrypto } from 'pkijs'; +import { getCrypto } from "pkijs"; -export const createDeviceHash = async (publicKey) => { +export const createDeviceHash = async publicKey => { try { const stringToEncode = publicKey + navigator.userAgent; const crypto = getCrypto(); @@ -21,11 +21,12 @@ export const encodeResponse = (code, data, status) => { }; export function makeid(len) { - if (typeof len === 'undefined') { - len = 10 + if (typeof len === "undefined") { + len = 10; } var text = ""; - var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + var possible = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < len; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); @@ -49,7 +50,12 @@ export function getTimeLeftInLocalStorage() { let minutes = Math.floor((blockFinishTime - timeNow) / 60); minutes %= 60; - const left = "Your identity has been locked. Try again in " + minutes + " minutes and " + seconds + " seconds."; + const left = + "Your identity has been locked. Try again in " + + minutes + + " minutes and " + + seconds + + " seconds."; return left; } @@ -58,16 +64,18 @@ export function listIdentitiesFromLocalStorage() { var identities = JSON.parse(serializedIdentitiesList); var identitiesResult = {}; - for(var key in identities) { - var profile = JSON.parse(JSON.stringify(localStorage.getItem("profiles/" + key))); - if(profile != null && profile !== "") { - identitiesResult[key] = JSON.parse(profile) + for (var key in identities) { + var profile = JSON.parse( + JSON.stringify(localStorage.getItem("profiles/" + key)) + ); + if (profile != null && profile !== "") { + identitiesResult[key] = JSON.parse(profile); } else { - identitiesResult[key] = {} + identitiesResult[key] = {}; } } - return identitiesResult + return identitiesResult; } export function destroyIdentityFromLocalStorage(key) { @@ -83,12 +91,12 @@ export function destroyIdentityFromLocalStorage(key) { delete identities[key]; - localStorage.setItem("identities", JSON.stringify(identities)) + localStorage.setItem("identities", JSON.stringify(identities)); } export function failPincodeAttempt(password) { let message = "Wrong pincode"; - if (password !== '00000000') { + if (password !== "00000000") { let attempt = localStorage.getItem("attempt") || 1; attempt = parseInt(attempt); if (attempt === 9) { @@ -120,4 +128,4 @@ export function canTryPincode() { } else { return false; } -} \ No newline at end of file +} diff --git a/javascript/src/utilities/emailUtilities.js b/javascript/src/utilities/emailUtilities.js index 0b5f92035105c1cc3b693c62147471a0ae20c679..df59737b20636ffca4b5b5431c024be65ff6668f 100644 --- a/javascript/src/utilities/emailUtilities.js +++ b/javascript/src/utilities/emailUtilities.js @@ -1,6 +1,6 @@ import dataUriToBlob from "data-uri-to-blob"; -import libmime from 'libmime'; -import union from 'lodash/union'; +import libmime from "libmime"; +import union from "lodash/union"; import { fixNewLines, @@ -14,14 +14,16 @@ import { import { getCertificateChain } from "./signingUtilities"; const SIGNATURE_CONTENT_TYPE = "application/pkcs7-signature"; -export const DEFAULT_ATTACHMENT_NAME = 'attachment'; +export const DEFAULT_ATTACHMENT_NAME = "attachment"; const splitParticipants = participantsList => { if (!participantsList) { return []; } - const participants = participantsList.map(participants => participants.split(",").map(p => p.trim())); + const participants = participantsList.map(participants => + participants.split(",").map(p => p.trim()) + ); return union.apply(null, participants); }; @@ -84,14 +86,16 @@ export const parseSMIME = smimeString => { * @returns {string} ('file.txt') */ export const getFilenameFromHeaders = headers => { - const headersToSearch = ['content-type', 'content-disposition']; + const headersToSearch = ["content-type", "content-disposition"]; - const filename = headers && Object.keys(headers) - .filter(key => headersToSearch.includes(key)) - .reduce((result, key) => { - const headerValue = libmime.parseHeaderValue(headers[key][0]); - return result || headerValue.params.name || headerValue.params.filename; - }, ''); + const filename = + headers && + Object.keys(headers) + .filter(key => headersToSearch.includes(key)) + .reduce((result, key) => { + const headerValue = libmime.parseHeaderValue(headers[key][0]); + return result || headerValue.params.name || headerValue.params.filename; + }, ""); return filename || DEFAULT_ATTACHMENT_NAME; }; @@ -110,8 +114,9 @@ export const extractHtmlBodyFromString = string => { if (bodyMatch && bodyMatch[1]) { body = bodyMatch[1] - .replace(/>\s+</gm, '><') - .replace(/<!--[\s\S]*?-->/gm, '').trim() + .replace(/>\s+</gm, "><") + .replace(/<!--[\s\S]*?-->/gm, "") + .trim(); } return body; diff --git a/javascript/src/utilities/signingUtilities.js b/javascript/src/utilities/signingUtilities.js index 2d68adc77fb074924821e432abe231daa0c70968..db402262761c388095f2ab57777f9b0030297555 100644 --- a/javascript/src/utilities/signingUtilities.js +++ b/javascript/src/utilities/signingUtilities.js @@ -1,13 +1,18 @@ -import {canTryPincode, failPincodeAttempt, getTimeLeftInLocalStorage, makeid} from './appUtility'; -import {bufferToHexCodes, stringToArrayBuffer} from 'pvutils'; -import {fromBER} from 'asn1js'; -import {ContentInfo, SignedData} from 'pkijs'; -import {algomap, rdnmap} from '../constants/certificates'; - -const libmime = require('libmime'); -const pkijs = require('pkijs'); -const asn1js = require('asn1js'); -const pvutils = require('pvutils'); +import { + canTryPincode, + failPincodeAttempt, + getTimeLeftInLocalStorage, + makeid +} from "./appUtility"; +import { bufferToHexCodes, stringToArrayBuffer } from "pvutils"; +import { fromBER } from "asn1js"; +import { ContentInfo, SignedData } from "pkijs"; +import { algomap, rdnmap } from "../constants/certificates"; + +const libmime = require("libmime"); +const pkijs = require("pkijs"); +const asn1js = require("asn1js"); +const pvutils = require("pvutils"); //********************************************************************************* @@ -15,36 +20,40 @@ const CERTIFIATE_Version_1 = 0; const CERTIFIATE_Version_3 = 2; //these bit fields are reversed, WTF! -const KEY_USAGE_DigitalSignature = 0x80;//01; -const KEY_USAGE_NonRepudiation = 0x40;//02; -const KEY_USAGE_KeyEncipherment = 0x20;//04; -const KEY_USAGE_DataEncipherment = 0x10;//08; -const KEY_USAGE_KeyAgreement = 0x08;//10; -const KEY_USAGE_KeyCertSign = 0x04;//20; -const KEY_USAGE_CRLSign = 0x02;//40; +const KEY_USAGE_DigitalSignature = 0x80; //01; +const KEY_USAGE_NonRepudiation = 0x40; //02; +const KEY_USAGE_KeyEncipherment = 0x20; //04; +const KEY_USAGE_DataEncipherment = 0x10; //08; +const KEY_USAGE_KeyAgreement = 0x08; //10; +const KEY_USAGE_KeyCertSign = 0x04; //20; +const KEY_USAGE_CRLSign = 0x02; //40; //const KEY_USAGE_EncipherOnly = 0x01;//80; // Not used for now. Must be used together with KEY_USAGE_KeyAgreement (maybe should be ORed as a constant directly?) //const KEY_USAGE_DecipherOnly = 0x80;//0100; // If used, modify "KeyUsage" extension array buffer size and appropriate bit operators to accomodate for extra byte -const KEY_USAGE_LeafCertificate = KEY_USAGE_DigitalSignature | KEY_USAGE_NonRepudiation | KEY_USAGE_KeyEncipherment | KEY_USAGE_DataEncipherment; -const KEY_USAGE_CertificateAuthority= KEY_USAGE_DigitalSignature | KEY_USAGE_KeyCertSign | KEY_USAGE_CRLSign; - - -const OID_EXT_KEY_USAGE_Any = "2.5.29.37.0"; -const OID_ID_PKIX_ServerAuth = "1.3.6.1.5.5.7.3.1"; -const OID_ID_PKIX_ClientAuth = "1.3.6.1.5.5.7.3.2"; -const OID_ID_PKIX_CodeSigning = "1.3.6.1.5.5.7.3.3"; -const OID_ID_PKIX_EmailProtection = "1.3.6.1.5.5.7.3.4"; -const OID_ID_PKIX_TimeStamping = "1.3.6.1.5.5.7.3.8"; -const OID_ID_PKIX_OCSPSigning = "1.3.6.1.5.5.7.3.9"; +const KEY_USAGE_LeafCertificate = + KEY_USAGE_DigitalSignature | + KEY_USAGE_NonRepudiation | + KEY_USAGE_KeyEncipherment | + KEY_USAGE_DataEncipherment; +const KEY_USAGE_CertificateAuthority = + KEY_USAGE_DigitalSignature | KEY_USAGE_KeyCertSign | KEY_USAGE_CRLSign; + +const OID_EXT_KEY_USAGE_Any = "2.5.29.37.0"; +const OID_ID_PKIX_ServerAuth = "1.3.6.1.5.5.7.3.1"; +const OID_ID_PKIX_ClientAuth = "1.3.6.1.5.5.7.3.2"; +const OID_ID_PKIX_CodeSigning = "1.3.6.1.5.5.7.3.3"; +const OID_ID_PKIX_EmailProtection = "1.3.6.1.5.5.7.3.4"; +const OID_ID_PKIX_TimeStamping = "1.3.6.1.5.5.7.3.8"; +const OID_ID_PKIX_OCSPSigning = "1.3.6.1.5.5.7.3.9"; // const OID_EXT_KEY_USAGE_MS... = "1.3.6.1.4.1.311.10.3.1"; // Microsoft Certificate Trust List signing // const OID_EXT_KEY_USAGE_MS... = "1.3.6.1.4.1.311.10.3.4"; // Microsoft Encrypted File System -const OID_PKCS7_Data = "1.2.840.113549.1.7.1"; -const OID_PKCS7_SignedData = "1.2.840.113549.1.7.2"; -const OID_PKCS7_EnvelopedData = "1.2.840.113549.1.7.3"; -const OID_PKCS9_EmailAddress = "1.2.840.113549.1.9.1"; -const OID_PKCS9_ContentType = "1.2.840.113549.1.9.3"; -const OID_PKCS9_MessageDigest = "1.2.840.113549.1.9.4"; -const OID_PKCS9_SigningTime = "1.2.840.113549.1.9.5"; +const OID_PKCS7_Data = "1.2.840.113549.1.7.1"; +const OID_PKCS7_SignedData = "1.2.840.113549.1.7.2"; +const OID_PKCS7_EnvelopedData = "1.2.840.113549.1.7.3"; +const OID_PKCS9_EmailAddress = "1.2.840.113549.1.9.1"; +const OID_PKCS9_ContentType = "1.2.840.113549.1.9.3"; +const OID_PKCS9_MessageDigest = "1.2.840.113549.1.9.4"; +const OID_PKCS9_SigningTime = "1.2.840.113549.1.9.5"; const defaultAlgorithms = { hashAlg: "SHA-256", @@ -52,7 +61,7 @@ const defaultAlgorithms = { keyLength: 2048 }; -const AES_encryptionVariant_Password = 2; +const AES_encryptionVariant_Password = 2; const encryptionAlgorithm = { name: "AES-CBC", length: 128 @@ -84,8 +93,11 @@ function generateKeys(algorithms) { } //region Get default algorithm parameters for key generation - const algorithm = pkijs.getAlgorithmParameters(algorithms.signAlg, "generatekey"); - if("hash" in algorithm.algorithm) { + const algorithm = pkijs.getAlgorithmParameters( + algorithms.signAlg, + "generatekey" + ); + if ("hash" in algorithm.algorithm) { algorithm.algorithm.hash.name = algorithms.hashAlg; } algorithm.algorithm.modulusLength = algorithms.keyLength; @@ -95,9 +107,7 @@ function generateKeys(algorithms) { } //********************************************************************************* -function createCertificate(certData, issuerData = null) -{ - +function createCertificate(certData, issuerData = null) { if (typeof certData === "undefined") { return Promise.reject("No Certificate data provided"); } @@ -106,7 +116,6 @@ function createCertificate(certData, issuerData = null) return Promise.reject("No Certificate subject data provided"); } - //region Get a "crypto" extension const crypto = pkijs.getCrypto(); @@ -122,35 +131,34 @@ function createCertificate(certData, issuerData = null) let publicKey; let privateKey; - let certificateBuffer;// = new ArrayBuffer(0); // ArrayBuffer with loaded or created CERT - let privateKeyBuffer;// = new ArrayBuffer(0); - let publicKeyBuffer;// = new ArrayBuffer(0); + let certificateBuffer; // = new ArrayBuffer(0); // ArrayBuffer with loaded or created CERT + let privateKeyBuffer; // = new ArrayBuffer(0); + let publicKeyBuffer; // = new ArrayBuffer(0); //endregion Initial variables if (certData.keyPair) { //region Create a new key pair - sequence = sequence.then(() => - { + sequence = sequence.then(() => { return certData.keyPair; }); //endregion Create a new key pair - } else { //region Create a new key pair - sequence = sequence.then(() => - { + sequence = sequence.then(() => { return generateKeys(certData.algorithms); }); //endregion Create a new key pair } //region Store new key in an interim variables - sequence = sequence.then(keyPair => - { - publicKey = keyPair.publicKey; - privateKey = keyPair.privateKey; - }, error => Promise.reject(`Error during key generation: ${error}`)); + sequence = sequence.then( + keyPair => { + publicKey = keyPair.publicKey; + privateKey = keyPair.privateKey; + }, + error => Promise.reject(`Error during key generation: ${error}`) + ); //endregion Store new key in an interim variables //region Exporting public key into "subjectPublicKeyInfo" value of certificate @@ -160,14 +168,16 @@ function createCertificate(certData, issuerData = null) //endregion Exporting public key into "subjectPublicKeyInfo" value of certificate sequence = sequence.then( - () => crypto.digest({ name: "SHA-1" }, certificate.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex), + () => + crypto.digest( + { name: "SHA-1" }, + certificate.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex + ), error => Promise.reject(`Error during importing public key: ${error}`) ); //region Fill in cert data - sequence = sequence.then(subjKeyIdBuffer => - { - + sequence = sequence.then(subjKeyIdBuffer => { //region Put a static values certificate.version = CERTIFIATE_Version_3; @@ -175,69 +185,92 @@ function createCertificate(certData, issuerData = null) const serialNumberView = new Uint8Array(serialNumberBuffer); pkijs.getRandomValues(serialNumberView); // noinspection JSUnresolvedFunction - certificate.serialNumber = new asn1js.Integer({ valueHex: serialNumberView }); + certificate.serialNumber = new asn1js.Integer({ + valueHex: serialNumberView + }); //endregion Put a static values //region Subject // For reference http://oidref.com/2.5.4.3 if (certData.subject.commonName) { // noinspection JSUnresolvedFunction - certificate.subject.typesAndValues.push(new pkijs.AttributeTypeAndValue({ - type: "2.5.4.3", // Common name - value: new asn1js.PrintableString({ value: certData.subject.commonName }) - })); + certificate.subject.typesAndValues.push( + new pkijs.AttributeTypeAndValue({ + type: "2.5.4.3", // Common name + value: new asn1js.PrintableString({ + value: certData.subject.commonName + }) + }) + ); } if (certData.subject.country) { // noinspection JSUnresolvedFunction - certificate.subject.typesAndValues.push(new pkijs.AttributeTypeAndValue({ - type: "2.5.4.6", // Country name - value: new asn1js.PrintableString({ value: certData.subject.country }) - })); + certificate.subject.typesAndValues.push( + new pkijs.AttributeTypeAndValue({ + type: "2.5.4.6", // Country name + value: new asn1js.PrintableString({ value: certData.subject.country }) + }) + ); } if (certData.subject.locality) { // noinspection JSUnresolvedFunction - certificate.subject.typesAndValues.push(new pkijs.AttributeTypeAndValue({ - type: "2.5.4.7", // Locality Name - value: new asn1js.PrintableString({ value: certData.subject.locality }) - })); + certificate.subject.typesAndValues.push( + new pkijs.AttributeTypeAndValue({ + type: "2.5.4.7", // Locality Name + value: new asn1js.PrintableString({ + value: certData.subject.locality + }) + }) + ); } if (certData.subject.state) { // noinspection JSUnresolvedFunction - certificate.subject.typesAndValues.push(new pkijs.AttributeTypeAndValue({ - type: "2.5.4.8", // State or Province name - value: new asn1js.PrintableString({ value: certData.subject.state }) - })); + certificate.subject.typesAndValues.push( + new pkijs.AttributeTypeAndValue({ + type: "2.5.4.8", // State or Province name + value: new asn1js.PrintableString({ value: certData.subject.state }) + }) + ); } if (certData.subject.organization) { // noinspection JSUnresolvedFunction - certificate.subject.typesAndValues.push(new pkijs.AttributeTypeAndValue({ - type: "2.5.4.10", // Organization name - value: new asn1js.PrintableString({ value: certData.subject.organization }) - })); + certificate.subject.typesAndValues.push( + new pkijs.AttributeTypeAndValue({ + type: "2.5.4.10", // Organization name + value: new asn1js.PrintableString({ + value: certData.subject.organization + }) + }) + ); } if (certData.subject.organizationUnit) { // noinspection JSUnresolvedFunction - certificate.subject.typesAndValues.push(new pkijs.AttributeTypeAndValue({ - type: "2.5.4.11", // Organization unit name - value: new asn1js.PrintableString({ value: certData.subject.organizationUnit }) - })); + certificate.subject.typesAndValues.push( + new pkijs.AttributeTypeAndValue({ + type: "2.5.4.11", // Organization unit name + value: new asn1js.PrintableString({ + value: certData.subject.organizationUnit + }) + }) + ); } if (certData.subject.email) { // noinspection JSUnresolvedFunction - certificate.subject.typesAndValues.push(new pkijs.AttributeTypeAndValue({ - type: OID_PKCS9_EmailAddress, // Email, deprecated but still widely used - value: new asn1js.IA5String({ value: certData.subject.email }) - })); + certificate.subject.typesAndValues.push( + new pkijs.AttributeTypeAndValue({ + type: OID_PKCS9_EmailAddress, // Email, deprecated but still widely used + value: new asn1js.IA5String({ value: certData.subject.email }) + }) + ); } //endregion Subject - //region Issuer if (issuerData && issuerData.certificate) { certificate.issuer = issuerData.certificate.subject; @@ -248,14 +281,21 @@ function createCertificate(certData, issuerData = null) //region Validity if (!certData.validity) { - certData.validity = {} + certData.validity = {}; } if (certData.validity.notBefore) { certificate.notBefore.value = certData.validity.notBefore; //date } else { const tmp = new Date(); - certificate.notBefore.value = new Date(tmp.getFullYear(), tmp.getMonth(), tmp.getDate(), 0, 0, 0); + certificate.notBefore.value = new Date( + tmp.getFullYear(), + tmp.getMonth(), + tmp.getDate(), + 0, + 0, + 0 + ); } if (certData.validity.notAfter) { @@ -263,7 +303,14 @@ function createCertificate(certData, issuerData = null) } else { const tmp = certificate.notBefore.value; const validYears = certData.validity.validYears || 1; - certificate.notAfter.value = new Date(tmp.getFullYear() + validYears, tmp.getMonth(), tmp.getDate(), 23, 59, 59); + certificate.notAfter.value = new Date( + tmp.getFullYear() + validYears, + tmp.getMonth(), + tmp.getDate(), + 23, + 59, + 59 + ); } //endregion Validity @@ -272,94 +319,106 @@ function createCertificate(certData, issuerData = null) //region "BasicConstraints" extension const basicConstr = new pkijs.BasicConstraints({ - cA: !!certData.isCA, + cA: !!certData.isCA //pathLenConstraint: 0 //TODO add logic for leaf CA }); - certificate.extensions.push(new pkijs.Extension({ - extnID: "2.5.29.19", - critical: true, - extnValue: basicConstr.toSchema().toBER(false), - parsedValue: basicConstr // Parsed value for well-known extensions - })); + certificate.extensions.push( + new pkijs.Extension({ + extnID: "2.5.29.19", + critical: true, + extnValue: basicConstr.toSchema().toBER(false), + parsedValue: basicConstr // Parsed value for well-known extensions + }) + ); //endregion "BasicConstraints" extension //region "KeyUsage" extension const keyUsageBuffer = new ArrayBuffer(1); const keyUsageBitView = new Uint8Array(keyUsageBuffer); - keyUsageBitView[0] = !!certData.isCA ? KEY_USAGE_CertificateAuthority : KEY_USAGE_LeafCertificate; + keyUsageBitView[0] = !!certData.isCA + ? KEY_USAGE_CertificateAuthority + : KEY_USAGE_LeafCertificate; // noinspection JSUnresolvedFunction const keyUsage = new asn1js.BitString({ valueHex: keyUsageBuffer }); - certificate.extensions.push(new pkijs.Extension({ - extnID: "2.5.29.15", - critical: true, - extnValue: keyUsage.toBER(false), - parsedValue: keyUsage // Parsed value for well-known extensions - })); + certificate.extensions.push( + new pkijs.Extension({ + extnID: "2.5.29.15", + critical: true, + extnValue: keyUsage.toBER(false), + parsedValue: keyUsage // Parsed value for well-known extensions + }) + ); //endregion "KeyUsage" extension //region "ExtKeyUsage" extension if (!certData.isCA && certData.subject.email) { const extKeyUsage = new pkijs.ExtKeyUsage({ - keyPurposes: [ - OID_ID_PKIX_EmailProtection - ] + keyPurposes: [OID_ID_PKIX_EmailProtection] }); - certificate.extensions.push(new pkijs.Extension({ - extnID: "2.5.29.37", - critical: false, - extnValue: extKeyUsage.toSchema().toBER(false), - parsedValue: extKeyUsage // Parsed value for well-known extensions - })); + certificate.extensions.push( + new pkijs.Extension({ + extnID: "2.5.29.37", + critical: false, + extnValue: extKeyUsage.toSchema().toBER(false), + parsedValue: extKeyUsage // Parsed value for well-known extensions + }) + ); } //endregion "ExtKeyUsage" extension //region "SubjAltName" extension if (certData.subject.email || certData.subject.url) { - const names = []; if (certData.subject.email) { - names.push(new pkijs.GeneralName({ - type: 1, // rfc822Name - value: certData.subject.email - })); + names.push( + new pkijs.GeneralName({ + type: 1, // rfc822Name + value: certData.subject.email + }) + ); } if (certData.subject.url) { - names.push(new pkijs.GeneralName({ - type: 2, // dNSName - value: certData.subject.url - })); + names.push( + new pkijs.GeneralName({ + type: 2, // dNSName + value: certData.subject.url + }) + ); } const subjAltNames = new pkijs.GeneralNames({ names: names }); - certificate.extensions.push(new pkijs.Extension({ - extnID: "2.5.29.17", - critical: false, - extnValue: subjAltNames.toSchema().toBER(false), - parsedValue: subjAltNames // Parsed value for well-known extensions - })); + certificate.extensions.push( + new pkijs.Extension({ + extnID: "2.5.29.17", + critical: false, + extnValue: subjAltNames.toSchema().toBER(false), + parsedValue: subjAltNames // Parsed value for well-known extensions + }) + ); } //endregion "SubjAltName" extension - //region "SubjectKeyIdentifier" extension const subjKeyId = new asn1js.OctetString({ valueHex: subjKeyIdBuffer }); - certificate.extensions.push(new pkijs.Extension({ - extnID: "2.5.29.14", - critical: false, - extnValue: subjKeyId.toBER(false), - parsedValue: subjKeyId // Parsed value for well-known extensions - })); + certificate.extensions.push( + new pkijs.Extension({ + extnID: "2.5.29.14", + critical: false, + extnValue: subjKeyId.toBER(false), + parsedValue: subjKeyId // Parsed value for well-known extensions + }) + ); //endregion "SubjectKeyIdentifier" extension /* COULD NOT GET IT WORKING @@ -407,50 +466,60 @@ function createCertificate(certData, issuerData = null) }); //region Fill in cert data - //region Signing final certificate - sequence = sequence.then(() => { - let signerKey = (issuerData && issuerData.privateKey) ? issuerData.privateKey : privateKey; - return certificate.sign(signerKey, (certData.algorithms && certData.algorithms.hashAlg) ? certData.algorithms.hashAlg : defaultAlgorithms.hashAlg) + sequence = sequence.then( + () => { + let signerKey = + issuerData && issuerData.privateKey + ? issuerData.privateKey + : privateKey; + return certificate.sign( + signerKey, + certData.algorithms && certData.algorithms.hashAlg + ? certData.algorithms.hashAlg + : defaultAlgorithms.hashAlg + ); }, - error => Promise.reject(`Error during exporting public key: ${error}`)); + error => Promise.reject(`Error during exporting public key: ${error}`) + ); //endregion //region Encode and store certificate - sequence = sequence.then(() => - { - certificateBuffer = certificate.toSchema(true).toBER(false); - }, error => Promise.reject(`Error during signing: ${error}`)); + sequence = sequence.then( + () => { + certificateBuffer = certificate.toSchema(true).toBER(false); + }, + error => Promise.reject(`Error during signing: ${error}`) + ); //endregion //region Exporting public key - sequence = sequence.then(() => - crypto.exportKey("spki", publicKey) - ); + sequence = sequence.then(() => crypto.exportKey("spki", publicKey)); //endregion //region Store exported public key on Web page - sequence = sequence.then(result => - { - publicKeyBuffer = result; - }, error => Promise.reject(`Error during exporting of public key: ${error}`)); + sequence = sequence.then( + result => { + publicKeyBuffer = result; + }, + error => Promise.reject(`Error during exporting of public key: ${error}`) + ); //endregion //region Exporting private key - sequence = sequence.then(() => - crypto.exportKey("pkcs8", privateKey) - ); + sequence = sequence.then(() => crypto.exportKey("pkcs8", privateKey)); //endregion //region Store exported key on Web page - sequence = sequence.then(result => - { - privateKeyBuffer = result; - }, error => Promise.reject(`Error during exporting of private key: ${error}`)); + sequence = sequence.then( + result => { + privateKeyBuffer = result; + }, + error => Promise.reject(`Error during exporting of private key: ${error}`) + ); //endregion return sequence.then(() => { - const result = { certificate: certificate, certificatePEM: encodePEM(certificateBuffer, "CERTIFICATE"), @@ -470,7 +539,7 @@ function formatPEM(pemString) { let piece; while ((piece = pemString.substring(start, start + lineWidth)).length > 0) { start += lineWidth; - resultString += piece + '\r\n'; + resultString += piece + "\r\n"; } return resultString; } @@ -487,7 +556,10 @@ function encodePEM(buffer, label) { } function decodePEM(pemString) { - const pemStripped = pemString.replace(/(-----(BEGIN|END) [a-zA-Z ]*-----|\r|\n)/g, ''); + const pemStripped = pemString.replace( + /(-----(BEGIN|END) [a-zA-Z ]*-----|\r|\n)/g, + "" + ); const pemDecoded = window.atob(pemStripped); const buffer = pvutils.stringToArrayBuffer(pemDecoded); return buffer; @@ -507,18 +579,21 @@ export function encryptMessage(message, password, label) { const secret = pvutils.stringToArrayBuffer(password); const enveloped = new pkijs.EnvelopedData(); - enveloped.addRecipientByPreDefinedData(secret, {}, AES_encryptionVariant_Password); - return enveloped.encrypt(encryptionAlgorithm, buffer). - then( + enveloped.addRecipientByPreDefinedData( + secret, + {}, + AES_encryptionVariant_Password + ); + return enveloped.encrypt(encryptionAlgorithm, buffer).then( () => { const content = new pkijs.ContentInfo(); content.contentType = OID_PKCS7_EnvelopedData; content.content = enveloped.toSchema(); const ber = content.toSchema().toBER(false); - return encodePEM(ber, label) + return encodePEM(ber, label); }, error => Promise.reject(`encryption error: ${error}`) - ) + ); } //********************************************************************************* @@ -528,13 +603,16 @@ export function decryptMessage(message, password) { const buffer = decodePEM(message); const asn1 = asn1js.fromBER(buffer); - const content = new pkijs.ContentInfo({schema: asn1.result}); - const enveloped = new pkijs.EnvelopedData({schema: content.content}); - return enveloped.decrypt(0, {preDefinedData: secret}).then(result => { - return pvutils.arrayBufferToString(result); - }).catch(() => { - return Promise.reject(failPincodeAttempt(password)); - }); + const content = new pkijs.ContentInfo({ schema: asn1.result }); + const enveloped = new pkijs.EnvelopedData({ schema: content.content }); + return enveloped + .decrypt(0, { preDefinedData: secret }) + .then(result => { + return pvutils.arrayBufferToString(result); + }) + .catch(() => { + return Promise.reject(failPincodeAttempt(password)); + }); } else { return Promise.reject(getTimeLeftInLocalStorage()); } @@ -547,9 +625,10 @@ function parsePrivateKey(privateKeyPEM) { const privateKeyPromise = crypto.importKey( "pkcs8", privateKeyBuffer, - { //these are the algorithm options + { + //these are the algorithm options name: "RSASSA-PKCS1-v1_5", - hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512" + hash: { name: "SHA-256" } //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512" }, true, ["sign"] @@ -557,7 +636,6 @@ function parsePrivateKey(privateKeyPEM) { return privateKeyPromise; } - export function createPassportCertificate(commonNameArg) { const certData = { algorithms: { @@ -572,7 +650,7 @@ export function createPassportCertificate(commonNameArg) { locality: "Zug", //optional for leaf, recommended for CA state: "Zug", //optional for leaf, recommended for CA organization: "Vereign AG", //optional for leaf, recommended for CA - organizationUnit:"Business Dep", //optional for leaf, recommended for CA + organizationUnit: "Business Dep" //optional for leaf, recommended for CA //email: "damyan.mitev@vereign.com", // added to DN and Subject Alternative Name extension. Optional for CA. Mandatory for leaf certificate, used for email protection //url: "www.vereign.com" // optional url, recommended for CA, added to Subject Alternative Name extension }, @@ -584,12 +662,17 @@ export function createPassportCertificate(commonNameArg) { isCA: true // optional flag denoting if this is CA certificate or leaf certificate, defaults to false }; - return createCertificate(certData, null) + return createCertificate(certData, null); } -export function createOneTimePassportCertificate(commonNameArg, emailArg, privateKeyIssuerArg, certicateIssuerArg) { +export function createOneTimePassportCertificate( + commonNameArg, + emailArg, + privateKeyIssuerArg, + certicateIssuerArg +) { var certData = null; - if(emailArg != null && emailArg !== "") { + if (emailArg != null && emailArg !== "") { certData = { algorithms: { hashAlg: "SHA-256", @@ -603,8 +686,8 @@ export function createOneTimePassportCertificate(commonNameArg, emailArg, privat locality: "Zug", //optional for leaf, recommended for CA state: "Zug", //optional for leaf, recommended for CA organization: "Vereign AG", //optional for leaf, recommended for CA - organizationUnit:"Business Dep", //optional for leaf, recommended for CA - email: emailArg, // added to DN and Subject Alternative Name extension. Optional for CA. Mandatory for leaf certificate, used for email protection + organizationUnit: "Business Dep", //optional for leaf, recommended for CA + email: emailArg // added to DN and Subject Alternative Name extension. Optional for CA. Mandatory for leaf certificate, used for email protection //url: "www.vereign.com" // optional url, recommended for CA, added to Subject Alternative Name extension }, validity: { @@ -613,7 +696,7 @@ export function createOneTimePassportCertificate(commonNameArg, emailArg, privat validYears: 5 //optional, defaults to 1 }, isCA: false // optional flag denoting if this is CA certificate or leaf certificate, defaults to false - } + }; } else { certData = { algorithms: { @@ -628,7 +711,7 @@ export function createOneTimePassportCertificate(commonNameArg, emailArg, privat locality: "Zug", //optional for leaf, recommended for CA state: "Zug", //optional for leaf, recommended for CA organization: "Vereign AG", //optional for leaf, recommended for CA - organizationUnit:"Business Dep", //optional for leaf, recommended for CA + organizationUnit: "Business Dep" //optional for leaf, recommended for CA //email: emailArg, // added to DN and Subject Alternative Name extension. Optional for CA. Mandatory for leaf certificate, used for email protection //url: "www.vereign.com" // optional url, recommended for CA, added to Subject Alternative Name extension }, @@ -638,12 +721,12 @@ export function createOneTimePassportCertificate(commonNameArg, emailArg, privat validYears: 5 //optional, defaults to 1 }, isCA: false // optional flag denoting if this is CA certificate or leaf certificate, defaults to false - } + }; } return parsePrivateKey(privateKeyIssuerArg).then(privateKeyDecoded => { const issuerData = { - certificate: parseCertificate(certicateIssuerArg),// vereignCACertPEM), + certificate: parseCertificate(certicateIssuerArg), // vereignCACertPEM), privateKey: privateKeyDecoded }; return createCertificate(certData, issuerData); @@ -661,16 +744,20 @@ export function signEmail(mime, signingCert, certificateChain, privateKey) { const certificateChainObj = []; certificateChainObj[0] = parseCertificate(signingCert); for (let i = 0; i < certificateChain.length; i++) { - certificateChainObj[i + 1] = parseCertificate(certificateChain[i]) + certificateChainObj[i + 1] = parseCertificate(certificateChain[i]); } return parsePrivateKey(privateKey).then(privateKeyDecoded => { - return signEmailObjects(mime, signingCertObj, certificateChainObj, privateKeyDecoded); + return signEmailObjects( + mime, + signingCertObj, + certificateChainObj, + privateKeyDecoded + ); }); } function signEmailObjects(mime, signingCert, certificateChain, privateKey) { - //region Get a "crypto" extension const crypto = pkijs.getCrypto(); if (typeof crypto === "undefined") { @@ -678,8 +765,7 @@ function signEmailObjects(mime, signingCert, certificateChain, privateKey) { } //endregion Get a "crypto" extension - let template = - `{{headers}}Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="{{boundary}}" + let template = `{{headers}}Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="{{boundary}}" MIME-Version: 1.0 This is a cryptographically signed message in MIME format. @@ -696,7 +782,7 @@ Content-Description: S/MIME Cryptographic Signature --{{boundary}}-- Vereign - Authentic Communication -`.replace(newline, '\r\n'); +`.replace(newline, "\r\n"); const detachedSignature = true; const addExt = true; @@ -713,18 +799,14 @@ Vereign - Authentic Communication "Content-Location" ]; - mime = mime.replace(newline, '\r\n'); + mime = mime.replace(newline, "\r\n"); let newHeaderLines = ""; - let headersEnd = mime.indexOf('\r\n\r\n'); //the first empty line - - if (headersEnd < 0 && mime.startsWith('\r\n')) { - - mime = mime.substring(2) //should not happen - - } else - if (headersEnd >= 0) { + let headersEnd = mime.indexOf("\r\n\r\n"); //the first empty line + if (headersEnd < 0 && mime.startsWith("\r\n")) { + mime = mime.substring(2); //should not happen + } else if (headersEnd >= 0) { let mimeHeaders = {}; let mimeBody = mime.substring(headersEnd + 4); @@ -733,51 +815,50 @@ Vereign - Authentic Communication let headers = libmime.decodeHeaders(mimeHeadersStr); for (var i = 0; i < mimeHeadersTitles.length; i++) { let key = mimeHeadersTitles[i].toLowerCase(); - if(key in headers) { + if (key in headers) { mimeHeaders[key] = headers[key]; - delete headers[key] + delete headers[key]; } } - for(let key in headers) { - if(!(key === "" || key === "MIME-Version".toLowerCase())) { //we have MIME-Version in the template - newHeaderLines += capitalizeHeader(key) + ": " + headers[key] + '\r\n'; + for (let key in headers) { + if (!(key === "" || key === "MIME-Version".toLowerCase())) { + //we have MIME-Version in the template + newHeaderLines += capitalizeHeader(key) + ": " + headers[key] + "\r\n"; } } let newMimeHeaderLines = ""; - for(let key in mimeHeaders) { - if(!(key === "")) { - newMimeHeaderLines += capitalizeHeader(key) + ": " + mimeHeaders[key] + '\r\n'; + for (let key in mimeHeaders) { + if (!(key === "")) { + newMimeHeaderLines += + capitalizeHeader(key) + ": " + mimeHeaders[key] + "\r\n"; } } if (newMimeHeaderLines === "") { - newMimeHeaderLines = 'Content-Type: text/plain\r\n' //should not happen + newMimeHeaderLines = "Content-Type: text/plain\r\n"; //should not happen } - mime = newMimeHeaderLines + '\r\n' + mimeBody + mime = newMimeHeaderLines + "\r\n" + mimeBody; } - let dataBuffer = Buffer.from(mime,'utf-8'); + let dataBuffer = Buffer.from(mime, "utf-8"); let sequence = Promise.resolve(); //region Check if user wants us to include signed extensions - if(addExt) - { + if (addExt) { //region Create a message digest - sequence = sequence.then( - () => crypto.digest({ name: hashAlg }, dataBuffer) + sequence = sequence.then(() => + crypto.digest({ name: hashAlg }, dataBuffer) ); //endregion //region Combine all signed extensions - sequence = sequence.then( - messageHash => - { - const signedAttr = []; - /* + sequence = sequence.then(messageHash => { + const signedAttr = []; + /* 1.2.840.113549.1.9.1 - e-mailAddress 1.2.840.113549.1.9.2 - PKCS-9 unstructuredName 1.2.840.113549.1.9.3 - contentType @@ -785,10 +866,11 @@ Vereign - Authentic Communication 1.2.840.113549.1.9.5 - Signing Time 1.2.840.113549.1.9.6 - counterSignature */ - signedAttr.push(new pkijs.Attribute({ + signedAttr.push( + new pkijs.Attribute({ type: OID_PKCS9_ContentType, //contentType values: [ - new asn1js.ObjectIdentifier({ value: OID_PKCS7_Data}) //data + new asn1js.ObjectIdentifier({ value: OID_PKCS7_Data }) //data ] /* 1.2.840.113549.1.7.1 - data @@ -798,78 +880,74 @@ Vereign - Authentic Communication 1.2.840.113549.1.7.5 - digestedData 1.2.840.113549.1.7.6 - encryptedData */ - })); // contentType + }) + ); // contentType - signedAttr.push(new pkijs.Attribute({ + signedAttr.push( + new pkijs.Attribute({ type: OID_PKCS9_SigningTime, //Signing Time - values: [ - new asn1js.UTCTime({ valueDate: new Date() }) - ] - })); // signingTime + values: [new asn1js.UTCTime({ valueDate: new Date() })] + }) + ); // signingTime - signedAttr.push(new pkijs.Attribute({ + signedAttr.push( + new pkijs.Attribute({ type: OID_PKCS9_MessageDigest, //messageDigest - values: [ - new asn1js.OctetString({ valueHex: messageHash }) - ] - })); // messageDigest + values: [new asn1js.OctetString({ valueHex: messageHash })] + }) + ); // messageDigest - return signedAttr; - } - ); + return signedAttr; + }); //endregion } //endregion //region Initialize CMS Signed Data structures and sign it - sequence = sequence.then( - signedAttr => - { - cmsSignedSimpl = new pkijs.SignedData({ - version: 1, - encapContentInfo: new pkijs.EncapsulatedContentInfo({ - eContentType: OID_PKCS7_Data // "data" content type - }), - signerInfos: [ - new pkijs.SignerInfo({ - version: 1, - sid: new pkijs.IssuerAndSerialNumber({ - issuer: signingCert.issuer, - serialNumber: signingCert.serialNumber - }) + sequence = sequence.then(signedAttr => { + cmsSignedSimpl = new pkijs.SignedData({ + version: 1, + encapContentInfo: new pkijs.EncapsulatedContentInfo({ + eContentType: OID_PKCS7_Data // "data" content type + }), + signerInfos: [ + new pkijs.SignerInfo({ + version: 1, + sid: new pkijs.IssuerAndSerialNumber({ + issuer: signingCert.issuer, + serialNumber: signingCert.serialNumber }) - ], - certificates: certificateChain //array - }); + }) + ], + certificates: certificateChain //array + }); - if(addExt) - { - cmsSignedSimpl.signerInfos[0].signedAttrs = new pkijs.SignedAndUnsignedAttributes({ + if (addExt) { + cmsSignedSimpl.signerInfos[0].signedAttrs = new pkijs.SignedAndUnsignedAttributes( + { type: 0, attributes: signedAttr - }); - } + } + ); + } - if(detachedSignature === false) - { - const contentInfo = new pkijs.EncapsulatedContentInfo({ - eContent: new asn1js.OctetString({ valueHex: dataBuffer }) - }); + if (detachedSignature === false) { + const contentInfo = new pkijs.EncapsulatedContentInfo({ + eContent: new asn1js.OctetString({ valueHex: dataBuffer }) + }); - cmsSignedSimpl.encapContentInfo.eContent = contentInfo.eContent; + cmsSignedSimpl.encapContentInfo.eContent = contentInfo.eContent; - return cmsSignedSimpl.sign(privateKey, 0, hashAlg); - } - - return cmsSignedSimpl.sign(privateKey, 0, hashAlg, dataBuffer); + return cmsSignedSimpl.sign(privateKey, 0, hashAlg); } - ); + + return cmsSignedSimpl.sign(privateKey, 0, hashAlg, dataBuffer); + }); //endregion //region Create final result sequence = sequence.then( - (result) => - { + result => { const cmsSignedSchema = cmsSignedSimpl.toSchema(true); const cmsContentSimp = new pkijs.ContentInfo({ @@ -888,8 +966,7 @@ Vereign - Authentic Communication const block2 = block1.valueBlock.value[0]; block2.lenBlock.isIndefiniteForm = true; - if(detachedSignature === false) - { + if (detachedSignature === false) { const block3 = block2.valueBlock.value[2]; block3.lenBlock.isIndefiniteForm = true; block3.valueBlock.value[1].lenBlock.isIndefiniteForm = true; @@ -904,34 +981,30 @@ Vereign - Authentic Communication ); //endregion - sequence = sequence.then( - (cmsSignedBuffer) => - { - let signature = arrayBufferToBase64Formatted(cmsSignedBuffer); - let boundary = makeBoundary(); + sequence = sequence.then(cmsSignedBuffer => { + let signature = arrayBufferToBase64Formatted(cmsSignedBuffer); + let boundary = makeBoundary(); - template = template.replace(/{{boundary}}/g, boundary); - template = template.replace("{{signature}}", signature); - template = template.replace("{{headers}}", newHeaderLines); - template = template.replace("{{mime}}", mime); + template = template.replace(/{{boundary}}/g, boundary); + template = template.replace("{{signature}}", signature); + template = template.replace("{{headers}}", newHeaderLines); + template = template.replace("{{mime}}", mime); - //template = template.replace(newline, '\r\n') - return template - } - ); + //template = template.replace(newline, '\r\n') + return template; + }); return sequence; } - const newline = /\r\n|\r|\n/g; function capitalizeFirstLetter(string) { - if(string === "id") { - return "ID" + if (string === "id") { + return "ID"; } - if(string === "mime") { + if (string === "mime") { return "MIME"; } @@ -951,11 +1024,9 @@ function capitalizeHeader(string) { return result; } - - function makeBoundary() { let len = 20 + Math.random() * 20; - return 'W0RyLiBEYW15YW4gTWl0ZXZd--' + makeid(len) + return "W0RyLiBEYW15YW4gTWl0ZXZd--" + makeid(len); } export const parseCertificates = signatureBase64 => { @@ -1027,7 +1098,9 @@ export const getCertificateChain = signatureBase64 => { // Go through all certificates to build a chain from first certificate to the root certificates.forEach(certificate => { - if (certificateChain[0].issuer.commonName === certificate.subject.commonName) { + if ( + certificateChain[0].issuer.commonName === certificate.subject.commonName + ) { certificateChain.unshift(certificate); } }); diff --git a/javascript/src/viamapi-client.js b/javascript/src/viamapi-client.js index 1fa645e73df4f0d1b9dd40e43050508df6b446a8..9c6e9cafe3a7d9d0c02cd1edee002f863589e2ce 100644 --- a/javascript/src/viamapi-client.js +++ b/javascript/src/viamapi-client.js @@ -1,4 +1,4 @@ -const Penpal = require('penpal').default; +const Penpal = require("penpal").default; /** * Sets up interaction with Vereign Restful API @@ -9,7 +9,14 @@ const Penpal = require('penpal').default; * @param wopiUrl - WOPI URL used to acces WopiAPI * @returns {*} */ -function setupViamAPI(divId, methods, iframeUrl, apiUrl, wopiUrl, collaboraUrl) { +function setupViamAPI( + divId, + methods, + iframeUrl, + apiUrl, + wopiUrl, + collaboraUrl +) { if (!iframeUrl) { iframeUrl = `${window.location.origin}/vcl/js/iframe`; console.warn(`Iframe URL not specified. Fall back to ${iframeUrl}`); // eslint-disable-line no-console @@ -24,9 +31,9 @@ function setupViamAPI(divId, methods, iframeUrl, apiUrl, wopiUrl, collaboraUrl) methods }); - return connection.promise - .then((child) => child.initialize(apiUrl, wopiUrl, collaboraUrl).then(() => child)); + return connection.promise.then(child => + child.initialize(apiUrl, wopiUrl, collaboraUrl).then(() => child) + ); } window.setupViamAPI = setupViamAPI; -