diff --git a/javascript/src/iframe/viamapi-iframe.js b/javascript/src/iframe/viamapi-iframe.js
index 43bb11975575dcc19d459600ddabfb97fa763c46..56cf322e3b4ec42b598d268917e71a9ee069c047 100644
--- a/javascript/src/iframe/viamapi-iframe.js
+++ b/javascript/src/iframe/viamapi-iframe.js
@@ -269,7 +269,7 @@ async function executeRestfulFunction(type, that, fn, config, ...args) {
   const badSession = type === "private" && identity && code === "400" && status === "Bad session";
   if (!badSession) return response.data;
 
-  const loginResponse = await viamApi.identityLogin("previousaddeddevice");
+  const loginResponse = await viamApi.identityLogin(null, "previousaddeddevice");
   if (loginResponse.data.code !== "200") return loginResponse.data;
 
   const uuid = loginResponse.data.data["Uuid"];
@@ -330,36 +330,6 @@ function loadIdentityInternal(identityKey, pinCode) {
   });
 }
 
-function changeIdentityPinCodeInternal(key, oldPinCode, newPinCode) {
-
-  return new Penpal.Promise(result => {
-    getIdentityFromLocalStorage(key, oldPinCode, false).then((identity) => {
-
-      identity.pinCode = newPinCode;
-
-      setIdentityInLocalStorage(identity).then(() => {
-        result({
-          "data": "",
-          "code": "200",
-          "status": "Successfully changed pincode"
-        });
-      }).catch((e) => {
-        result({
-          "data": "",
-          "code": "400",
-          "status": "Cannot store identity " + e
-        });
-      });
-    }).catch((e) => {
-      result({
-        "data": "",
-        "code": "400",
-        "status": "Cannot get identity " + e
-      });
-    });
-  });
-}
-
 function getCertificateForPassport(passportUUID, internal) {
 
   return new Penpal.Promise(certificateResult => {
@@ -504,8 +474,34 @@ const connection = Penpal.connectToParent({
     loadIdentity(identityKey, pinCode) {
       return loadIdentityInternal(identityKey, pinCode)
     },
-    changeIdentityPinCode(key, oldPinCode, newPinCode) {
-      return changeIdentityPinCodeInternal(key, oldPinCode, newPinCode)
+    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 => {
@@ -523,18 +519,15 @@ const connection = Penpal.connectToParent({
         }
       });
     },
-    clearIdentities() {
-      return new Penpal.Promise(result => {
-        var identitiesTemp = listIdentitiesFromLocalStorage();
+    clearIdentities: async () => {
+      destroyAuthentication();
 
-        for(var i in identitiesTemp) {
-          destroyIdentityFromLocalStorage(i)
-        }
-        result({"data" : "",
-          "code" : "200",
-          "status" : "Identities cleared"
-        })
-      });
+      const identitiesTemp = listIdentitiesFromLocalStorage();
+
+      for (const i in identitiesTemp) {
+        destroyIdentityFromLocalStorage(i);
+      }
+      return encodeResponse("200", "", "Identities cleared");
     },
     confirmIdentificator(identity, confirmationCodeArg) {
       return new Penpal.Promise(result => {
@@ -615,6 +608,7 @@ const connection = Penpal.connectToParent({
       }
 
       const deviceHash = await createDeviceHash(loginIdentity.authentication.publicKey);
+      window.viamApi.setSessionData("", "");
       window.viamApi.setDeviceHash(deviceHash);
       window.viamApi.setIdentity(loginIdentity.authentication.publicKey);
 
@@ -647,19 +641,6 @@ const connection = Penpal.connectToParent({
 
       return responseToClient;
     },
-    identityPullAvatarFromGravatar: async () => {
-      const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
-
-      if (
-        !authenticationPublicKey ||
-        !window.loadedIdentities[authenticationPublicKey] ||
-        !extendPinCodeTtl(authenticationPublicKey)
-      ) {
-        return encodeResponse("400", "", "Identity not authenticated");
-      }
-
-      return await executeRestfulFunction("private", viamApi, viamApi.identityPullAvatarFromGravatar);
-    },
     identityAddNewDevice() {
       return new Penpal.Promise(result => {
         const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
@@ -732,28 +713,41 @@ const connection = Penpal.connectToParent({
       });
     },
     logout: async () => {
-      const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
-      if (!authenticationPublicKey || !window.loadedIdentities[authenticationPublicKey]) {
+      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();
+
+        return executeRestfulFunction(
+          "private",
+          window.viamApi,
+          window.viamApi.identityLogout,
+          {
+            headers
+          }
+        );
+      } catch (e) {
         return {
           data: "",
           code: "400",
-          status: "Identity not loaded"
+          status: e.message
         };
       }
-
-      const identityLogoutResponse = await executeRestfulFunction(
-        "private",
-        window.viamApi,
-        window.viamApi.identityLogout,
-        null
-      );
-
-      destroyAuthentication();
-
-      return identityLogoutResponse;
     },
     identityRestoreAccess(restoreAccessIdentity, identificator) {
       return new Penpal.Promise(result => {
+        viamApi.setSessionData("", "");
         viamApi.setIdentity(restoreAccessIdentity.authentication.publicKey);
 
         executeRestfulFunction("public", viamApi, viamApi.identityRestoreAccess, null, identificator).then(executeResult => {
@@ -1073,6 +1067,64 @@ const connection = Penpal.connectToParent({
 
       return encodeResponse("200", response.data, "PDF signed");
     },
+    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");
+    },
     documentCreateDocument: async (path, passportUUID, contenttype) => {
       const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
       if (
@@ -1325,6 +1377,8 @@ connection.promise.then(parent => {
     localStorage.getItem("token") === null ||
     localStorage.getItem("authenticatedIdentity") === null
   ) {
+    const event = createEvent("", "NotAuthenticated");
+    parent.onEvent(event);
     localStorage.removeItem("uuid");
     localStorage.removeItem("token");
     localStorage.removeItem("authenticatedIdentity");
@@ -1426,86 +1480,23 @@ connection.promise.then(parent => {
     }
   }, 50);
 
-  setInterval(async () => {
-    if (window.currentlyLoadedIdentity && !anynomousDeviceKeyEventsProcessing && !window.currentlyAuthenticatedIdentity) {
-      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 "Authenticated" : {
-                const uuid = event.payloads[0];
-                const token = event.payloads[1];
-                handleIdentityLogin(window.currentlyLoadedIdentity, uuid, token);
-                const identityToStore = window.currentlyAuthenticatedIdentity;
-                event.payloads = [{fromQRCode: true}];
-                await setIdentityInLocalStorage(identityToStore);
-                await getProfileData(identityToStore);
-                parent.onEvent(event);
-                break;
-              }
-
-              case "QRCodeUpdated" : {
-                const actionID = event["actionID"];
-                const QrCode = event["payloads"][1];
-
-                const eventCopy = JSON.parse(JSON.stringify(event));
-
-                QRCode.toDataURL(actionID + "," + QrCode, function (err, url) {
-                  eventCopy["payloads"].push(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);
-              }
+  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;
             }
-            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;
-    }
 
-    if (window.currentlyAuthenticatedIdentity != null && eventsDeviceEventsProcessing === false) {
-      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") {
+            case "QRCodeUpdated" : {
               const actionID = event["actionID"];
               const QrCode = event["payloads"][1];
 
@@ -1515,59 +1506,126 @@ connection.promise.then(parent => {
                 eventCopy["payloads"].push(url);
                 parent.onEvent(eventCopy);
               });
-            } else {
+              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);
             }
-            maxDeviceKeyEventTime = Math.max(maxDeviceKeyEventTime, event.stamp);
           }
-          if(changedMaxDeviceKeyEventTime) {
-            await executeRestfulFunction("private", viamApi, viamApi.eventUpdateLastViewed, null, "devicekey",
-              maxDeviceKeyEventTime.toString());
+          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;
+    } catch (e) {
+      console.warn(e);
     }
+    eventsDeviceEventsProcessing = false;
+  };
 
-    if (window.currentlyAuthenticatedIdentity != null && eventsEntityEventsProcessing === false) {
-      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 getNewEntityEvents = async () => {
+    eventsEntityEventsProcessing = true;
+    try {
+      const executeResult = await executeRestfulFunction("private", viamApi, viamApi.eventGetNewEvents, null, "entity");
 
-              const eventCopy = JSON.parse(JSON.stringify(event));
+      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];
 
-              QRCode.toDataURL(actionID + "," + QrCode, function (err, url) {
-                eventCopy["payloads"].push(url);
-                parent.onEvent(eventCopy);
-              });
+            const eventCopy = JSON.parse(JSON.stringify(event));
 
-              continue;
-            }
+            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());
+            continue;
           }
+
+          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;
+    } 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();
     }
   }, 1000);
 });