@atomicjolt/lti-client
Version:
Client Javascript libraries to handle LTI.
127 lines • 5.33 kB
JavaScript
import i18next from "i18next";
import { STATE_KEY_PREFIX } from "./constants";
import { setCookie } from "./cookies";
import { showLaunchNewWindow } from "../html/launch_new_window";
import { getCapability } from "../libs/capabilities";
export async function getTargetFrame(storageParams) {
let target = storageParams.target;
if (target == null) {
const cap = await getCapability("lti.get_data");
target = cap?.frame;
}
if (target == null) {
target = "_parent";
}
const parent = window.parent || window.opener;
return target === "_parent" ? parent : parent.frames[target] || parent;
}
export async function storeState(state, storageParams) {
return new Promise((resolve, reject) => {
let platformOrigin = new URL(storageParams.platformOIDCUrl).origin;
if (storageParams.originSupportBroken) {
// The spec requires that the message's target origin be set to the platform's OIDC Authorization url
// but Canvas does not yet support this, so we have to use '*'.
platformOrigin = "*";
}
let timeout = setTimeout(() => {
console.error("postMessage timeout");
reject(new Error(i18next.t("Timeout while waiting for platform response")));
}, 2000);
let receiveMessage = (event) => {
if (typeof event.data === "object" &&
event.data.subject === "lti.put_data.response" &&
event.data.message_id === state &&
(event.origin === platformOrigin ||
(storageParams.originSupportBroken && platformOrigin === "*"))) {
removeEventListener("message", receiveMessage);
clearTimeout(timeout);
if (event.data.error) {
// handle errors
console.error(event.data.error.code);
console.error(event.data.error.message);
reject(new Error(event.data.errormessage));
}
resolve();
}
};
window.addEventListener("message", receiveMessage);
getTargetFrame(storageParams)
.then((targetFrame) => targetFrame?.postMessage({
subject: "lti.put_data",
message_id: state,
key: `${STATE_KEY_PREFIX}${state}`,
value: state,
}, platformOrigin))
.catch((e) => {
console.log(i18next.t("Could not find target frame"));
console.log(e);
reject(new Error(i18next.t("Could not find target frame")));
});
// Platform should post a message back
});
}
export function hasStorageAccessAPI() {
return (typeof document.hasStorageAccess === "function" &&
typeof document.requestStorageAccess === "function");
}
export function tryRequestStorageAccess(settings) {
document
.requestStorageAccess()
.then(() => {
// We should have cookies now
setCookie(settings);
window.location.replace(settings.responseUrl);
})
.catch((e) => {
console.log(e);
showLaunchNewWindow(settings, {
showStorageAccessDenied: true,
disableLaunch: true,
showRequestStorageAccess: false,
});
});
}
export function loadState(state, storageParams) {
return new Promise((resolve, reject) => {
let platformOrigin = new URL(storageParams.platformOIDCUrl).origin;
if (storageParams.originSupportBroken) {
// The spec requires that the message's target origin be set to the platform's OIDC Authorization url
// but Canvas does not yet support this, so we have to use '*'.
platformOrigin = "*";
}
const timeout = setTimeout(() => {
console.log(i18next.t("postMessage timeout"));
reject(new Error(i18next.t("Timeout while waiting for platform response")));
}, 2000);
const receiveMessage = (event) => {
if (typeof event.data === "object" &&
event.data.subject === "lti.get_data.response" &&
event.data.message_id === state &&
(event.origin === platformOrigin || platformOrigin === "*")) {
removeEventListener("message", receiveMessage);
clearTimeout(timeout);
if (event.data.error) {
// handle errors
console.error(event.data.error.code);
console.error(event.data.error.message);
reject(new Error(event.data.errormessage));
}
resolve(event.data.value);
}
};
window.addEventListener("message", receiveMessage);
getTargetFrame(storageParams)
.then((targetFrame) => targetFrame.postMessage({
subject: "lti.get_data",
message_id: state,
key: `${STATE_KEY_PREFIX}${state}`,
}, platformOrigin))
.catch((e) => {
console.log(i18next.t("Could not find target frame"));
console.log(e);
reject(new Error(i18next.t("Could not find target frame")));
});
// Platform will post a message back
});
}
//# sourceMappingURL=platform_storage.js.map