Hotfix: Embed - Fix issue in accessing sessionStorage in certain scenarios (#3851)
* Fixes issue when sessionStorage is not accessible in privacy focussed modes in various browsers * Fix eslint errors Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>pull/3864/head
parent
732acb5b25
commit
bc6c9e1b0a
|
@ -3,12 +3,26 @@ import Document, { DocumentContext, Head, Html, Main, NextScript, DocumentProps
|
|||
type Props = Record<string, unknown> & DocumentProps;
|
||||
|
||||
function toRunBeforeReactOnClient() {
|
||||
window.sessionStorage.setItem("calEmbedMode", String(location.search.includes("embed=")));
|
||||
const calEmbedMode = location.search.includes("embed=");
|
||||
try {
|
||||
// eslint-disable-next-line @calcom/eslint/avoid-web-storage
|
||||
window.sessionStorage.setItem("calEmbedMode", String(calEmbedMode));
|
||||
} catch (e) {}
|
||||
|
||||
window.isEmbed = () => {
|
||||
return window.sessionStorage.getItem("calEmbedMode") === "true";
|
||||
try {
|
||||
// eslint-disable-next-line @calcom/eslint/avoid-web-storage
|
||||
return window.sessionStorage.getItem("calEmbedMode") === "true";
|
||||
} catch (e) {}
|
||||
// If we can't use sessionStorage to retrieve embed mode, just use the variable. It would fail to detect embed if page in iframe reloads without embed query param in it.
|
||||
return calEmbedMode;
|
||||
};
|
||||
|
||||
window.resetEmbedStatus = () => {
|
||||
window.sessionStorage.removeItem("calEmbedMode");
|
||||
try {
|
||||
// eslint-disable-next-line @calcom/eslint/avoid-web-storage
|
||||
window.sessionStorage.removeItem("calEmbedMode");
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
window.getEmbedTheme = () => {
|
||||
|
|
|
@ -40,6 +40,9 @@ import { UsernameAvailability } from "@components/ui/UsernameAvailability";
|
|||
|
||||
import { TRPCClientErrorLike } from "@trpc/client";
|
||||
|
||||
// Embed isn't applicable to onboarding, so ignore the rule
|
||||
/* eslint-disable @calcom/eslint/avoid-web-storage */
|
||||
|
||||
type ScheduleFormValues = {
|
||||
schedule: ScheduleType;
|
||||
};
|
||||
|
|
|
@ -179,6 +179,8 @@ function SettingsView(props: ComponentProps<typeof Settings> & { localeProp: str
|
|||
const enteredTimeFormat = selectedTimeFormat.value;
|
||||
|
||||
// Write time format to localStorage if available
|
||||
// Embed isn't applicable to profile pages. So ignore the rule
|
||||
// eslint-disable-next-line @calcom/eslint/avoid-web-storage
|
||||
window.localStorage.setItem("timeOption.is24hClock", selectedTimeFormat.value === 12 ? "false" : "true");
|
||||
|
||||
// TODO: Add validation
|
||||
|
|
|
@ -36,6 +36,7 @@ test.describe("Onboarding", () => {
|
|||
*/
|
||||
test.fixme();
|
||||
await page.addInitScript(() => {
|
||||
// eslint-disable-next-line @calcom/eslint/avoid-web-storage
|
||||
window.localStorage.setItem("username", "alwaysavailable");
|
||||
}, {});
|
||||
// Try to go getting started with a available username
|
||||
|
|
|
@ -3,6 +3,7 @@ const recommended = {
|
|||
parserOptions: { sourceType: "module" },
|
||||
rules: {
|
||||
"@calcom/eslint/deprecated-imports": "error",
|
||||
"@calcom/eslint/avoid-web-storage": "error",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import { ESLintUtils } from "@typescript-eslint/utils";
|
||||
|
||||
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
|
||||
const rule = createRule({
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
const webStorages = ["localStorage", "sessionStorage"];
|
||||
const callee = node.callee;
|
||||
if (
|
||||
// Can't figure out how to fix this TS issue
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
callee.object?.object?.name === "window" &&
|
||||
// Can't figure out how to fix this TS issue
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
webStorages.includes(node?.callee?.object?.property?.name)
|
||||
) {
|
||||
return context.report({
|
||||
node: node,
|
||||
loc: node.loc,
|
||||
messageId: "possible-issue-with-embed",
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
name: "avoid-web-storage",
|
||||
meta: {
|
||||
fixable: "code",
|
||||
docs: {
|
||||
description: "Avoid deprecated imports",
|
||||
recommended: "warn",
|
||||
},
|
||||
messages: {
|
||||
"possible-issue-with-embed": `Be aware that accessing localStorage/sessionStorage throws error in Chrome Incognito mode when embed is in cross domain context. If you know what you are doing, \`import {localStorage, sessionStorage} from "@calcom/lib/webstorage"\` for safe usage. See https://github.com/calcom/cal.com/issues/2618`,
|
||||
},
|
||||
type: "suggestion",
|
||||
schema: [],
|
||||
},
|
||||
defaultOptions: [],
|
||||
});
|
||||
|
||||
export default rule;
|
|
@ -4,4 +4,5 @@ import type { ESLint } from "eslint";
|
|||
export default {
|
||||
"my-first-rule": require("./my-first-rule").default,
|
||||
"deprecated-imports": require("./deprecated-imports").default,
|
||||
"avoid-web-storage": require("./avoid-web-storage").default,
|
||||
} as ESLint.Plugin["rules"];
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
export const localStorage = {
|
||||
getItem(key: string) {
|
||||
try {
|
||||
// eslint-disable-next-line @calcom/eslint/avoid-web-storage
|
||||
return window.localStorage.getItem(key);
|
||||
} catch (e) {
|
||||
// In case storage is restricted. Possible reasons
|
||||
|
@ -11,6 +12,7 @@ export const localStorage = {
|
|||
},
|
||||
setItem(key: string, value: string) {
|
||||
try {
|
||||
// eslint-disable-next-line @calcom/eslint/avoid-web-storage
|
||||
window.localStorage.setItem(key, value);
|
||||
} catch (e) {
|
||||
// In case storage is restricted. Possible reasons
|
||||
|
|
Loading…
Reference in New Issue