* add Add Group button * add host groups to schema * UI for host groups * raname groups to hostGroups * schema update * show groups in assignment tab * add no group hosts to Group 1 * add dummy group for non group hosts * fix type errors * use two dimensional array for luckyUserPools * fix empty array * group RR hosts in handleNewBooking * improve logic for grouping lucky users * find all lucky users of all groups * allow several RR hosts on booking * clean up migrations * create helper function * group hosts for slots logic * add group logic to loading available slots * adding hosts to groups * add groupId to hostSchema * disable hosts from other groups * handle groups in checkedTeamSelect * fix adding hosts to groups * remove and add groups * show hosts if there are no groups * fixing adding first group with existing hosts * show groups empty groups correctly * UI upddate fixes * fix adding hosts to existing first host group * small fixes + code clean up * add availability fix with test * create new round-robin test file * disable reassignment * fix losing fixed hosts * fix updating weights and priorities * disable load balancing with Round Robin Groups * automatically disable load balancing in update handler * allRRHosts should only include hosts from same group * fix type errors * fix type error * fix tests * fix type error * remove undefined from groupId type * type changes * add tests for hostGroups * add tests for host groups * fixes * fix type errors with undefined groupId * remove seperate host groups prop * fix editing weights * remove console.log * code clean up * improve getAggregatedAvailability tests * throw error when no available hosts in a group * add fixme comment * create constant for DEFAULT_GROUP_ID * clean up code * mock default_group_id for unit tests * don't show fixed hosts in edit weights side bar * add DEFAULT_GROUP_ID to mock test-setup * remove unused index variable * code clean up * fix updating host groups * fix imports * add default_group_id to mocks * add uuid() to zod schema * remove unused code * fix singular translation key * remove unnessary !! * Revert formatting changes * add additional tests for bookingActions * use createMany * import DEFAULT_GROUP_ID for mocks * fix mocks * clean up EventTeamAssignmentTab * fix type errors in tests * fix mocks * remove constants.example.test.ts * fix type error * add missing groupId * fix margin * clean up empty host groups * fix constants mock * useCalback * use reduce * extract handlers into seperate functions * fix handler functions * fix border radius * fix type error in CheckForEmptyAssignment * fix type error --------- Co-authored-by: CarinaWolli <wollencarina@gmail.com>
128 lines
4.5 KiB
TypeScript
128 lines
4.5 KiB
TypeScript
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
|
|
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
|
|
const rule = createRule({
|
|
create(context) {
|
|
// Track imported names from @calcom/lib/webstorage
|
|
const safeImportedNames = new Set<string>();
|
|
|
|
return {
|
|
ImportDeclaration(node) {
|
|
// Check if this is an import from the safe webstorage module
|
|
if (node.source.value === "@calcom/lib/webstorage") {
|
|
node.specifiers.forEach((specifier) => {
|
|
if (specifier.type === "ImportSpecifier") {
|
|
// Track the local name used for the import
|
|
safeImportedNames.add(specifier.local.name);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
CallExpression(node) {
|
|
const webStorages = ["localStorage", "sessionStorage"];
|
|
const callee = node.callee;
|
|
|
|
// Check for window.localStorage or window.sessionStorage
|
|
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",
|
|
});
|
|
}
|
|
|
|
// Check for direct localStorage or sessionStorage usage
|
|
if (
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
callee.type === "MemberExpression" &&
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
callee.object?.type === "Identifier" &&
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
webStorages.includes(callee.object?.name) &&
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
!safeImportedNames.has(callee.object?.name)
|
|
) {
|
|
return context.report({
|
|
node: node,
|
|
loc: node.loc,
|
|
messageId: "possible-issue-with-embed",
|
|
});
|
|
}
|
|
},
|
|
|
|
// Also check for property access like localStorage.length
|
|
MemberExpression(node) {
|
|
const webStorages = ["localStorage", "sessionStorage"];
|
|
|
|
// Check for direct property access on localStorage/sessionStorage
|
|
if (
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
node.object?.type === "Identifier" &&
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
webStorages.includes(node.object?.name) &&
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
!safeImportedNames.has(node.object?.name)
|
|
) {
|
|
return context.report({
|
|
node: node,
|
|
loc: node.loc,
|
|
messageId: "possible-issue-with-embed",
|
|
});
|
|
}
|
|
|
|
// Check for window.localStorage/sessionStorage property access
|
|
if (
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
node.object?.type === "MemberExpression" &&
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
node.object?.object?.name === "window" &&
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
webStorages.includes(node.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;
|