Newer
Older
import { parseSMIME } from '../utilities/emailUtilities';
const QRCode = require('qrcode');
const Penpal = require('penpal').default;
Markin Igor
committed
import {
createDeviceHash,
destroyIdentityFromLocalStorage,
encodeResponse,
listIdentitiesFromLocalStorage, makeid
} from '../utilities/appUtility';
import {LOGIN_MODES} from '../constants/authentication';
import {
createOneTimePassportCertificate,
createPassportCertificate,
decryptMessage,
encryptMessage, signEmail
} from '../utilities/signingUtilities';
import {
signPdf
} from '../utilities/pdfUtilities';
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");
return color
}
function setKeyForUUID(uuid, key) {
var storedIdentityForUuid = localStorage.getItem("keyperuuid/" + uuid);
if(storedIdentityForUuid !== key && storedIdentityForUuid != null && storedIdentityForUuid !== "") {
destroyIdentityFromLocalStorage(storedIdentityForUuid)
}
localStorage.setItem("keyperuuid/" + uuid, key)
}
function getColorForIdentity(key) {
var storedColor = localStorage.getItem("colors/" + key);
localStorage.setItem("colors/" + key, storedColor)
}
return storedColor
}
function setIdentityInLocalStorage(identityToStore, extendKey = true) {
var pinCode = identityToStore.pinCode;
const serializedIdentity = JSON.stringify(identityToStore);
const key = identityToStore.authentication.publicKey;
return null;
}
return encryptMessage(serializedIdentity, pinCode, "identity").then((encryptedIdentity) => {
if(extendKey === true) {
success = extendPinCodeTtl(key, pinCode)
}
localStorage.setItem(key, encryptedIdentity);
let serializedIdentitiesList = localStorage.getItem("identities");
let identities = JSON.parse(serializedIdentitiesList);
identities[key] = true;
localStorage.setItem("identities", JSON.stringify(identities))
} else {
}
});
}
function getProfileData(identity) {
return new Penpal.Promise(executeResultUpper => {
executeRestfulFunction("private", viamApi,
viamApi.identityGetIdentityProfileData, null).then(executeResult => {
listItem.identityColor = getColorForIdentity(identity.authentication.publicKey);
listItem.initials = executeResult.data.initials;
if(listItem.initials === null || listItem.initials === "") {
listItem.initials = "JD";
}
localStorage.setItem("profiles/" + identity.authentication.publicKey, JSON.stringify(listItem));
executeResultUpper(listItem)
} else {
executeResultUpper({})
}
});
});
}
async function getIdentityFromLocalStorage(key, pinCode, extendTtl = true) {
const encryptedIdentity = localStorage.getItem(key);
if (!encryptedIdentity) {
const serializedIdentity = await decryptMessage(encryptedIdentity, pinCode);
const identity = new Identity(serializedIdentity);
if (extendTtl) {
const success = extendPinCodeTtl(key, pinCode);
if (!success) {
console.log("Can not extend pincode ttl");
return null;
}
}
return identity;
}
function extendPinCodeTtl(key, 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)) {
return false
} else {
var ttl = now.getTime() + 4 * 60 * 60 * 1000;
window.sessionStorage.setItem("pincodettls/" + key, ttl);
}
} else {
var now = new Date();
var ttl = now.getTime() + 4 * 60 * 60 * 1000;
window.sessionStorage.setItem("pincodettls/" + key, ttl);
window.sessionStorage.setItem("pincodes/" + key, pinCode);
}
return true;
}
window.extendPinCodeTtl = extendPinCodeTtl;
window.sessionStorage.removeItem("pincodettls/" + key);
window.sessionStorage.removeItem("pincodes/" + key)
}
function getPincode(key) {
var now = new Date();
var nowMillis = now.getTime();
var ttl = window.sessionStorage.getItem("pincodettls/" + key);
return null
} else {
if(nowMillis >= parseInt(ttl)) {
return null
} else {
return window.sessionStorage.getItem("pincodes/" + key);
}
}
}
function createEvent(actionId, type, payloads) {
return {
"actionID": actionId,
"type": type,
"stamp": new Date().getTime(),
"payloads" : payloads
}
}
const destroyAuthentication = () => {
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
window.viamApi.setIdentity("");
window.viamApi.setSessionData("", "");
clearPinCodeTtl(authenticationPublicKey);
localStorage.removeItem("uuid");
localStorage.removeItem("token");
localStorage.removeItem("authenticatedIdentity");
window.currentlyAuthenticatedIdentity = null;
window.lastTimeGetProfile = 0;
};
const destroyIdentity = () => {
destroyAuthentication();
if (window.currentlyLoadedIdentity) {
const { publicKey } = window.currentlyLoadedIdentity.authentication;
delete window.loadedIdentities[publicKey];
window.currentlyLoadedIdentity = null;
destroyIdentityFromLocalStorage(publicKey);
}
};
window.wopiAPI = new WopiAPI();
window.collaboraApi = new CollaboraAPI();
window.viamApi = new ViamAPI();
window.viamAnonymousApi = new ViamAPI();
window.currentlyAuthenticatedIdentity = null;
window.currentlyLoadedIdentity = null;
window.lastTimeGetProfile = 0;
const handleIdentityLogin = (identity, uuid, token) => {
const { loadedIdentities, viamApi } = window;
const { publicKey } = identity.authentication;
viamApi.setSessionData(uuid, token);
localStorage.setItem("uuid", uuid);
localStorage.setItem("token", token);
localStorage.setItem("authenticatedIdentity", publicKey);
window.currentlyAuthenticatedIdentity = loadedIdentities[publicKey];
window.lastTimeGetProfile = 0;
setKeyForUUID(uuid, publicKey);

Alexey Lunin
committed
async function executeRestfulFunction(type, that, fn, config, ...args) {
const { currentlyAuthenticatedIdentity, viamApi, currentlyLoadedIdentity } = window;

Alexey Lunin
committed
const response = await fn.apply(that, [config, ...args]);
const identity = currentlyAuthenticatedIdentity || currentlyLoadedIdentity;

Alexey Lunin
committed
const { code, status } = response.data;

Alexey Lunin
committed
const deviceRevoked = type === "private" && code === "401" && status === STATUS_DEVICE_REVOKED;
if (deviceRevoked) {
destroyIdentity();

Alexey Lunin
committed
const event = createEvent("", "DeviceRevoked");
iframeParent.onEvent(event);

Alexey Lunin
committed
return response.data;
}

Alexey Lunin
committed
const badSession = type === "private" && identity && code === "400" && status === "Bad session";
if (!badSession) return response.data;
const loginResponse = await viamApi.identityLogin(null, "previousaddeddevice");
if (loginResponse.data.code !== "200") return loginResponse.data;
const uuid = loginResponse.data.data["Uuid"];
const token = loginResponse.data.data["Session"];
handleIdentityLogin(identity, uuid, token);

Alexey Lunin
committed
const { data } = await fn.apply(that, [config, ...args]);
}
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."
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);
const { publicKey, x509Certificate } = loadedIdentity.authentication;
"data": {
authentication: {
publicKey,
x509Certificate
}
},
"code": "200",
"status": "Identity loaded"
}).catch((e) => {
result({
"data": "",
"code": "400",
});
}
function getCertificateForPassport(passportUUID, internal) {
return new Penpal.Promise(certificateResult => {
if (window.currentlyAuthenticatedIdentity === null) {
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){
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 => {
var signedCertificate = atob(executeResult.data["SignedCertificate"]);
//download("passportCertificateAfterSigning.crt", "text/plain", signedCertificate)
var keyUUID = executeResult.data["CertificateUUID"];
var encodedChain = executeResult.data["Chain"];
//download("rootCertificate.crt", "text/plain", atob(encodedChain[0]))
for(var i = 0; i < encodedChain.length; i++) {
chain.push(atob(encodedChain[i]))
}
cryptoData.setx509Certificate(signedCertificate);
cryptoData.setKeyUUID(keyUUID);
cryptoData.setChain(chain);
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));
copyOfCryptoData["privateKey"] = "";
}
certificateResult({
"data": copyOfCryptoData,
"code": "200",
"status": "Certificate got"
});
}).catch((e) => {
certificateResult({
"data": "",
"code": "400",
"status": "Can not store certificate " + e
});
});
});
} else {
certificateResult(executeResult);
var copyOfCryptoData = JSON.parse(JSON.stringify(passport));
if(internal === false) {
copyOfCryptoData["privateKey"] = ""
}
certificateResult({"data" : copyOfCryptoData,
"code" : "200",
"status" : "Certificate got"
});
}
});
}
const connection = Penpal.connectToParent({
// Methods child is exposing to parent
methods: {
initialize: (apiUrl, wopiUrl, collaboraUrl) => {
Alexey Lunin
committed
if (!apiUrl) {
apiUrl = `${window.location.origin}/api/`;
console.warn(`API host URL not specified. Fall back to ${apiUrl}`); // eslint-disable-line no-console
}
if (!wopiUrl) {
wopiUrl = `${window.location.origin}/wopi/`;
console.warn(`WOPI host URL not specified. Fall back to ${wopiUrl}`); // eslint-disable-line no-console
}
if (!collaboraUrl) {
collaboraUrl = window.location.origin;
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 + "/";
...penpalMethods,
createIdentity(pinCode) {
return new Penpal.Promise(result => {
createPassportCertificate(makeid()).then(function(keys){
var newIdentity = new Identity();
var cryptoData = new CryptoData();
cryptoData.setPublicKey(keys["publicKeyPEM"]);
cryptoData.setPrivateKey(keys["privateKeyPEM"]);
cryptoData.setx509Certificate(keys["certificatePEM"]);
newIdentity.setAuthentication(cryptoData);
newIdentity.setPinCode(pinCode);
window.currentlyLoadedIdentity = newIdentity;
window.loadedIdentities[newIdentity.authentication.publicKey] = newIdentity;
extendPinCodeTtl(newIdentity.authentication.publicKey, pinCode);
window.viamAnonymousApi.setIdentity(newIdentity.authentication.publicKey);
result({"data" : newIdentity,
"code" : "200",
"status" : "Identity created"
})
})
},
listIdentities() {
return new Penpal.Promise(result => {
result({"data" : identities,
"code" : "200",
"status" : "Identities listed"
})
});
},
loadIdentity(identityKey, pinCode) {
return loadIdentityInternal(identityKey, pinCode)
},
checkIdentityPinCode: async (key, pinCode) => {
try {
const identity = await getIdentityFromLocalStorage(key, pinCode, false);
if (identity) {
return encodeResponse("200", null, "Pincode check successful");
} else {
return encodeResponse("400", null, "Pincode check failed");
}
} catch (e) {
return encodeResponse("400", e, "Pincode check error");
}
},
changeIdentityPinCode: async (key, oldPinCode, newPinCode) => {
try {
const identity = await getIdentityFromLocalStorage(key, oldPinCode, false);
if (identity) {
identity.pinCode = newPinCode;
await setIdentityInLocalStorage(identity);
return encodeResponse("200", null, "Successfully changed pincode");
} else {
return encodeResponse("400", null, "Identity not found");
}
} catch (e) {
return encodeResponse("400", e.message, "Change pincode error");
},
getIdentityProfile(identityKey) {
return new Penpal.Promise(result => {
const serializedProfile = localStorage.getItem("profiles/" + identityKey);
if (serializedProfile === null || serializedProfile === "") {
result({"data" : "",
"code" : "400",
"status" : "Profile is empty"
});
} else {
result({"data" : JSON.parse(serializedProfile),
"code" : "200",
"status" : "Identities cleared"
})
}
});
},
clearIdentities: async () => {
destroyAuthentication();
const identitiesTemp = listIdentitiesFromLocalStorage();
for (const i in identitiesTemp) {
destroyIdentityFromLocalStorage(i);
}
return encodeResponse("200", "", "Identities cleared");
confirmIdentificator(identity, confirmationCodeArg) {
return new Penpal.Promise(result => {
viamApi.setIdentity(identity.authentication.publicKey);
executeRestfulFunction("public", viamApi, viamApi.identityConfirmIdentificator, null, confirmationCodeArg).then(executeResult => {
result(executeResult);
});
});
},
identityGetIdentificatorByRegisterToken(identity, tokenArg) {
return new Penpal.Promise(result => {
viamApi.setIdentity(identity.authentication.publicKey);
executeRestfulFunction("public", viamApi, viamApi.identityGetIdentificatorByRegisterToken, null, tokenArg).then(executeResult => {
result(executeResult);
});
});
},
submitIdentificator(identity, identificatorArg, registerToken) {
return new Penpal.Promise(result => {
viamApi.setIdentity(identity.authentication.publicKey);
executeRestfulFunction("public", viamApi, viamApi.identitySubmitIdentificator, null, identificatorArg, registerToken).then(executeResult => {
result(executeResult);
});
});
},
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 => {
result(executeResult);
});
});
},
agreeOnRegistration(registerIdentity) {
viamApi.setIdentity(registerIdentity.authentication.publicKey);
executeRestfulFunction("public", viamApi, viamApi.identityAgreeOnRegistration, null).then(executeResult => {
if (executeResult.code === "200") {
sequence = sequence.then(() => {
setIdentityInLocalStorage(registerIdentity)
}
)
}
sequence.then(() => {
result(executeResult);
}).catch((e) => {
result({
"data": "",
"code": "400",
"status": "Can not store identity: " + e
})
})
});
});
},
resendConfirmationCode(identity, identificatorArg) {
return new Penpal.Promise(result => {
viamApi.setIdentity(identity.authentication.publicKey);
executeRestfulFunction("public", viamApi, viamApi.identityResendConfirmationCode, null, identificatorArg).then(executeResult => {
result(executeResult);
});
});
},
login: async (loginIdentity, mode, requestCode, requestActionID) => {
if (!window.loadedIdentities[loginIdentity.authentication.publicKey]) {
return {
data: "",
code: "400",
status: "Identity not loaded"
};
}
const deviceHash = await createDeviceHash(loginIdentity.authentication.publicKey);
window.viamApi.setSessionData("", "");
window.viamApi.setIdentity(loginIdentity.authentication.publicKey);
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) {
handleIdentityLogin(loginIdentity, data.Uuid, data.Session);
if (mode === LOGIN_MODES.SMS) {
} else if (mode === LOGIN_MODES.NEW_DEVICE) {
const dataUrl = await QRCode.toDataURL(`${data.ActionID},${data.QrCode}`);
Object.assign(responseToClient.data, { image: dataUrl });
}
}
return responseToClient;
},
identityAddNewDevice() {
return new Penpal.Promise(result => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (authenticationPublicKey === null) {
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
if (window.loadedIdentities[authenticationPublicKey] === null) {
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
var success = extendPinCodeTtl(authenticationPublicKey);
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
executeRestfulFunction("private", viamApi, viamApi.identityAddNewDevice, null).then(executeResult => {
var actionID = executeResult.data["ActionID"];
var QrCode = executeResult.data["QrCode"];
QRCode.toDataURL(actionID + "," + QrCode, function (err, url) {
result(executeResult);
})
} else {
result(executeResult);
}
});
});
},
identityDestroyKeysForDevice(authenticationPublicKeyArg) {
return new Penpal.Promise(result => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (authenticationPublicKey === null) {
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
if (window.loadedIdentities[authenticationPublicKey] === null) {
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
var success = extendPinCodeTtl(authenticationPublicKey);
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
executeRestfulFunction("private", viamApi, viamApi.identityDestroyKeysForDevice, null, btoa(authenticationPublicKeyArg)).then(executeResult => {
result(executeResult);
});
});
},
try {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (!authenticationPublicKey || !window.loadedIdentities[authenticationPublicKey]) {
return {
data: "",
code: "400",
status: "Identity not loaded"
};
}
// 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};
destroyAuthentication();
"private",
window.viamApi,
window.viamApi.identityLogout,
}
},
identityRestoreAccess(restoreAccessIdentity, identificator) {
return new Penpal.Promise(result => {
viamApi.setSessionData("", "");
viamApi.setIdentity(restoreAccessIdentity.authentication.publicKey);
executeRestfulFunction("public", viamApi, viamApi.identityRestoreAccess, null, identificator).then(executeResult => {
result(executeResult);
});
});
},
getCurrentlyLoggedInUUID() {
return new Penpal.Promise(result => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (authenticationPublicKey === null) {
return {"data" : "",
"code" : "400",
"status" : "Identity not loaded"
}
}
if (window.loadedIdentities[authenticationPublicKey] === null) {
return {"data" : "",
"code" : "400",
"status" : "Identity not loaded"
}
}
var success = extendPinCodeTtl(authenticationPublicKey);
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
if(localStorage.getItem("uuid") === null) {
result({"data" : "",
"code" : "400",
"status" : "Not logged in UUID"
})
}
result({"data" : localStorage.getItem("uuid"),
"code" : "200",
"status" : "UUID loaded"
})
});
},
getCertificateByPassport(passportUUID) {
return new Penpal.Promise(result => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (authenticationPublicKey === null) {
return {"data" : "",
"code" : "400",
"status" : "Identity not loaded"
}
}
if (window.loadedIdentities[authenticationPublicKey] === null) {
return {"data" : "",
"code" : "400",
"status" : "Identity not loaded"
}
}
var success = extendPinCodeTtl(authenticationPublicKey);
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
getCertificateForPassport(passportUUID, false).then(certificateResult => {
result(certificateResult)
})
});
},
getOneTimeCertificateByPassport(passportUUID, emailArg) {
return new Penpal.Promise(result => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (authenticationPublicKey === null) {
return {"data" : "",
"code" : "400",
"status" : "Identity not loaded"
}
}
if (window.loadedIdentities[authenticationPublicKey] === null) {
return {"data" : "",
"code" : "400",
"status" : "Identity not loaded"
}
}
var success = extendPinCodeTtl(authenticationPublicKey);
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
getCertificateForPassport(passportUUID, true).then(certificateResult => {
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");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
let response = await getCertificateForPassport(passportUUID, true);
if (response.code !== "200") {
return encodeResponse("400", "", response.status);
}
const {
x509Certificate: passportCertificate,
privateKey: passportPrivateKey,
chain: passportChain
} = response.data;
const keys =
await createOneTimePassportCertificate(
makeid() + "-" + passportUUID, emailArg, passportPrivateKey, passportCertificate);
const { privateKeyPEM: privateKeyOneTime, certificatePEM: certificateOneTime } = keys;
passportChain.push(passportCertificate);
response = await executeRestfulFunction(
"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);
response = await executeRestfulFunction(
"private", window.viamApi, window.viamApi.signResignEmail, null, passportUUID, signedEmail);
if (response.code !== "200") {
return encodeResponse("400", "", response.status);
}
return encodeResponse("200", response.data, "Email signed");
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
signPdf: async (passportUUID, pdfRaw /*array buffer*/) => {
//TODO api is not finished
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
let response = await getCertificateForPassport(passportUUID, true);
if (response.code !== "200") {
return encodeResponse("400", "", response.status);
}
const {
x509Certificate: passportCertificate,
privateKey: passportPrivateKey,
chain: passportChain
} = response.data;
const keys =
await createOneTimePassportCertificate(
makeid() + "-" + passportUUID, null, passportPrivateKey, passportCertificate);
const { privateKeyPEM: privateKeyOneTime, certificatePEM: certificateOneTime } = keys;
passportChain.push(passportCertificate);
const signedPdf = await signPdf(pdfRaw, certificateOneTime, passportChain, privateKeyOneTime);
//for test
response.data.signedPdf = signedPdf;
//for test
// response = await executeRestfulFunction(
// "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);
//
// response = await executeRestfulFunction(
// "private", window.viamApi, window.viamApi.signResignEmail, null, passportUUID, signedEmail);
//
// if (response.code !== "200") {
// return encodeResponse("400", "", response.status);
// }
return encodeResponse("200", response.data, "PDF signed");
},
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
signDocument: async (passportUUID, documentUUID, documentContentType) => {
//TODO api is not finished
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const response = await getCertificateForPassport(passportUUID, true);
if (response.code !== "200") {
return encodeResponse("400", "", response.status);
}
const {
x509Certificate: passportCertificate,
privateKey: passportPrivateKey,
chain: passportChain
} = response.data;
const keys =
await createOneTimePassportCertificate(
makeid() + "-" + passportUUID, null, passportPrivateKey, passportCertificate);
const { privateKeyPEM: privateKeyOneTime, certificatePEM: certificateOneTime } = keys;
passportChain.push(passportCertificate);
const pdfContentType = 'application/pdf';
if (documentContentType !== pdfContentType) {
const convResponse = await executeRestfulFunction(
"private", window.viamApi, window.viamApi.documentConvertDocumentByUUID, null, documentUUID, documentContentType, pdfContentType);
if (convResponse.code !== "200") {
return encodeResponse("400", "", convResponse.status);
}
}
const downloadResponse = await executeRestfulFunction(
"private", window.viamApi, window.viamApi.documentGetDocumentByUUID, null, documentUUID, pdfContentType)
if (downloadResponse.code !== "200") {
return encodeResponse("400", "", downloadResponse.status);
}
let pdfRaw = this.base64ToByteArray(downloadResponse.data);
const signedPdf = await signPdf(pdfRaw, certificateOneTime, passportChain, privateKeyOneTime);
//for test
response.data.signedPdf = signedPdf;
//for test
// response = await executeRestfulFunction(
// "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);
//
// response = await executeRestfulFunction(
// "private", window.viamApi, window.viamApi.signResignEmail, null, passportUUID, signedEmail);
//
// if (response.code !== "200") {
// return encodeResponse("400", "", response.status);
// }
return encodeResponse("200", response.data, "PDF signed");
},
documentCreateDocument: async (path, passportUUID, contenttype) => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const config = {
headers: {
path,
passportuuid: passportUUID,
contenttype
}
};
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");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const config = {
headers: {
'Content-Type': 'multipart/form-data',
passportuuid: passportUUID,
resourceid
}
};
const response = await executeRestfulFunction(
"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");
if (authenticationPublicKey === null) {
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
});
}
if (window.loadedIdentities[authenticationPublicKey] === null) {
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
});
}
var success = extendPinCodeTtl(authenticationPublicKey);
result({"data" : "",
"code" : "400",
"status" : "Identity not authenticated"
})
}
executeRestfulFunction("private", viamApi, viamApi.identityHasSession, null).then(executeResult => {
result(executeResult);
});
});
},
marketingSignUpIdentificator(identificator, reference) {
return new Penpal.Promise(result => {
executeRestfulFunction("public", viamApi, viamApi.marketingSignUpIdentificator, null, identificator, reference).then(executeResult => {
result(executeResult);
});
});
},
marketingGetIdentificatorProfile(identificator, pincode) {
return new Penpal.Promise(result => {
executeRestfulFunction("public", viamApi, viamApi.marketingGetIdentificatorProfile, null, identificator, pincode).then(executeResult => {
result(executeResult);
});
});
},
marketingExecuteEventForIdentificator(identificator, pincode, event) {
executeRestfulFunction("public", viamApi, viamApi.marketingExecuteEventForIdentificator, null, identificator, pincode, event).then(executeResult => {
result(executeResult);
});
});
},
getCurrentlyAuthenticatedIdentity() {
const { publicKey, x509Certificate } = window.currentlyAuthenticatedIdentity.authentication;
return encodeResponse(
"200",
{
authentication: {
publicKey,
x509Certificate
}
},
"Currently authenticated identity"
);
stringToUtf8ByteArray(str) {
if (typeof str !== 'string') {
str = str.toString()
}
return new Penpal.Promise(result => {
result(res)
})
},
utf8ByteArrayToString(ba) {
if (!Buffer.isBuffer(ba)) {
ba = Buffer.from(ba)
}
return new Penpal.Promise(result => {
result(res)
})
},
stringToUtf8Base64(str) {
if (!Buffer.isBuffer(str)) {
if (typeof str !== 'string') {
str = str.toString()
}
str = Buffer.from(str, 'utf-8')
}
return new Penpal.Promise(result => {
result(res)
})
},
utf8Base64ToString(strBase64) {
if (!Buffer.isBuffer(strBase64)) {
if (typeof strBase64 !== 'string') {
strBase64 = strBase64.toString()
}
strBase64 = Buffer.from(strBase64, 'base64')
}
return new Penpal.Promise(result => {
result(res)
})
},
base64ToByteArray(strBase64) {
if (typeof strBase64 !== 'string') {
strBase64 = strBase64.toString()
}
return new Penpal.Promise(result => {
result(res)
})
},
byteArrayToBase64(ba) {
if (!Buffer.isBuffer(ba)) {
ba = Buffer.from(ba)
}
return new Penpal.Promise(result => {
result(res)
})
},
return collaboraApi.discovery().then(apps => apps);
getPassports: async fileId => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const response = await wopiAPI.getPassports(fileId);
return response.data;
wopiPutFile: async (path, accessToken, file) => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const response = await wopiAPI.putDocument(path, accessToken, file);
connection.promise.then(parent => {
if (!navigator.cookieEnabled) {
console.warn("Cookie disabled. Can't start library.");
return;
}
window.addEventListener('storage', event => {
if (event.key === "authenticatedIdentity" && event.newValue === null) {
const publicKey = window.currentlyAuthenticatedIdentity.authentication.publicKey;
window.currentlyLoadedIdentity = null;
window.currentlyAuthenticatedIdentity = null;
const event = createEvent("LogoutFromAnotherTab", "Logout", [publicKey]);
parent.onEvent(event);
}
});
const identities = localStorage.getItem("identities");
console.log("Library loaded at: " + new Date().toISOString());
if (identities === "" || identities === null) {
localStorage.setItem("identities", JSON.stringify({}));
if (
localStorage.getItem("uuid") === null ||
localStorage.getItem("token") === null ||
localStorage.getItem("authenticatedIdentity") === null
) {
const event = createEvent("", "NotAuthenticated");
parent.onEvent(event);
localStorage.removeItem("uuid");
localStorage.removeItem("token");
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
const pinCode = getPincode(authenticationPublicKey);
loadIdentityInternal(authenticationPublicKey, "00000000").then(result => {
if (result.code !== "200") {
const event = createEvent(
"CanNotGetPincodeForAuthenticatedIdentity",
"IdentityNotLoaded",
loadIdentityInternal(authenticationPublicKey, pinCode).then(result => {
if (result.code !== "200") {
const event = createEvent(
"CanNotLoadIdentity",
"ErrorDuringLoadingIdentity",
let anynomousDeviceKeyEventsProcessing = false;
let maxDeviceKeyAnonymousEventTime = 0;
let eventsDeviceEventsProcessing = false;
let maxDeviceKeyEventTime = 0;
let eventsEntityEventsProcessing = false;
let maxEntityEventTime = 0;
let identityLoadedEvent = false;
let identityAuthenticatedEvent = false;
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);
window.currentlyLoadedIdentity = identity;
if (!identityAuthenticatedEvent && identity) {
const event = createEvent("IdentityAuthenticated", "Authenticated", [identity.authentication.publicKey]);
parent.onEvent(event);
identityAuthenticatedEvent = true;
}
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (authenticationPublicKey) {
const result = await loadIdentityInternal(authenticationPublicKey, "00000000");
if (result.code !== "200") {
const event = createEvent("CanNotGetPincodeForAuthenticatedIdentity", "IdentityNotLoaded", [authenticationPublicKey]);
parent.onEvent(event);
clearPinCodeTtl(authenticationPublicKey);
window.currentlyAuthenticatedIdentity = null;
}
if (window.currentlyLoadedIdentity) {
const pinCode = getPincode(window.currentlyLoadedIdentity.authentication.publicKey);
if (!pinCode) {
if (!identityLoadedEvent) {
const result = await loadIdentityInternal(window.currentlyLoadedIdentity.authentication.publicKey, "00000000");

Alexey Lunin
committed
if (window.currentlyLoadedIdentity && result.code !== "200") {
const event = createEvent("CanNotLoadPincodeForLoadedIdentity", "IdentityNotLoaded", [window.currentlyLoadedIdentity.authentication.publicKey]);
parent.onEvent(event);
identityLoadedEvent = true;
}
if (window.currentlyAuthenticatedIdentity) {
const now = new Date().getTime();
if (now - window.lastTimeGetProfile > 30000) {
getProfileData(window.currentlyAuthenticatedIdentity);
const getNewEventsWithoutSession = async () => {
anynomousDeviceKeyEventsProcessing = true;
try {
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" : {
await setIdentityInLocalStorage(window.currentlyLoadedIdentity);
parent.onEvent(event);
break;
const actionID = event["actionID"];
const QrCode = event["payloads"][1];
const eventCopy = JSON.parse(JSON.stringify(event));
QRCode.toDataURL(actionID + "," + QrCode, function (err, url) {
parent.onEvent(eventCopy);
});
break;
}
case "KeyDeleted" : {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
clearPinCodeTtl(authenticationPublicKey);
localStorage.removeItem("uuid");
localStorage.removeItem("token");
localStorage.removeItem("authenticatedIdentity");
delete window.loadedIdentities[authenticationPublicKey];
window.currentlyLoadedIdentity = null;
window.currentlyAuthenticatedIdentity = null;
window.lastTimeGetProfile = 0;
destroyIdentityFromLocalStorage(authenticationPublicKey);
break;
}
default : {
parent.onEvent(event);
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
changedMaxDeviceKeyAnonymousEventTime = true;
maxDeviceKeyAnonymousEventTime = Math.max(maxDeviceKeyAnonymousEventTime, event.stamp);
}
if(changedMaxDeviceKeyAnonymousEventTime) {
await executeRestfulFunction("public", viamAnonymousApi, viamAnonymousApi.eventUpdateLastViewedWithoutSession,
null, "devicekey", maxDeviceKeyAnonymousEventTime.toString());
}
}
} catch (e) {
console.warn(e);
}
anynomousDeviceKeyEventsProcessing = false;
};
const getNewDeviceEvents = async () => {
eventsDeviceEventsProcessing = true;
try {
const executeResult = await executeRestfulFunction("private", viamApi, viamApi.eventGetNewEvents, null, "devicekey");
if (executeResult.code === "200") {
const eventsLen = executeResult.data.length;
const changedMaxDeviceKeyEventTime = false;
for (let i = 0; i < eventsLen; i++) {
const event = executeResult.data[i];
if (event.type === "QRCodeUpdated") {
const actionID = event["actionID"];
const QrCode = event["payloads"][1];
const eventCopy = JSON.parse(JSON.stringify(event));
QRCode.toDataURL(actionID + "," + QrCode, function (err, url) {
eventCopy["payloads"].push(url);
parent.onEvent(eventCopy);
});
} else {
parent.onEvent(event);
maxDeviceKeyEventTime = Math.max(maxDeviceKeyEventTime, event.stamp);
}
if(changedMaxDeviceKeyEventTime) {
await executeRestfulFunction("private", viamApi, viamApi.eventUpdateLastViewed, null, "devicekey",
maxDeviceKeyEventTime.toString());
} catch (e) {
console.warn(e);
eventsDeviceEventsProcessing = false;
};
const getNewEntityEvents = async () => {
eventsEntityEventsProcessing = true;
try {
const executeResult = await executeRestfulFunction("private", viamApi, viamApi.eventGetNewEvents, null, "entity");
if (executeResult.code === "200") {
const eventsLen = executeResult.data.length;
let changedMaxEntityEventTime = false;
for (let i = 0; i < eventsLen; i++) {
const event = executeResult.data[i];
if (event.type === "QRCodeUpdated") {
const actionID = event["actionID"];
const QrCode = event["payloads"][1];
const eventCopy = JSON.parse(JSON.stringify(event));
QRCode.toDataURL(actionID + "," + QrCode, function (err, url) {
eventCopy["payloads"].push(url);
parent.onEvent(eventCopy);
});
parent.onEvent(event);
changedMaxEntityEventTime = true;
maxEntityEventTime = Math.max(maxEntityEventTime, event.stamp);
}
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) {
getNewEventsWithoutSession();
}
if (window.currentlyAuthenticatedIdentity) {
// These functions has to be executed at the same time.
!eventsDeviceEventsProcessing && getNewDeviceEvents();
!eventsEntityEventsProcessing && getNewEntityEvents();
Loading
Loading full blame...