Newer
Older
import {
parseSMIME,
prepareVCardParts
} from "../utilities/emailUtilities";
import {
stringToUtf8ByteArray,
utf8ByteArrayToString,
stringToUtf8Base64,
utf8Base64ToString,
base64ToByteArray,
byteArrayToBase64
import { extractMessageID } from "../helpers/mailparser";
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";
CertificateData,
createOneTimePassportCertificate,
createPassportCertificate,
decryptMessage,
encryptMessage, parseCertificate,
} from "../utilities/signingUtilities";
import { signPdf } from "../utilities/pdfUtilities";
import CryptoData from "../CryptoData";
import Identity from "../Identity";
import { STATUS_DEVICE_REVOKED } from "../constants/statuses";
import generateQrCode from '../utilities/generateQrCode';
const penpalMethods = require("../../temp/penpal-methods").default;
const WopiAPI = require("./wopiapi-iframe");
const CollaboraAPI = require("./collaboraapi-iframe");
const ViamAPI = require("../../temp/viamapi");
let identityColors = ["#994392", "#cb0767", "#e51d31", "#ec671b", "#fab610"];
}
function setKeyForUUID(uuid, key) {
let storedIdentityForUuid = localStorage.getItem("keyperuuid/" + uuid);
if (
storedIdentityForUuid !== key &&
storedIdentityForUuid != null &&
storedIdentityForUuid !== ""
) {
destroyIdentityFromLocalStorage(storedIdentityForUuid);
}
function getColorForIdentity(key) {
let storedColor = localStorage.getItem("colors/" + key);
}
function setIdentityInLocalStorage(identityToStore, extendKey = true) {
const serializedIdentity = JSON.stringify(identityToStore);
const key = identityToStore.authentication.publicKey;
if (pinCode == null || pinCode === "") {
pinCode = getPincode(key);
return encryptMessage(serializedIdentity, pinCode, "identity").then(
encryptedIdentity => {
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");
}
}
function getProfileData(identity) {
return new Penpal.Promise(executeResultUpper => {
executeRestfulFunction(
"private",
viamApi,
viamApi.identityGetIdentityProfileData,
null
).then(executeResult => {
if (executeResult.code === "200") {
listItem.identityColor = getColorForIdentity(
identity.authentication.publicKey
);
localStorage.setItem(
"profiles/" + identity.authentication.publicKey,
JSON.stringify(listItem)
);
executeResultUpper(listItem);
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) {
let now = new Date();
let nowMillis = now.getTime();
let ttl = window.sessionStorage.getItem("pincodettls/" + key);
if (ttl == null || ttl === "" || nowMillis >= parseInt(ttl)) {
window.sessionStorage.setItem("pincodettls/" + key, ttl);
}
} else {
let now = new Date();
let ttl = now.getTime() + 4 * 60 * 60 * 1000;
window.sessionStorage.removeItem("pincodettls/" + key);
let now = new Date();
let nowMillis = now.getTime();
let ttl = window.sessionStorage.getItem("pincodettls/" + key);
} else {
return window.sessionStorage.getItem("pincodes/" + key);
}
}
}
function createEvent(actionId, type, payloads) {
return {
actionID: actionId,
type: type,
stamp: new Date().getTime(),
payloads: payloads
};
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
const destroyAuthentication = () => {
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;
let response;
try {
response = await fn.apply(that, [config, ...args]);
} catch (error) {
if (error.response) {
//Resposnse with status code != 2xx still has valid response
response = error.response;
} else {
//Connection error or similar
const data = {
const identity = currentlyAuthenticatedIdentity || currentlyLoadedIdentity;

Alexey Lunin
committed
const { code, status } = response.data;
const deviceRevoked =
type === "private" && code === "401" && status === STATUS_DEVICE_REVOKED;

Alexey Lunin
committed
if (deviceRevoked) {
destroyIdentity();

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

Alexey Lunin
committed
return response.data;
}
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);
try {
response = await fn.apply(that, [config, ...args]);
} catch (error) {
response = error.response;
}
return response.data;
}
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);
}
window.viamAnonymousApi.setIdentity(
window.currentlyLoadedIdentity.authentication.publicKey
);
const { publicKey, x509Certificate } = loadedIdentity.authentication;
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" };
const passportIdentity = window.currentlyAuthenticatedIdentity;
let passport = passportIdentity.getPassport(passportUUID);
if (passport === undefined || passport === null) {
createPassportCertificate(passportUUID).then(function(keys) {
cryptoData.setPublicKey(keys["publicKeyPEM"]);
cryptoData.setPrivateKey(keys["privateKeyPEM"]);
//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") {
//download("passportCertificateAfterSigning.crt", "text/plain", signedCertificate)
let keyUUID = executeResult.data["CertificateUUID"];
let encodedChain = executeResult.data["Chain"];
//download("rootCertificate.crt", "text/plain", atob(encodedChain[0]))
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)
);
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
});
certificateResult(executeResult);
let 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
Alexey Lunin
committed
}
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 => {
let newIdentity = new Identity();
let cryptoData = new CryptoData();
cryptoData.setPublicKey(keys["publicKeyPEM"]);
cryptoData.setPrivateKey(keys["privateKeyPEM"]);
cryptoData.setx509Certificate(keys["certificatePEM"]);
newIdentity.setAuthentication(cryptoData);
newIdentity.setPinCode(pinCode);
window.currentlyLoadedIdentity = newIdentity;
const {
publicKey,
x509Certificate
} = newIdentity.authentication;
extendPinCodeTtl(newIdentity.authentication.publicKey, pinCode);
window.viamAnonymousApi.setIdentity(
newIdentity.authentication.publicKey
);
data: {
authentication: {
publicKey,
x509Certificate
}
},
},
listIdentities() {
return new Penpal.Promise(result => {
result({ data: identities, code: "200", status: "Identities listed" });
});
},
loadIdentity(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);
window.currentlyAuthenticatedIdentity = identity;
window.currentlyLoadedIdentity = 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: 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(() => {
.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) {
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"
});
let success = extendPinCodeTtl(authenticationPublicKey);
if (success === false) {
result({
data: "",
code: "400",
status: "Identity not authenticated"
});
executeRestfulFunction(
"private",
viamApi,
viamApi.identityAddNewDevice,
null
).then(executeResult => {
let actionID = executeResult.data["ActionID"];
let QrCode = executeResult.data["QrCode"];
} 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"
});
let success = extendPinCodeTtl(authenticationPublicKey);
if (success === false) {
result({
data: "",
code: "400",
status: "Identity not authenticated"
});
executeRestfulFunction(
"private",
viamApi,
viamApi.identityDestroyKeysForDevice,
null,
btoa(authenticationPublicKeyArg)
).then(executeResult => {
result(executeResult);
});
});
},
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
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" };
let success = extendPinCodeTtl(authenticationPublicKey);
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" });
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" };
let success = extendPinCodeTtl(authenticationPublicKey);
if (success === false) {
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" };
let success = extendPinCodeTtl(authenticationPublicKey);
if (success === false) {
result({
data: "",
code: "400",
status: "Identity not authenticated"
});
getCertificateForPassport(passportUUID, true).then(
certificateResult => {
if (certificateResult.code === "200") {
let passportPrivateKey = certificateResult.data["privateKey"];
let passportChain = certificateResult.data["chain"];
createOneTimePassportCertificate(
makeid() + "-" + passportUUID,
emailArg,
passportPrivateKey,
passportCertificate
).then(function(keys) {
let publicKeyOneTime = keys["publicKeyPEM"];
let privateKeyOneTime = keys["privateKeyPEM"];
let certificateOneTime = keys["certificatePEM"];
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"
});
}
verifySMIME: async (smimeString) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
//TODO cache (for some time) the root certificate
// either as PEM or as certificate object (preferred)
const rootCaResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.signRetrieveRootCertificate,
null
);
if (rootCaResponse.code !== "200") {
return encodeResponse("400", "", rootCaResponse.status);
}
const rootCaPem = rootCaResponse.data;
const verificationResult = await verifySMIME(smimeString, rootCaPem);
return encodeResponse("200", verificationResult.verified, verificationResult.message);
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
validateDocument: async (documentUUID, contentType) => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const validateDocumentResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.documentValidateDocumentByUUID,
null,
documentUUID,
contentType);
if (validateDocumentResponse.code !== "200") {
return encodeResponse("400", "", validateDocumentResponse.status);
}
const signatures = validateDocumentResponse.data;
if (signatures) {
for (const signature of signatures) {
const certificateChain = signature.certificateChainPEM.map((certificatePEM) => {
const certificate = parseCertificate(certificatePEM);
const certificateData = new CertificateData(certificate);
return certificateData;
});
signature.certificateChain = certificateChain;
}
}
return validateDocumentResponse;
},
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");
signDocument: async (passportUUID, documentUUID, documentContentType) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const certResponse = await getCertificateForPassport(passportUUID, true);
if (certResponse.code !== "200") {
return encodeResponse("400", "", certResponse.status);
}
const {
x509Certificate: passportCertificate,
privateKey: passportPrivateKey,
chain: passportChain
const keys = await createOneTimePassportCertificate(
makeid() + "-" + passportUUID,
null,
passportPrivateKey,
passportCertificate
);
const {
privateKeyPEM: privateKeyOneTime,
certificatePEM: certificateOneTime
} = keys;
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);
}
const pdfRaw = base64ToByteArray(downloadResponse.data);
signedPdf = await signPdf(
pdfRaw,
certificateOneTime,
passportChain,
privateKeyOneTime
);
} catch (err) {
console.error(err);
return encodeResponse("500", "", err.message);
}
const signedPdfB64 = byteArrayToBase64(signedPdf);
const uploadResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.documentPutDocumentByUUID,
null,
documentUUID,
pdfContentType,
signedPdfB64
);
if (uploadResponse.code !== "200") {
return encodeResponse("400", "", uploadResponse.status);
}
const signResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.documentSignDocumentByUUID,
null,
passportUUID,
documentUUID,
pdfContentType
);
if (signResponse.code !== "200") {
return encodeResponse("400", "", signResponse.status);
}
return encodeResponse("200", "", "Document signed");
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
signDocumentJava: async (passportUUID, documentUUID, documentContentType) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const certResponse = await getCertificateForPassport(passportUUID, true);
if (certResponse.code !== "200") {
return encodeResponse("400", "", certResponse.status);
}
const {
x509Certificate: passportCertificate,
privateKey: passportPrivateKey,
chain: passportChain
} = certResponse.data;
const keys = await createOneTimePassportCertificate(
makeid() + "-" + passportUUID,
passportPrivateKey,
passportCertificate
);
const {
privateKeyPEM: privateKeyOneTime,
certificatePEM: certificateOneTime
} = keys;
passportChain.push(passportCertificate);
passportChain.push(certificateOneTime);
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
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 signResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.documentSignDocumentJavaService,
null,
privateKeyOneTime,
passportChain,
passportUUID,
documentUUID,
pdfContentType
);
if (signResponse.code !== "200") {
return encodeResponse("400", "", signResponse.status);
}
return encodeResponse("200", "", "Document signed");
},
// passportUUID - String - passport to sign the vCard
// senderEmail - the email address of the sender
// attribs - additional attributes, to be added to the vCard. Recognized attribs are:
// - emailService: "GMail", "Outlook 365", ...
// text, html - String - the text and html part of the email, both optional
// parts - array of objects, representing the MIME structure in format:
// "Content-Type": "image/jpeg",
// "Content-Disposition": "inline" or "attachment" with additional attributes,
// ... //other headers from MIME
// body: String if it is a text part (Content-Type = "text/...") or Uint8Array otherwise; filled for leaf MIME nodes
// parts: array of instances of the same object; filled for container MIME nodes (Content-Type = "multipart/...")
signVCard: async (passportUUID, senderEmail, attribs, textBody, htmlBody, parts) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const messageUUID = makeid();
const vCardAttribs = {
...attribs,
passportUUID,
messageUUID
let vCardImageData;
let vCardImageClaimValue;
const vCardImageClaimName = "vCardImage";
const defaultTagName = "notag";
const vCardClaimResponse = await executeRestfulFunction(
vCardImageClaimName,
defaultTagName,
// if (vCardClaimResponse.code !== "200") {
// return encodeResponse("400", "", vCardClaimResponse.status);
// }
if (vCardClaimResponse.code === "200") {
vCardImageClaimValue = vCardClaimResponse.data;
}
let qrCodeImageData;
let qrCodeCoordinates = {fromL: -1, fromR:-1, toL: -1, toR: -1};
if (vCardImageClaimValue && "state" in vCardImageClaimValue && vCardImageClaimValue.state === "disabled") {
vCardImageData = new ImageData({
contentType: "image/png",
contentBase64: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" //1x1px transparent pixel
});
} else {
const vCardImageResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.passportGetVCardImage,
null,
passportUUID
);
if (vCardImageResponse.code !== "200") {
return encodeResponse("400", "", vCardImageResponse.status);
}
vCardImageData = new ImageData(vCardImageResponse.data.Image);
if (vCardImageData.contentType !== "image/png") {
return encodeResponse("400", "", "Content type of vCard mmust be 'image/png'");
}
qrCodeCoordinates = vCardImageResponse.data.QRCodeCoordinates;
const qrCodeBase64Content = await generateQrCode("https://" + location.host + "/check/" + messageUUID);
qrCodeImageData = new ImageData(
{
contentType: "image/png",
content: qrCodeBase64Content
}
);
if (typeof parts === "undefined" || parts === null) {
if (htmlBody) {
if (typeof htmlBody !== "string") {
throw new Error("htmlBody is not string"); // should not happen
}
const htmlPart = {
headers: {
"Content-Type": "text/html"
},
} else {
console.log("Html body is not passed to signVCard, its value is ", {html: htmlBody});
if (textBody) {
if (typeof textBody !== "string") {
throw new Error("textBody is not string"); // should not happen
}
const textPart = {
headers: {
"Content-Type": "text/plain"
},
} else {
console.log("Text body is not passed to signVCard, its value is ", {text: textBody});
const count = prepareVCardParts(parts);
if (count.textParts === 0) {
return encodeResponse("400", "", "No text parts passed to signVCard");
}
if (count.htmlParts === 0) {
return encodeResponse("400", "", "No html parts passed to signVCard");
}
const certResponse = await getCertificateForPassport(passportUUID, true);
if (certResponse.code !== "200") {
return encodeResponse("400", "", certResponse.status);
}
const {
x509Certificate: passportCertificate,
privateKey: passportPrivateKey,
chain: passportChain
} = certResponse.data;
const keys = await createOneTimePassportCertificate(
makeid() + "-" + passportUUID,
passportPrivateKey,
passportCertificate
);
const {
privateKeyPEM: privateKeyOneTime,
certificatePEM: certificateOneTime
} = keys;
passportChain.reverse();
passportChain.push(passportCertificate);
passportChain.push(certificateOneTime);
passportChain.reverse();
console.log(qrCodeImageData);
console.log(qrCodeCoordinates);
const signVCardResponse = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.signSignVCardForChain,
null,
vCardImageData,
privateKeyOneTime,
passportChain,
vCardAttribs,
qrCodeImageData,
qrCodeCoordinates,
);
if (signVCardResponse.code !== "200") {
return encodeResponse("400", "", signVCardResponse.status);
}
const signedVCardImageData = new ImageData(signVCardResponse.data);
return encodeResponse("200", {
image: signedVCardImageData,
// mime - String - the MIME of the email message
// vCardAttribs - optional attributes for the verification procedure in format
// passportUUID: passportUUID,
// messageUUID: messageUUID
// };
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const validateVMimeResponse = await executeRestfulFunction(
window.viamApi.signValidateVMime,
if (validateVMimeResponse.code !== "200") {
return encodeResponse("400", "", validateVMimeResponse.status);
const {signatures} = validationResult;
if (signatures) {
for (const signature of signatures) {
const certificateChain = signature.certificateChainPEM.map((certificatePEM) => {
const certificate = parseCertificate(certificatePEM);
const certificateData = new CertificateData(certificate);
return certificateData;
});
signature.certificateChain = certificateChain;
return encodeResponse("200", validationResult, "Validation result retrieved");
documentCreateDocument: async (passportUUID, path, contentType, title) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
path = encodeURI(path);
contentType = encodeURI(contentType);
title = encodeURI(title);
const config = {
headers: {
path,
passportuuid: passportUUID,
contentType,
title
}
};
const response = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.documentCreateDocument,
config
);
if (response.code !== "200") {
return encodeResponse("400", "", response.status);
}
return encodeResponse("200", response.data, "Document created");
},
documentPutDocument: async (
passportUUID,
resourceid,
contentType,
) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
resourceid = encodeURI(resourceid);
contentType = encodeURI(contentType);
const config = {
headers: {
passportuuid: passportUUID,
}
};
const response = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.documentPutDocument,
config,
file
);
if (response.code !== "200") {
return encodeResponse("400", "", response.status);
}
return encodeResponse("200", response.data, "Document stored");
},
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"
let success = extendPinCodeTtl(authenticationPublicKey);
if (success === false) {
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"
);
extractMessageID(mime) {
return new Penpal.Promise(result => {
result(extractMessageID(mime));
});
},
stringToUtf8ByteArray(str) {
return new Penpal.Promise(result => {
result(stringToUtf8ByteArray(str));
});
},
utf8ByteArrayToString(ba) {
return new Penpal.Promise(result => {
result(utf8ByteArrayToString(ba));
});
},
stringToUtf8Base64(str) {
return new Penpal.Promise(result => {
result(stringToUtf8Base64(str));
});
},
utf8Base64ToString(strBase64) {
return new Penpal.Promise(result => {
result(utf8Base64ToString(strBase64));
});
},
base64ToByteArray(strBase64) {
return new Penpal.Promise(result => {
result(base64ToByteArray(strBase64));
});
},
byteArrayToBase64(ba) {
return new Penpal.Promise(result => {
result(byteArrayToBase64(ba));
});
return collaboraApi.discovery().then(apps => apps);
getPassportsNewProtocol: async (resourceID, contentType) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const response = await wopiAPI.getPassportsNewProtocol(
resourceID,
contentType
);
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const response = await wopiAPI.getPassports(fileId);
wopiCreateDocument: async (passportUUID, path, title) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const config = {
headers: {
path,
passportuuid: passportUUID,
title
}
};
const createDocumentResult = await executeRestfulFunction(
"private",
window.viamApi,
window.viamApi.documentCreateDocument,
config
);
if (createDocumentResult.code !== "200") {
return createDocumentResult;
const resourceID = createDocumentResult.data;
const accessTokenResponse = await wopiAPI.getAccessToken(passportUUID, resourceID);
if (accessTokenResponse.data.code !== "200") {
return accessTokenResponse.data;
}
const accessToken = accessTokenResponse.data.data;
const result = {
resourceID,
accessToken
};
wopiGetAccessToken: async (passportUUID, resourceID, contentType) => {
const authenticationPublicKey = localStorage.getItem(
"authenticatedIdentity"
);
if (
!authenticationPublicKey ||
!window.loadedIdentities[authenticationPublicKey] ||
!extendPinCodeTtl(authenticationPublicKey)
) {
return encodeResponse("400", "", "Identity not authenticated");
}
const response = await wopiAPI.getAccessToken(passportUUID, resourceID, contentType);
return response.data;
},
wopiPutFile: async (resourceID, 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(resourceID, accessToken, file);
connection.promise.then(parent => {
if (!navigator.cookieEnabled) {
console.warn("Cookie disabled. Can't start library.");
return;
}
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;
let previousLocalStorageUUID;
let previousLocalStorageToken;
let previousLocalStorageIdentity;
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"
);
const result = await loadIdentityInternal(
authenticationPublicKey,
"00000000"
);
const event = createEvent(
"CanNotGetPincodeForAuthenticatedIdentity",
"IdentityNotLoaded",
[authenticationPublicKey]
);
parent.onEvent(event);
clearPinCodeTtl(authenticationPublicKey);
window.currentlyAuthenticatedIdentity = null;
}
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 currentLocalStorageUUID = localStorage.getItem("uuid");
const currentLocalStorageToken = localStorage.getItem("token");
const currentLocalStorageIdentity = localStorage.getItem(
"authenticatedIdentity"
);
(!currentLocalStorageUUID && previousLocalStorageUUID) ||
(!currentLocalStorageToken && previousLocalStorageToken) ||
(!currentLocalStorageIdentity && previousLocalStorageIdentity)
) {
previousLocalStorageUUID = null;
previousLocalStorageToken = null;
previousLocalStorageIdentity = null;
destroyAuthentication();
const event = createEvent("", "LogoutExternal");
parent.onEvent(event);
} else {
previousLocalStorageUUID = currentLocalStorageUUID;
previousLocalStorageToken = currentLocalStorageToken;
previousLocalStorageIdentity = currentLocalStorageIdentity;
}
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) {
await setIdentityInLocalStorage(window.currentlyLoadedIdentity);
parent.onEvent(event);
break;
const actionID = event["actionID"];
const QrCode = event["payloads"][1];
const eventCopy = JSON.parse(JSON.stringify(event));
parent.onEvent(eventCopy);
});
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;
}
parent.onEvent(event);
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));
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));
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;
if (
window.currentlyLoadedIdentity &&
!anynomousDeviceKeyEventsProcessing &&
!window.currentlyAuthenticatedIdentity
) {
getNewEventsWithoutSession();
}
if (window.currentlyAuthenticatedIdentity) {
// These functions has to be executed at the same time.
!eventsDeviceEventsProcessing && getNewDeviceEvents();
!eventsEntityEventsProcessing && getNewEntityEvents();