Skip to content
Snippets Groups Projects

Implement request signing and permitted domains

Merged Gospodin Bodurov requested to merge iframe-security into master
Files
4
@@ -47,6 +47,7 @@ import {
checkRecoveryKeyCombine,
encryptShare
} from "../utilities/secrets";
import {generateNonce, signRSA} from "../utilities/cryptoUtils";
const penpalMethods = require("../../temp/penpal-methods").default;
const WopiAPI = require("./wopiapi-iframe");
@@ -129,6 +130,22 @@ function setIdentityInLocalStorage(identityToStore, extendKey = true) {
);
}
async function setCurrentlyLoadedIdentity(identity) {
window.currentlyLoadedIdentity = identity;
if (identity) {
let nonce = window.viamApi.getNonce();
if (!nonce) {
nonce = generateNonce();
const privateKey = window.currentlyLoadedIdentity.authentication.privateKey;
const nonceSignature = await signRSA(privateKey, nonce);
window.viamApi.setNonce(Buffer.from(nonce).toString("base64"));
window.viamApi.setNonceSignature(Buffer.from(nonceSignature).toString("base64"));
}
}
}
function getProfileData(identity) {
return new Penpal.Promise(executeResultUpper => {
executeRestfulFunction(
@@ -260,7 +277,7 @@ const destroyIdentity = () => {
const { publicKey } = window.currentlyLoadedIdentity.authentication;
delete window.loadedIdentities[publicKey];
window.currentlyLoadedIdentity = null;
setCurrentlyLoadedIdentity(null);
destroyIdentityFromLocalStorage(publicKey);
}
};
@@ -393,7 +410,7 @@ function loadIdentityInternal(identityKey, pinCode) {
localStorage.removeItem("attempt");
window.loadedIdentities[identityKey] = loadedIdentity;
window.currentlyLoadedIdentity = loadedIdentity;
await setCurrentlyLoadedIdentity(loadedIdentity)
if (identityKey === localStorage.getItem("authenticatedIdentity")) {
window.currentlyAuthenticatedIdentity = loadedIdentity;
@@ -479,10 +496,10 @@ function getCertificateForPassport(passportUUID, internal) {
getProfileData(passportIdentity).then(executeResult1 => {
setIdentityInLocalStorage(passportIdentity)
.then(() => {
.then(async () => {
window.currentlyAuthenticatedIdentity = passportIdentity;
window.lastTimeGetProfile = 0;
window.currentlyLoadedIdentity = passportIdentity;
await setCurrentlyLoadedIdentity(passportIdentity)
const copyOfCryptoData = JSON.parse(
JSON.stringify(cryptoData)
);
@@ -529,7 +546,7 @@ function getCertificateForPassport(passportUUID, internal) {
const connection = Penpal.connectToParent({
// Methods child is exposing to parent
methods: {
initialize: (apiUrl, wopiUrl, collaboraUrl) => {
initialize: async (apiUrl, wopiUrl, collaboraUrl) => {
if (!apiUrl) {
apiUrl = `${window.location.origin}/api/`;
console.warn(`API host URL not specified. Fall back to ${apiUrl}`); // eslint-disable-line no-console
@@ -555,11 +572,33 @@ const connection = Penpal.connectToParent({
collaboraUrl.charAt(collaboraUrl.length - 1) === "/"
? collaboraUrl
: collaboraUrl + "/";
const { code, data: { domains: permittedDomains }} = await penpalMethods.identityGetPermittedDomains();
if (code !== "200") {
throw new Error("Unable to retrieve a list of permitted domains.")
}
if (permittedDomains && permittedDomains.length) {
const iframeOrigin = document.referrer;
let iframeOriginIsPermitted = false;
for (const domain of permittedDomains) {
if (iframeOrigin.includes(domain)) {
iframeOriginIsPermitted = true;
break;
}
}
if (!iframeOriginIsPermitted) {
throw new Error(`Iframe origin "${iframeOrigin}" is not permitted.`)
}
}
},
...penpalMethods,
createIdentity(pinCode) {
return new Penpal.Promise(result => {
createPassportCertificate(makeid()).then(function (keys) {
createPassportCertificate(makeid()).then(async function (keys) {
const newIdentity = new Identity();
const cryptoData = new CryptoData();
cryptoData.setPublicKey(keys["publicKeyPEM"]);
@@ -568,7 +607,7 @@ const connection = Penpal.connectToParent({
newIdentity.setAuthentication(cryptoData);
newIdentity.setPinCode(pinCode);
window.currentlyLoadedIdentity = newIdentity;
await setCurrentlyLoadedIdentity(newIdentity)
localStorage.setItem(
"currentlyLoadedIdentity",
JSON.stringify(newIdentity)
@@ -629,7 +668,7 @@ const connection = Penpal.connectToParent({
identity.pinCode = newPinCode;
await setIdentityInLocalStorage(identity);
window.currentlyAuthenticatedIdentity = identity;
window.currentlyLoadedIdentity = identity;
await setCurrentlyLoadedIdentity(identity);
return encodeResponse("200", null, "Successfully changed pincode");
} else {
@@ -758,7 +797,7 @@ const connection = Penpal.connectToParent({
let sequence = Promise.resolve();
if (executeResult.code === "200") {
sequence = sequence.then(() => {
setIdentityInLocalStorage(registerIdentity);
setIdentityInLocalStorage(window.currentlyLoadedIdentity);
});
}
sequence
@@ -995,7 +1034,7 @@ const connection = Penpal.connectToParent({
"currentlyLoadedIdentity"
);
const identity = new Identity(currentlyLoadedIdentity);
window.currentlyLoadedIdentity = identity;
await setCurrentlyLoadedIdentity(identity);
const { publicKey } = identity.authentication;
window.loadedIdentities[publicKey] = identity;
window.viamAnonymousApi.setIdentity(publicKey);
@@ -2489,7 +2528,7 @@ connection.promise.then(parent => {
if (event.key === "authenticatedIdentity" && event.newValue === null) {
const publicKey =
window.currentlyAuthenticatedIdentity.authentication.publicKey;
window.currentlyLoadedIdentity = null;
setCurrentlyLoadedIdentity(null);
window.currentlyAuthenticatedIdentity = null;
const event = createEvent("LogoutFromAnotherTab", "Logout", [publicKey]);
parent.onEvent(event);
@@ -2572,7 +2611,7 @@ connection.promise.then(parent => {
false
);
window.currentlyLoadedIdentity = identity;
!window.currentlyLoadedIdentity && await setCurrentlyLoadedIdentity(identity);
if (!identityAuthenticatedEvent && identity) {
const event = createEvent("IdentityAuthenticated", "Authenticated", [
@@ -2604,7 +2643,7 @@ connection.promise.then(parent => {
}
identityAuthenticatedEvent = false;
window.currentlyLoadedIdentity = null;
setCurrentlyLoadedIdentity(null);
}
localStorage.removeItem("currentlyLoadedIdentity");
@@ -2711,7 +2750,7 @@ connection.promise.then(parent => {
localStorage.removeItem("token");
localStorage.removeItem("authenticatedIdentity");
delete window.loadedIdentities[authenticationPublicKey];
window.currentlyLoadedIdentity = null;
setCurrentlyLoadedIdentity(null);
window.currentlyAuthenticatedIdentity = null;
window.lastTimeGetProfile = 0;
Loading