{"version":3,"file":"javascript.min.js","sources":["../node_modules/js-cookie/dist/js.cookie.mjs","../src/cookies.ts","../src/org.ts","../src/user.ts","../src/api.ts","../src/org_helper.ts","../src/access_helper.ts","../src/fetch_retries.ts","../src/helpers.ts","../src/client.ts"],"sourcesContent":["/*! js-cookie v3.0.5 | MIT */\n/* eslint-disable no-var */\nfunction assign (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n target[key] = source[key];\n }\n }\n return target\n}\n/* eslint-enable no-var */\n\n/* eslint-disable no-var */\nvar defaultConverter = {\n read: function (value) {\n if (value[0] === '\"') {\n value = value.slice(1, -1);\n }\n return value.replace(/(%[\\dA-F]{2})+/gi, decodeURIComponent)\n },\n write: function (value) {\n return encodeURIComponent(value).replace(\n /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,\n decodeURIComponent\n )\n }\n};\n/* eslint-enable no-var */\n\n/* eslint-disable no-var */\n\nfunction init (converter, defaultAttributes) {\n function set (name, value, attributes) {\n if (typeof document === 'undefined') {\n return\n }\n\n attributes = assign({}, defaultAttributes, attributes);\n\n if (typeof attributes.expires === 'number') {\n attributes.expires = new Date(Date.now() + attributes.expires * 864e5);\n }\n if (attributes.expires) {\n attributes.expires = attributes.expires.toUTCString();\n }\n\n name = encodeURIComponent(name)\n .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)\n .replace(/[()]/g, escape);\n\n var stringifiedAttributes = '';\n for (var attributeName in attributes) {\n if (!attributes[attributeName]) {\n continue\n }\n\n stringifiedAttributes += '; ' + attributeName;\n\n if (attributes[attributeName] === true) {\n continue\n }\n\n // Considers RFC 6265 section 5.2:\n // ...\n // 3. If the remaining unparsed-attributes contains a %x3B (\";\")\n // character:\n // Consume the characters of the unparsed-attributes up to,\n // not including, the first %x3B (\";\") character.\n // ...\n stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n }\n\n return (document.cookie =\n name + '=' + converter.write(value, name) + stringifiedAttributes)\n }\n\n function get (name) {\n if (typeof document === 'undefined' || (arguments.length && !name)) {\n return\n }\n\n // To prevent the for loop in the first place assign an empty array\n // in case there are no cookies at all.\n var cookies = document.cookie ? document.cookie.split('; ') : [];\n var jar = {};\n for (var i = 0; i < cookies.length; i++) {\n var parts = cookies[i].split('=');\n var value = parts.slice(1).join('=');\n\n try {\n var found = decodeURIComponent(parts[0]);\n jar[found] = converter.read(value, found);\n\n if (name === found) {\n break\n }\n } catch (e) {}\n }\n\n return name ? jar[name] : jar\n }\n\n return Object.create(\n {\n set,\n get,\n remove: function (name, attributes) {\n set(\n name,\n '',\n assign({}, attributes, {\n expires: -1\n })\n );\n },\n withAttributes: function (attributes) {\n return init(this.converter, assign({}, this.attributes, attributes))\n },\n withConverter: function (converter) {\n return init(assign({}, this.converter, converter), this.attributes)\n }\n },\n {\n attributes: { value: Object.freeze(defaultAttributes) },\n converter: { value: Object.freeze(converter) }\n }\n )\n}\n\nvar api = init(defaultConverter, { path: '/' });\n/* eslint-enable no-var */\n\nexport { api as default };\n","export const ACTIVE_ORG_ID_COOKIE_NAME = \"active_org_id\"\n","import Cookies from \"js-cookie\"\nimport { ACTIVE_ORG_ID_COOKIE_NAME } from \"./cookies\"\n\nexport type OrgMemberInfo = {\n orgId: string\n orgName: string\n orgMetadata: { [key: string]: any }\n urlSafeOrgName: string\n orgRoleStructure: OrgRoleStructure\n userAssignedRole: string\n userInheritedRolesPlusCurrentRole: string[]\n userPermissions: string[]\n userAssignedAdditionalRoles: string[]\n legacyOrgId?: string\n}\nexport type OrgIdToOrgMemberInfo = {\n [orgId: string]: OrgMemberInfo\n}\n\nexport enum OrgRoleStructure {\n SingleRole = \"single_role_in_hierarchy\",\n MultiRole = \"multi_role\",\n}\n\nexport const setActiveOrgId = (orgId: string) => {\n Cookies.set(ACTIVE_ORG_ID_COOKIE_NAME, orgId, {\n sameSite: \"lax\",\n secure: true,\n })\n}\n\nexport const getActiveOrgId = (): string | undefined => {\n return Cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)\n}\n","import { OrgIdToOrgMemberInfo, OrgRoleStructure } from \"./org\"\n\nexport type UserProperties = { [key: string]: unknown }\n\nexport interface UserFields {\n userId: string\n email: string\n createdAt: number\n firstName?: string\n lastName?: string\n username?: string\n properties?: UserProperties\n pictureUrl?: string\n hasPassword?: boolean\n hasMfaEnabled?: boolean\n canCreateOrgs?: boolean\n legacyUserId?: string\n impersonatorUserId?: string\n}\n\nexport class UserClass {\n public userId: string\n public orgIdToUserOrgInfo?: OrgIdToOrgMemberInfoClass\n\n // Metadata about the user\n public email: string\n public createdAt: number\n public firstName?: string\n public lastName?: string\n public username?: string\n public properties?: UserProperties\n public pictureUrl?: string\n public hasPassword?: boolean\n public hasMfaEnabled?: boolean\n public canCreateOrgs?: boolean\n\n // If you used our migration APIs to migrate this user from a different system,\n // this is their original ID from that system.\n public legacyUserId?: string\n public impersonatorUserId?: string\n\n constructor(userFields: UserFields, orgIdToUserOrgInfo?: OrgIdToOrgMemberInfoClass) {\n this.userId = userFields.userId\n this.orgIdToUserOrgInfo = orgIdToUserOrgInfo\n\n this.email = userFields.email\n this.firstName = userFields.firstName\n this.lastName = userFields.lastName\n this.username = userFields.username\n this.createdAt = userFields.createdAt\n this.pictureUrl = userFields.pictureUrl\n this.hasPassword = userFields.hasPassword\n this.hasMfaEnabled = userFields.hasMfaEnabled\n this.canCreateOrgs = userFields.canCreateOrgs\n\n this.legacyUserId = userFields.legacyUserId\n this.impersonatorUserId = userFields.impersonatorUserId\n this.properties = userFields.properties\n }\n\n public getOrg(orgId: string): OrgMemberInfoClass | undefined {\n if (!this.orgIdToUserOrgInfo) {\n return undefined\n }\n\n return this.orgIdToUserOrgInfo[orgId]\n }\n\n public getOrgByName(orgName: string): OrgMemberInfoClass | undefined {\n if (!this.orgIdToUserOrgInfo) {\n return undefined\n }\n\n const urlSafeOrgName = orgName.toLowerCase().replace(/ /g, \"-\")\n for (const orgId in this.orgIdToUserOrgInfo) {\n const orgMemberInfo = this.orgIdToUserOrgInfo[orgId]\n if (orgMemberInfo?.urlSafeOrgName === urlSafeOrgName) {\n return orgMemberInfo\n }\n }\n\n return undefined\n }\n\n public getUserProperty(key: string): unknown | undefined {\n if (!this.properties) {\n return undefined\n }\n\n return this.properties[key]\n }\n\n public getOrgs(): OrgMemberInfoClass[] {\n if (!this.orgIdToUserOrgInfo) {\n return []\n }\n\n return Object.values(this.orgIdToUserOrgInfo)\n }\n\n public isImpersonating(): boolean {\n return !!this.impersonatorUserId\n }\n\n public isRole(orgId: string, role: string): boolean {\n const orgMemberInfo = this.getOrg(orgId)\n if (!orgMemberInfo) {\n return false\n }\n\n return orgMemberInfo.isRole(role)\n }\n\n public isAtLeastRole(orgId: string, role: string): boolean {\n const orgMemberInfo = this.getOrg(orgId)\n if (!orgMemberInfo) {\n return false\n }\n\n return orgMemberInfo.isAtLeastRole(role)\n }\n\n public hasPermission(orgId: string, permission: string): boolean {\n const orgMemberInfo = this.getOrg(orgId)\n if (!orgMemberInfo) {\n return false\n }\n\n return orgMemberInfo.hasPermission(permission)\n }\n\n public hasAllPermissions(orgId: string, permissions: string[]): boolean {\n const orgMemberInfo = this.getOrg(orgId)\n if (!orgMemberInfo) {\n return false\n }\n\n return orgMemberInfo.hasAllPermissions(permissions)\n }\n\n public static fromJSON(json: string): UserClass {\n const obj = JSON.parse(json)\n const orgIdToUserOrgInfo: OrgIdToOrgMemberInfoClass = {}\n for (const orgId in obj.orgIdToUserOrgInfo) {\n orgIdToUserOrgInfo[orgId] = OrgMemberInfoClass.fromJSON(JSON.stringify(obj.orgIdToUserOrgInfo[orgId]))\n }\n try {\n return new UserClass(\n {\n userId: obj.userId,\n email: obj.email,\n createdAt: obj.createdAt,\n firstName: obj.firstName,\n lastName: obj.lastName,\n username: obj.username,\n legacyUserId: obj.legacyUserId,\n impersonatorUserId: obj.impersonatorUserId,\n properties: obj.properties,\n pictureUrl: obj.pictureUrl,\n hasPassword: obj.hasPassword,\n hasMfaEnabled: obj.hasMfaEnabled,\n canCreateOrgs: obj.canCreateOrgs,\n },\n orgIdToUserOrgInfo\n )\n } catch (e) {\n console.error(\"Unable to parse User. Make sure the JSON string is a stringified `UserClass` type.\", e)\n throw e\n }\n }\n}\n\nexport interface OrgIdToOrgMemberInfoClass {\n [orgId: string]: OrgMemberInfoClass\n}\n\nexport class OrgMemberInfoClass {\n public orgId: string\n public orgName: string\n public legacyOrgId?: string\n public orgMetadata: { [key: string]: any }\n public urlSafeOrgName: string\n public orgRoleStructure: OrgRoleStructure\n\n public userAssignedRole: string\n public userInheritedRolesPlusCurrentRole: string[]\n public userPermissions: string[]\n public userAssignedAdditionalRoles: string[]\n\n constructor(\n orgId: string,\n orgName: string,\n orgMetadata: { [key: string]: any },\n urlSafeOrgName: string,\n userAssignedRole: string,\n userInheritedRolesPlusCurrentRole: string[],\n userPermissions: string[],\n orgRoleStructure?: OrgRoleStructure,\n userAssignedAdditionalRoles?: string[],\n legacyOrgId?: string\n ) {\n this.orgId = orgId\n this.orgName = orgName\n this.legacyOrgId = legacyOrgId\n this.orgMetadata = orgMetadata\n this.urlSafeOrgName = urlSafeOrgName\n this.orgRoleStructure = orgRoleStructure ?? OrgRoleStructure.SingleRole\n\n this.userAssignedRole = userAssignedRole\n this.userInheritedRolesPlusCurrentRole = userInheritedRolesPlusCurrentRole\n this.userPermissions = userPermissions\n this.userAssignedAdditionalRoles = userAssignedAdditionalRoles ?? []\n }\n\n // validation methods\n public isRole(role: string): boolean {\n if (this.orgRoleStructure === OrgRoleStructure.MultiRole) {\n return this.userAssignedRole === role || this.userAssignedAdditionalRoles.includes(role)\n } else {\n return this.userAssignedRole === role\n }\n }\n\n public isAtLeastRole(role: string): boolean {\n if (this.orgRoleStructure === OrgRoleStructure.MultiRole) {\n return this.userAssignedRole === role || this.userAssignedAdditionalRoles.includes(role)\n } else {\n return this.userInheritedRolesPlusCurrentRole.includes(role)\n }\n }\n\n public hasPermission(permission: string): boolean {\n return this.userPermissions.includes(permission)\n }\n\n public hasAllPermissions(permissions: string[]): boolean {\n return permissions.every((permission) => this.hasPermission(permission))\n }\n\n public static fromJSON(json: string): OrgMemberInfoClass {\n const obj = JSON.parse(json)\n try {\n return new OrgMemberInfoClass(\n obj.orgId,\n obj.orgName,\n obj.orgMetadata,\n obj.urlSafeOrgName,\n obj.userAssignedRole,\n obj.userInheritedRolesPlusCurrentRole,\n obj.userPermissions,\n obj.orgRoleStructure,\n obj.userAssignedAdditionalRoles,\n obj.legacyOrgId\n )\n } catch (e) {\n console.error(\n \"Unable to parse UserOrgInfo. Make sure the JSON string is a stringified `UserOrgInfo` type.\",\n e\n )\n throw e\n }\n }\n}\n\nexport function convertOrgIdToOrgMemberInfo(\n orgIdToOrgMemberInfo: OrgIdToOrgMemberInfo | undefined\n): OrgIdToOrgMemberInfoClass | undefined {\n if (orgIdToOrgMemberInfo === undefined) {\n return undefined\n }\n const orgIdToUserOrgInfo: OrgIdToOrgMemberInfoClass = {}\n for (const orgMemberInfo of Object.values(orgIdToOrgMemberInfo)) {\n orgIdToUserOrgInfo[orgMemberInfo.orgId] = new OrgMemberInfoClass(\n orgMemberInfo.orgId,\n orgMemberInfo.orgName,\n orgMemberInfo.orgMetadata,\n orgMemberInfo.urlSafeOrgName,\n orgMemberInfo.userAssignedRole,\n orgMemberInfo.userInheritedRolesPlusCurrentRole,\n orgMemberInfo.userPermissions,\n orgMemberInfo.orgRoleStructure,\n orgMemberInfo.userAssignedAdditionalRoles,\n orgMemberInfo.legacyOrgId\n )\n }\n return orgIdToUserOrgInfo\n}\n","import { AccessHelper, getAccessHelper } from \"./access_helper\"\nimport { OrgIdToOrgMemberInfo } from \"./org\"\nimport { getOrgHelper, OrgHelper } from \"./org_helper\"\nimport { convertOrgIdToOrgMemberInfo, UserClass } from \"./user\"\n\nexport type User = {\n userId: string\n\n email: string\n emailConfirmed: boolean\n\n hasPassword: boolean\n\n username?: string\n firstName?: string\n lastName?: string\n pictureUrl?: string\n\n locked: boolean\n enabled: boolean\n mfaEnabled: boolean\n canCreateOrgs: boolean\n\n createdAt: number\n lastActiveAt: number\n\n legacyUserId?: string\n properties?: { [key: string]: unknown }\n}\n\nexport type AuthenticationInfo = {\n accessToken: string\n expiresAtSeconds: number\n orgHelper: OrgHelper\n accessHelper: AccessHelper\n\n /**\n * You should prefer orgHelper to orgIdToOrgMemberInfo.\n * orgHelper provides useful abstractions over this mapping\n */\n orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo\n user: User\n userClass: UserClass\n\n // If someone on your team is impersonating another user, this will be set to the employee's ID\n // By default, user impersonation is turned off and this will be undefined\n impersonatorUserId?: string\n}\n\nexport type LogoutResponse = {\n redirect_to: string\n}\n\nexport function fetchAuthenticationInfo(authUrl: string, activeOrgId?: string): Promise {\n const queryParams = new URLSearchParams()\n if (activeOrgId) {\n queryParams.append(\"active_org_id\", activeOrgId)\n }\n let path = `${authUrl}/api/v1/refresh_token`\n if (queryParams.toString()) {\n path += `?${queryParams.toString()}`\n }\n return fetch(path, {\n method: \"GET\",\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }).then((res) => {\n if (res.status === 401) {\n return null\n } else if (res.status === 0) {\n logCorsError()\n return Promise.reject({\n status: 503,\n message: \"Unable to process authentication response\",\n })\n } else if (!res.ok) {\n return Promise.reject({\n status: res.status,\n message: res.statusText,\n })\n } else {\n return parseResponse(res)\n }\n })\n}\n\nexport function logout(authUrl: string): Promise {\n return fetch(`${authUrl}/api/v1/logout`, {\n method: \"POST\",\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }).then((res) => {\n if (res.status === 0) {\n logCorsError()\n return Promise.reject({\n status: 503,\n message: \"Unable to process authentication response\",\n })\n } else if (!res.ok) {\n console.error(\"Logout error\", res.status, res.statusText)\n return Promise.reject({\n status: res.status,\n message: res.statusText,\n })\n } else {\n return res.json()\n }\n })\n}\n\nfunction parseResponse(res: Response): Promise {\n return res.text().then(\n (httpResponse) => {\n try {\n const authInfoWithoutUserClass = parseJsonConvertingSnakeToCamel(httpResponse)\n return withExtraArgs(authInfoWithoutUserClass)\n } catch (e) {\n console.error(\"Unable to process authentication response\", e)\n return Promise.reject({\n status: 500,\n message: \"Unable to process authentication response\",\n })\n }\n },\n (e) => {\n console.error(\"Unable to process authentication response\", e)\n return Promise.reject({\n status: 500,\n message: \"Unable to process authentication response\",\n })\n }\n )\n}\n\n// The API responds with snake_case, but TypeScript convention is camelCase.\n// When parsing JSON, we pass in reviver function to convert from snake_case to camelCase.\nexport function parseJsonConvertingSnakeToCamel(str: string): AuthenticationInfo {\n return JSON.parse(str, function (key, value) {\n if (key === \"org_id\") {\n this.orgId = value\n } else if (key === \"org_name\") {\n this.orgName = value\n } else if (key === \"org_metadata\") {\n this.orgMetadata = value\n } else if (key === \"url_safe_org_name\") {\n this.urlSafeOrgName = value\n } else if (key === \"user_role\") {\n this.userAssignedRole = value\n } else if (key === \"inherited_user_roles_plus_current_role\") {\n this.userInheritedRolesPlusCurrentRole = value\n } else if (key === \"user_permissions\") {\n this.userPermissions = value\n } else if (key === \"access_token\") {\n this.accessToken = value\n } else if (key === \"expires_at_seconds\") {\n this.expiresAtSeconds = value\n } else if (key === \"org_id_to_org_member_info\") {\n this.orgIdToOrgMemberInfo = value\n } else if (key === \"user_id\") {\n this.userId = value\n } else if (key === \"email_confirmed\") {\n this.emailConfirmed = value\n } else if (key === \"first_name\") {\n this.firstName = value\n } else if (key === \"last_name\") {\n this.lastName = value\n } else if (key === \"picture_url\") {\n this.pictureUrl = value\n } else if (key === \"mfa_enabled\") {\n this.mfaEnabled = value\n } else if (key === \"has_password\") {\n this.hasPassword = value\n } else if (key === \"can_create_orgs\") {\n this.canCreateOrgs = value\n } else if (key === \"created_at\") {\n this.createdAt = value\n } else if (key === \"last_active_at\") {\n this.lastActiveAt = value\n } else if (key === \"legacy_user_id\") {\n this.legacyUserId = value\n } else if (key === \"legacy_org_id\") {\n this.legacyOrgId = value\n } else if (key === \"impersonator_user\") {\n this.impersonatorUserId = value\n } else if (key === \"org_role_structure\") {\n this.orgRoleStructure = value\n } else if (key === \"additional_roles\") {\n this.userAssignedAdditionalRoles = value\n } else {\n return value\n }\n })\n}\n\nfunction withExtraArgs(authInfoWithoutExtraArgs: AuthenticationInfo): Promise {\n if (authInfoWithoutExtraArgs.orgIdToOrgMemberInfo) {\n authInfoWithoutExtraArgs.orgHelper = getOrgHelper(authInfoWithoutExtraArgs.orgIdToOrgMemberInfo)\n authInfoWithoutExtraArgs.accessHelper = getAccessHelper(authInfoWithoutExtraArgs.orgIdToOrgMemberInfo)\n }\n authInfoWithoutExtraArgs.userClass = new UserClass(\n {\n userId: authInfoWithoutExtraArgs.user.userId,\n email: authInfoWithoutExtraArgs.user.email,\n createdAt: authInfoWithoutExtraArgs.user.createdAt,\n firstName: authInfoWithoutExtraArgs.user.firstName,\n lastName: authInfoWithoutExtraArgs.user.lastName,\n username: authInfoWithoutExtraArgs.user.username,\n properties: authInfoWithoutExtraArgs.user.properties,\n pictureUrl: authInfoWithoutExtraArgs.user.pictureUrl,\n hasPassword: authInfoWithoutExtraArgs.user.hasPassword,\n hasMfaEnabled: authInfoWithoutExtraArgs.user.mfaEnabled,\n canCreateOrgs: authInfoWithoutExtraArgs.user.canCreateOrgs,\n legacyUserId: authInfoWithoutExtraArgs.user.legacyUserId,\n impersonatorUserId: authInfoWithoutExtraArgs.impersonatorUserId,\n },\n convertOrgIdToOrgMemberInfo(authInfoWithoutExtraArgs.orgIdToOrgMemberInfo)\n )\n return Promise.resolve(authInfoWithoutExtraArgs)\n}\n\nfunction logCorsError() {\n console.error(\n \"Request to PropelAuth failed due to a CORS error. There are a few likely causes: \\n\" +\n \" 1. In the Frontend Integration section of your dashboard, make sure your requests are coming either the specified Application URL or localhost with a matching port.\\n\" +\n \" 2. Make sure your server is hosted on HTTPS in production.\"\n )\n}\n","import {OrgIdToOrgMemberInfo, OrgMemberInfo} from \"./org\";\n\nexport type OrgHelper = {\n getOrgs: () => OrgMemberInfo[]\n getOrgIds: () => string[]\n getOrg: (orgId: string) => OrgMemberInfo | undefined\n getOrgByName: (orgName: string) => OrgMemberInfo | undefined\n}\n\nexport function getOrgHelper(\n orgIdToOrgMemberInfo: OrgIdToOrgMemberInfo,\n): OrgHelper {\n return {\n getOrg(orgId: string): OrgMemberInfo | undefined {\n if (orgIdToOrgMemberInfo.hasOwnProperty(orgId)) {\n return orgIdToOrgMemberInfo[orgId]\n } else {\n return undefined\n }\n },\n getOrgIds(): string[] {\n return Object.keys(orgIdToOrgMemberInfo)\n },\n getOrgs(): OrgMemberInfo[] {\n return Object.values(orgIdToOrgMemberInfo)\n },\n getOrgByName(orgName: string): OrgMemberInfo | undefined {\n for (const orgMemberInfo of Object.values(orgIdToOrgMemberInfo)) {\n if (orgMemberInfo.orgName === orgName || orgMemberInfo.urlSafeOrgName === orgName) {\n return orgMemberInfo\n }\n }\n return undefined\n },\n }\n}","import {OrgIdToOrgMemberInfo, OrgRoleStructure} from \"./org\";\n\nexport type AccessHelper = {\n isRole: (orgId: string, role: string) => boolean\n isAtLeastRole: (orgId: string, role: string) => boolean\n hasPermission: (orgId: string, permission: string) => boolean\n hasAllPermissions: (orgId: string, permissions: string[]) => boolean\n getAccessHelperWithOrgId: (orgId: string) => AccessHelperWithOrg\n}\n\nexport type AccessHelperWithOrg = {\n isRole: (role: string) => boolean\n isAtLeastRole: (role: string) => boolean\n hasPermission: (permission: string) => boolean\n hasAllPermissions: (permissions: string[]) => boolean\n}\n\nexport function getAccessHelper(\n orgIdToOrgMemberInfo: OrgIdToOrgMemberInfo,\n): AccessHelper {\n function isRole(orgId: string, role: string): boolean {\n const orgMemberInfo = orgIdToOrgMemberInfo[orgId]\n if (orgMemberInfo === undefined) {\n return false;\n }\n if (orgMemberInfo.orgRoleStructure === OrgRoleStructure.MultiRole) {\n return orgMemberInfo.userAssignedRole === role || orgMemberInfo.userAssignedAdditionalRoles.includes(role)\n } else {\n return orgMemberInfo.userAssignedRole === role\n }\n }\n \n function isAtLeastRole(orgId: string, role: string): boolean {\n const orgMemberInfo = orgIdToOrgMemberInfo[orgId]\n if (orgMemberInfo === undefined) {\n return false;\n }\n if (orgMemberInfo.orgRoleStructure === OrgRoleStructure.MultiRole) {\n return orgMemberInfo.userAssignedRole === role || orgMemberInfo.userAssignedAdditionalRoles.includes(role)\n } else {\n return orgMemberInfo.userInheritedRolesPlusCurrentRole.includes(role)\n }\n }\n\n function hasPermission(orgId: string, permission: string): boolean {\n const orgMemberInfo = orgIdToOrgMemberInfo[orgId]\n if (orgMemberInfo === undefined) {\n return false;\n }\n return orgMemberInfo.userPermissions.includes(permission)\n }\n\n function hasAllPermissions(orgId: string, permissions: string[]): boolean {\n const orgMemberInfo = orgIdToOrgMemberInfo[orgId]\n if (orgMemberInfo === undefined) {\n return false;\n }\n return permissions.every(permission => orgMemberInfo.userPermissions.includes(permission))\n }\n\n function getAccessHelperWithOrgId(orgId: string): AccessHelperWithOrg {\n return {\n isRole(role: string): boolean {\n return isRole(orgId, role)\n },\n isAtLeastRole(role: string): boolean {\n return isAtLeastRole(orgId, role)\n },\n hasPermission(permission: string): boolean {\n return hasPermission(orgId, permission)\n },\n hasAllPermissions(permissions: string[]): boolean {\n return hasAllPermissions(orgId, permissions)\n },\n }\n }\n \n return {\n isRole,\n isAtLeastRole,\n hasPermission,\n hasAllPermissions,\n getAccessHelperWithOrgId,\n }\n}\n","export const DEFAULT_RETRIES = 3\n\nexport const runWithRetriesOnAnyError = async (fn: () => Promise): Promise => {\n return runWithRetriesInner(fn, DEFAULT_RETRIES)\n}\n\nconst runWithRetriesInner = async (fn: () => Promise, numRetriesLeft: number): Promise => {\n try {\n return await fn()\n } catch (e) {\n if (numRetriesLeft <= 0) {\n throw e\n }\n await delay(numRetriesLeftToDelay(numRetriesLeft))\n return runWithRetriesInner(fn, numRetriesLeft - 1)\n }\n}\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))\n\nconst numRetriesLeftToDelay = (numRetriesLeft: number) => {\n // We could be fancy, but we only retry 3 times so...\n if (numRetriesLeft >= 3) {\n return 100\n } else if (numRetriesLeft === 2) {\n return 200\n } else {\n return 300\n }\n}","export function currentTimeSeconds() {\n return Date.now() / 1000\n}\n\nexport function hasLocalStorage(): boolean {\n return typeof localStorage !== \"undefined\"\n}\n\nexport function hasWindow(): boolean {\n return typeof window !== \"undefined\"\n}\n\nexport function getLocalStorageNumber(key: string): number | null {\n if (!hasLocalStorage()) {\n return null\n }\n\n const value = localStorage.getItem(key)\n if (!value) {\n return null\n }\n const num = parseInt(value, 10)\n if (Number.isNaN(num)) {\n return null\n }\n return num\n}\n","import { AuthenticationInfo, fetchAuthenticationInfo, logout } from \"./api\"\nimport { runWithRetriesOnAnyError } from \"./fetch_retries\"\nimport { currentTimeSeconds, getLocalStorageNumber, hasLocalStorage, hasWindow } from \"./helpers\"\n\nconst LOGGED_IN_AT_KEY = \"__PROPEL_AUTH_LOGGED_IN_AT\"\nconst LOGGED_OUT_AT_KEY = \"__PROPEL_AUTH_LOGGED_OUT_AT\"\nconst AUTH_TOKEN_REFRESH_BEFORE_EXPIRATION_SECONDS = 10 * 60\nconst DEFAULT_MIN_SECONDS_BEFORE_REFRESH = 60 * 2\nconst ACTIVE_ORG_ACCESS_TOKEN_REFRESH_EXPIRATION_SECONDS = 60 * 5\n\nconst encodeBase64 = (str: string) => {\n const encode = window ? window.btoa : btoa\n return encode(str)\n}\n\nexport interface RedirectToSignupOptions {\n postSignupRedirectUrl?: string\n userSignupQueryParameters?: Record\n}\n\nexport interface RedirectToLoginOptions {\n postLoginRedirectUrl?: string\n userSignupQueryParameters?: Record\n}\n\nexport interface RedirectToAccountOptions {\n redirectBackToUrl?: string\n}\n\nexport interface RedirectToCreateOrgOptions {\n redirectBackToUrl?: string\n}\n\nexport interface RedirectToOrgPageOptions {\n redirectBackToUrl?: string\n}\n\nexport interface RedirectToSetupSAMLPageOptions {\n redirectBackToUrl?: string\n}\n\nexport type AccessTokenForActiveOrg =\n | {\n error: undefined\n accessToken: string\n }\n | {\n error: \"user_not_in_org\"\n accessToken: never\n }\n | {\n error: \"unexpected_error\"\n accessToken: never\n }\n\nexport interface IAuthClient {\n /**\n * If the user is logged in, this method returns an access token, the time (in seconds) that the token will expire,\n * the user's organizations (including org names and user's role within the org), and the user's metadata.\n * Otherwise, this method returns null.\n *\n * The promise will generally resolve immediately, unless our current information is stale in which case it will\n * make an API request.\n *\n * @param forceRefresh If true, this method will always make an API request. Default false\n */\n getAuthenticationInfoOrNull(forceRefresh?: boolean): Promise\n\n /**\n * Logs the current user out.\n * @param redirectAfterLogout If true, will redirect the user to the configured logout URL.\n */\n logout(redirectAfterLogout: boolean): Promise\n\n /**\n * Gets the URL for the hosted signup page.\n */\n getSignupPageUrl(options?: RedirectToSignupOptions): string\n\n /**\n * Gets the URL for the hosted login page.\n */\n getLoginPageUrl(options?: RedirectToLoginOptions): string\n\n /**\n * Gets the URL for the hosted account page.\n */\n getAccountPageUrl(options?: RedirectToAccountOptions): string\n\n /**\n * Gets the URL for the hosted organization page.\n * @param orgId The ID of the organization's page to load. If not specified, a random one will be used instead.\n */\n getOrgPageUrl(orgId?: string, options?: RedirectToOrgPageOptions): string\n\n /**\n * Gets the URL for the hosted create organization page.\n */\n getCreateOrgPageUrl(options?: RedirectToCreateOrgOptions): string\n\n /**\n * Gets the URL for the hosted SAML configuration page.\n */\n getSetupSAMLPageUrl(orgId: string): string\n\n /**\n * Gets an access token for a specific organization, known as an Active Org.\n */\n getAccessTokenForOrg(orgId: string): Promise\n\n /**\n * Redirects the user to the signup page.\n */\n redirectToSignupPage(options?: RedirectToSignupOptions): void\n\n /**\n * Redirects the user to the login page.\n */\n redirectToLoginPage(options?: RedirectToLoginOptions): void\n\n /**\n * Redirects the user to the account page.\n */\n redirectToAccountPage(options?: RedirectToAccountOptions): void\n\n /**\n * Redirects the user to the organization page.\n * @param orgId The ID of the organization\"s page to load. If not specified, a random one will be used instead.\n */\n redirectToOrgPage(orgId?: string, options?: RedirectToOrgPageOptions): void\n\n /**\n * Redirects the user to the create organization page.\n */\n redirectToCreateOrgPage(options?: RedirectToCreateOrgOptions): void\n\n /**\n * Redirects the user to the SAML configuration page.\n */\n redirectToSetupSAMLPage(orgId: string, options?: RedirectToSetupSAMLPageOptions): void\n\n /**\n * Adds an observer which is called whenever the users logs in or logs out.\n */\n addLoggedInChangeObserver(observer: (isLoggedIn: boolean) => void): void\n\n /**\n * Removes the observer\n */\n removeLoggedInChangeObserver(observer: (isLoggedIn: boolean) => void): void\n\n /**\n * Adds an observer which is called whenever the access token changes.\n */\n addAccessTokenChangeObserver(observer: (accessToken: string | undefined) => void): void\n\n /**\n * Removes the observer\n */\n removeAccessTokenChangeObserver(observer: (accessToken: string | undefined) => void): void\n\n /**\n * Cleanup the auth client if you no longer need it.\n */\n destroy(): void\n}\n\nexport interface IAuthOptions {\n /**\n * Base URL where your authentication pages are hosted. See **Frontend Integration** section of your PropelAuth project.\n */\n authUrl: string\n\n /**\n * If true, periodically refresh the token in the background.\n * This helps ensure you always have a valid token ready to go when you need it.\n *\n * Default true\n */\n enableBackgroundTokenRefresh?: boolean\n\n /**\n * Minimum number of seconds before refreshing the token again.\n * Defaults to 120 seconds.\n */\n minSecondsBeforeRefresh?: number\n\n /**\n * If true, disables the token refresh when the tab regains focus.\n *\n * Default false\n */\n disableRefreshOnFocus?: boolean\n}\n\ninterface AccessTokenActiveOrgMap {\n [orgId: string]: {\n accessToken: string\n fetchedAt: number\n }\n}\n\ninterface ClientState {\n initialLoadFinished: boolean\n authenticationInfo: AuthenticationInfo | null\n observers: ((isLoggedIn: boolean) => void)[]\n accessTokenObservers: ((accessToken: string | undefined) => void)[]\n lastLoggedInAtMessage: number | null\n lastLoggedOutAtMessage: number | null\n refreshInterval: number | null\n lastRefresh: number | null\n accessTokenActiveOrgMap: AccessTokenActiveOrgMap\n readonly authUrl: string\n}\n\nfunction validateAndCleanupOptions(authOptions: IAuthOptions) {\n try {\n // This helps make sure we have a consistent URL ignoring things like trailing slashes\n const authUrl = new URL(authOptions.authUrl)\n authOptions.authUrl = authUrl.origin\n } catch (e) {\n console.error(\"Invalid authUrl\", e)\n throw new Error(\"Unable to initialize auth client\")\n }\n\n if (authOptions.enableBackgroundTokenRefresh === undefined) {\n authOptions.enableBackgroundTokenRefresh = true\n }\n}\n\nexport function createClient(authOptions: IAuthOptions): IAuthClient {\n const { minSecondsBeforeRefresh = DEFAULT_MIN_SECONDS_BEFORE_REFRESH } = authOptions\n\n validateAndCleanupOptions(authOptions)\n\n // Internal state\n const clientState: ClientState = {\n initialLoadFinished: false,\n authenticationInfo: null,\n observers: [],\n accessTokenObservers: [],\n lastLoggedInAtMessage: getLocalStorageNumber(LOGGED_IN_AT_KEY),\n lastLoggedOutAtMessage: getLocalStorageNumber(LOGGED_OUT_AT_KEY),\n authUrl: authOptions.authUrl,\n refreshInterval: null,\n lastRefresh: null,\n accessTokenActiveOrgMap: {},\n }\n\n // Helper functions\n function notifyObservers(isLoggedIn: boolean) {\n for (let i = 0; i < clientState.observers.length; i++) {\n const observer = clientState.observers[i]\n if (observer) {\n observer(isLoggedIn)\n }\n }\n }\n\n function notifyObserversOfAccessTokenChange(accessToken: string | undefined) {\n for (let i = 0; i < clientState.accessTokenObservers.length; i++) {\n const observer = clientState.accessTokenObservers[i]\n if (observer) {\n observer(accessToken)\n }\n }\n }\n\n function userJustLoggedOut(accessToken: string | undefined, previousAccessToken: string | undefined) {\n // Edge case: the first time we go to the page, if we can't load the\n // auth token we should treat it as a logout event\n return !accessToken && (previousAccessToken || !clientState.initialLoadFinished)\n }\n\n function userJustLoggedIn(accessToken: string | undefined, previousAccessToken: string | undefined) {\n return !previousAccessToken && accessToken\n }\n\n function updateLastLoggedOutAt() {\n const loggedOutAt = currentTimeSeconds()\n clientState.lastLoggedOutAtMessage = loggedOutAt\n if (hasLocalStorage()) {\n localStorage.setItem(LOGGED_OUT_AT_KEY, String(loggedOutAt))\n }\n }\n\n function updateLastLoggedInAt() {\n const loggedInAt = currentTimeSeconds()\n clientState.lastLoggedInAtMessage = loggedInAt\n if (hasLocalStorage()) {\n localStorage.setItem(LOGGED_IN_AT_KEY, String(loggedInAt))\n }\n }\n\n /**\n * Invalidates all org's access tokens.\n */\n function resetAccessTokenActiveOrgMap() {\n clientState.accessTokenActiveOrgMap = {}\n }\n\n function setAuthenticationInfoAndUpdateDownstream(authenticationInfo: AuthenticationInfo | null) {\n const previousAccessToken = clientState.authenticationInfo?.accessToken\n clientState.authenticationInfo = authenticationInfo\n const accessToken = authenticationInfo?.accessToken\n\n if (userJustLoggedOut(accessToken, previousAccessToken)) {\n notifyObservers(false)\n updateLastLoggedOutAt()\n } else if (userJustLoggedIn(accessToken, previousAccessToken)) {\n notifyObservers(true)\n updateLastLoggedInAt()\n }\n\n if (previousAccessToken !== accessToken) {\n notifyObserversOfAccessTokenChange(accessToken)\n }\n\n resetAccessTokenActiveOrgMap()\n\n clientState.lastRefresh = currentTimeSeconds()\n clientState.initialLoadFinished = true\n }\n\n async function forceRefreshToken(returnCached: boolean): Promise {\n try {\n // Happy case, we fetch auth info and save it\n const authenticationInfo = await runWithRetriesOnAnyError(() =>\n fetchAuthenticationInfo(clientState.authUrl)\n )\n setAuthenticationInfoAndUpdateDownstream(authenticationInfo)\n return authenticationInfo\n } catch (e) {\n // If there was an error, we sometimes still want to return the value we have cached\n // (e.g. if we were prefetching), so in those cases we swallow the exception\n if (returnCached) {\n return clientState.authenticationInfo\n } else {\n setAuthenticationInfoAndUpdateDownstream(null)\n throw e\n }\n }\n }\n\n const getSignupPageUrl = (options?: RedirectToSignupOptions) => {\n let qs = new URLSearchParams()\n let url = `${clientState.authUrl}/signup`\n if (options) {\n const { postSignupRedirectUrl, userSignupQueryParameters } = options\n if (postSignupRedirectUrl) {\n qs.set(\"rt\", encodeBase64(postSignupRedirectUrl))\n }\n if (userSignupQueryParameters) {\n Object.entries(userSignupQueryParameters).forEach(([key, value]) => {\n qs.set(key, value)\n })\n }\n }\n if (qs.toString()) {\n url += `?${qs.toString()}`\n }\n return url\n }\n\n const getLoginPageUrl = (options?: RedirectToLoginOptions) => {\n let qs = new URLSearchParams()\n let url = `${clientState.authUrl}/login`\n if (options) {\n const { postLoginRedirectUrl, userSignupQueryParameters } = options\n if (postLoginRedirectUrl) {\n qs.set(\"rt\", encodeBase64(postLoginRedirectUrl))\n }\n if (userSignupQueryParameters) {\n Object.entries(userSignupQueryParameters).forEach(([key, value]) => {\n qs.set(key, value)\n })\n }\n }\n if (qs.toString()) {\n url += `?${qs.toString()}`\n }\n return url\n }\n\n const getAccountPageUrl = (options?: RedirectToAccountOptions) => {\n let qs = new URLSearchParams()\n let url = `${clientState.authUrl}/account`\n if (options) {\n const { redirectBackToUrl } = options\n if (redirectBackToUrl) {\n qs.set(\"rt\", encodeBase64(redirectBackToUrl))\n }\n }\n\n if (qs.toString()) {\n url += `?${qs.toString()}`\n }\n return url\n }\n\n const getOrgPageUrl = (orgId?: string, options?: RedirectToOrgPageOptions) => {\n let qs = new URLSearchParams()\n let url = `${clientState.authUrl}/org`\n if (orgId) {\n qs.set(\"id\", orgId)\n }\n\n if (options) {\n if (options.redirectBackToUrl) {\n qs.set(\"rt\", encodeBase64(options.redirectBackToUrl))\n }\n }\n\n if (qs.toString()) {\n url += `?${qs.toString()}`\n }\n return url\n }\n\n const getCreateOrgPageUrl = (options?: RedirectToCreateOrgOptions) => {\n let qs = new URLSearchParams()\n let url = `${clientState.authUrl}/create_org`\n if (options) {\n const { redirectBackToUrl } = options\n if (redirectBackToUrl) {\n qs.set(\"rt\", encodeBase64(redirectBackToUrl))\n }\n }\n if (qs.toString()) {\n url += `?${qs.toString()}`\n }\n return url\n }\n\n const getSetupSAMLPageUrl = (orgId: string, options?: RedirectToSetupSAMLPageOptions) => {\n let qs = new URLSearchParams()\n if (options) {\n if (options.redirectBackToUrl) {\n qs.set(\"rt\", encodeBase64(options.redirectBackToUrl))\n }\n }\n qs.set(\"id\", orgId)\n\n return `${clientState.authUrl}/saml?${qs.toString()}`\n }\n\n const client = {\n addLoggedInChangeObserver(loggedInChangeObserver: (isLoggedIn: boolean) => void): void {\n const hasObserver = clientState.observers.includes(loggedInChangeObserver)\n if (hasObserver) {\n console.error(\"Observer has been attached already.\")\n } else if (!loggedInChangeObserver) {\n console.error(\"Cannot add a null observer\")\n } else {\n clientState.observers.push(loggedInChangeObserver)\n }\n },\n\n removeLoggedInChangeObserver(loggedInChangeObserver: (isLoggedIn: boolean) => void): void {\n const observerIndex = clientState.observers.indexOf(loggedInChangeObserver)\n if (observerIndex === -1) {\n console.error(\"Cannot find observer to remove\")\n } else {\n clientState.observers.splice(observerIndex, 1)\n }\n },\n\n addAccessTokenChangeObserver(observer: (accessToken: string | undefined) => void) {\n const hasObserver = clientState.accessTokenObservers.includes(observer)\n if (hasObserver) {\n console.error(\"Observer has been attached already.\")\n } else if (!observer) {\n console.error(\"Cannot add a null observer\")\n } else {\n clientState.accessTokenObservers.push(observer)\n }\n },\n\n removeAccessTokenChangeObserver(observer: (accessToken: string | undefined) => void) {\n const observerIndex = clientState.accessTokenObservers.indexOf(observer)\n if (observerIndex === -1) {\n console.error(\"Cannot find observer to remove\")\n } else {\n clientState.accessTokenObservers.splice(observerIndex, 1)\n }\n },\n\n async getAuthenticationInfoOrNull(forceRefresh?: boolean): Promise {\n const currentTimeSecs = currentTimeSeconds()\n if (forceRefresh) {\n return await forceRefreshToken(false)\n } else if (!clientState.authenticationInfo) {\n return await forceRefreshToken(false)\n } else if (\n currentTimeSecs + AUTH_TOKEN_REFRESH_BEFORE_EXPIRATION_SECONDS >\n clientState.authenticationInfo.expiresAtSeconds\n ) {\n // Small edge case: If we were being proactive\n // and the auth information hasn't expired yet, swallow any exceptions\n const returnCached = currentTimeSecs < clientState.authenticationInfo.expiresAtSeconds\n return await forceRefreshToken(returnCached)\n } else {\n return clientState.authenticationInfo\n }\n },\n\n async getAccessTokenForOrg(orgId: string): Promise {\n // First, check if there is a valid access token for the org ID in the\n // valid time frame.\n const currentTimeSecs = currentTimeSeconds()\n\n const activeOrgAccessToken = clientState.accessTokenActiveOrgMap[orgId]\n if (!!activeOrgAccessToken) {\n if (\n currentTimeSecs <\n activeOrgAccessToken.fetchedAt + ACTIVE_ORG_ACCESS_TOKEN_REFRESH_EXPIRATION_SECONDS\n ) {\n return {\n accessToken: activeOrgAccessToken.accessToken,\n error: undefined,\n }\n }\n }\n // Fetch the access token for the org ID and update.\n try {\n const authenticationInfo = await runWithRetriesOnAnyError(() =>\n fetchAuthenticationInfo(clientState.authUrl, orgId)\n )\n if (!authenticationInfo) {\n // Only null if 401 unauthorized.\n return {\n error: \"user_not_in_org\",\n accessToken: null as never,\n }\n }\n const { accessToken } = authenticationInfo\n clientState.accessTokenActiveOrgMap[orgId] = {\n accessToken,\n fetchedAt: currentTimeSecs,\n }\n return {\n accessToken,\n error: undefined,\n }\n } catch (e) {\n return {\n error: \"unexpected_error\",\n accessToken: null as never,\n }\n }\n },\n\n getSignupPageUrl(options?: RedirectToSignupOptions): string {\n return getSignupPageUrl(options)\n },\n\n getLoginPageUrl(options?: RedirectToLoginOptions): string {\n return getLoginPageUrl(options)\n },\n\n getAccountPageUrl(options?: RedirectToAccountOptions): string {\n return getAccountPageUrl(options)\n },\n\n getOrgPageUrl(orgId?: string, options?: RedirectToOrgPageOptions): string {\n return getOrgPageUrl(orgId, options)\n },\n\n getCreateOrgPageUrl(options?: RedirectToCreateOrgOptions): string {\n return getCreateOrgPageUrl(options)\n },\n\n getSetupSAMLPageUrl(orgId: string, options?: RedirectToSetupSAMLPageOptions): string {\n return getSetupSAMLPageUrl(orgId, options)\n },\n\n redirectToSignupPage(options?: RedirectToSignupOptions): void {\n window.location.href = getSignupPageUrl(options)\n },\n\n redirectToLoginPage(options?: RedirectToLoginOptions): void {\n window.location.href = getLoginPageUrl(options)\n },\n\n redirectToAccountPage(options?: RedirectToAccountOptions): void {\n window.location.href = getAccountPageUrl(options)\n },\n\n redirectToOrgPage(orgId?: string, options?: RedirectToOrgPageOptions): void {\n window.location.href = getOrgPageUrl(orgId, options)\n },\n\n redirectToCreateOrgPage(options?: RedirectToCreateOrgOptions): void {\n window.location.href = getCreateOrgPageUrl(options)\n },\n\n redirectToSetupSAMLPage(orgId: string, options?: RedirectToSetupSAMLPageOptions) {\n window.location.href = getSetupSAMLPageUrl(orgId, options)\n },\n\n async logout(redirectAfterLogout: boolean): Promise {\n const logoutResponse = await logout(clientState.authUrl)\n setAuthenticationInfoAndUpdateDownstream(null)\n if (redirectAfterLogout) {\n window.location.href = logoutResponse.redirect_to\n }\n },\n\n destroy() {\n clientState.observers = []\n clientState.accessTokenObservers = []\n window.removeEventListener(\"storage\", onStorageChange)\n window.removeEventListener(\"online\", onOnlineOrFocus)\n if (!authOptions.disableRefreshOnFocus) {\n window.removeEventListener(\"focus\", onOnlineOrFocus)\n }\n if (clientState.refreshInterval) {\n clearInterval(clientState.refreshInterval)\n }\n },\n }\n\n const onStorageChange = async function () {\n // If localStorage isn't available, nothing to do here.\n // This usually happens in frameworks that have some SSR components\n if (!hasLocalStorage()) {\n return\n }\n\n const loggedOutAt = getLocalStorageNumber(LOGGED_OUT_AT_KEY)\n const loggedInAt = getLocalStorageNumber(LOGGED_IN_AT_KEY)\n\n // If we've detected a logout event after the last one our client is aware of, trigger a refresh\n if (loggedOutAt && (!clientState.lastLoggedOutAtMessage || loggedOutAt > clientState.lastLoggedOutAtMessage)) {\n clientState.lastLoggedOutAtMessage = loggedOutAt\n if (clientState.authenticationInfo) {\n await forceRefreshToken(true)\n }\n }\n\n // If we've detected a login event after the last one our client is aware of, trigger a refresh\n if (loggedInAt && (!clientState.lastLoggedInAtMessage || loggedInAt > clientState.lastLoggedInAtMessage)) {\n clientState.lastLoggedInAtMessage = loggedInAt\n if (!clientState.authenticationInfo) {\n await forceRefreshToken(true)\n }\n }\n }\n\n // If we were offline or on a different tab, when we return, refetch auth info\n // Some browsers trigger focus more often than we'd like, so we'll debounce a little here as well\n const onOnlineOrFocus = async function () {\n if (clientState.lastRefresh && currentTimeSeconds() > clientState.lastRefresh + minSecondsBeforeRefresh) {\n await forceRefreshToken(true)\n } else {\n await client.getAuthenticationInfoOrNull()\n }\n }\n\n if (hasWindow()) {\n window.addEventListener(\"storage\", onStorageChange)\n window.addEventListener(\"online\", onOnlineOrFocus)\n\n if (!authOptions.disableRefreshOnFocus) {\n window.addEventListener(\"focus\", onOnlineOrFocus)\n }\n\n if (authOptions.enableBackgroundTokenRefresh) {\n client.getAuthenticationInfoOrNull()\n clientState.refreshInterval = window.setInterval(client.getAuthenticationInfoOrNull, 60000)\n }\n }\n\n return client\n}\n"],"names":["assign","target","i","arguments","length","source","key","api","init","converter","defaultAttributes","set","name","value","attributes","document","expires","Date","now","toUTCString","encodeURIComponent","replace","decodeURIComponent","escape","stringifiedAttributes","attributeName","split","cookie","write","Object","create","get","cookies","jar","parts","slice","join","found","read","e","remove","withAttributes","this","withConverter","freeze","path","ACTIVE_ORG_ID_COOKIE_NAME","OrgRoleStructure","UserClass","constructor","userFields","orgIdToUserOrgInfo","userId","email","firstName","lastName","username","createdAt","pictureUrl","hasPassword","hasMfaEnabled","canCreateOrgs","legacyUserId","impersonatorUserId","properties","getOrg","orgId","getOrgByName","orgName","urlSafeOrgName","toLowerCase","orgMemberInfo","getUserProperty","getOrgs","values","isImpersonating","isRole","role","isAtLeastRole","hasPermission","permission","hasAllPermissions","permissions","fromJSON","json","obj","JSON","parse","OrgMemberInfoClass","stringify","console","error","orgMetadata","userAssignedRole","userInheritedRolesPlusCurrentRole","userPermissions","orgRoleStructure","userAssignedAdditionalRoles","legacyOrgId","SingleRole","MultiRole","includes","every","fetchAuthenticationInfo","authUrl","activeOrgId","queryParams","URLSearchParams","append","toString","fetch","method","credentials","headers","then","res","status","logCorsError","Promise","reject","message","ok","text","httpResponse","authInfoWithoutExtraArgs","orgIdToOrgMemberInfo","orgHelper","hasOwnProperty","getOrgIds","keys","accessHelper","undefined","getAccessHelperWithOrgId","getAccessHelper","userClass","user","mfaEnabled","convertOrgIdToOrgMemberInfo","resolve","withExtraArgs","str","accessToken","expiresAtSeconds","emailConfirmed","lastActiveAt","parseResponse","statusText","runWithRetriesOnAnyError","async","runWithRetriesInner","fn","numRetriesLeft","delay","numRetriesLeftToDelay","ms","setTimeout","currentTimeSeconds","hasLocalStorage","localStorage","getLocalStorageNumber","getItem","num","parseInt","Number","isNaN","LOGGED_IN_AT_KEY","LOGGED_OUT_AT_KEY","DEFAULT_MIN_SECONDS_BEFORE_REFRESH","encodeBase64","window","btoa","authOptions","minSecondsBeforeRefresh","URL","origin","Error","enableBackgroundTokenRefresh","validateAndCleanupOptions","clientState","initialLoadFinished","authenticationInfo","observers","accessTokenObservers","lastLoggedInAtMessage","lastLoggedOutAtMessage","refreshInterval","lastRefresh","accessTokenActiveOrgMap","notifyObservers","isLoggedIn","observer","setAuthenticationInfoAndUpdateDownstream","_clientState$authenti","previousAccessToken","userJustLoggedOut","userJustLoggedIn","loggedInAt","setItem","String","updateLastLoggedInAt","loggedOutAt","updateLastLoggedOutAt","notifyObserversOfAccessTokenChange","forceRefreshToken","returnCached","getSignupPageUrl","options","qs","url","postSignupRedirectUrl","userSignupQueryParameters","entries","forEach","getLoginPageUrl","postLoginRedirectUrl","getAccountPageUrl","redirectBackToUrl","getOrgPageUrl","getCreateOrgPageUrl","getSetupSAMLPageUrl","client","addLoggedInChangeObserver","loggedInChangeObserver","push","removeLoggedInChangeObserver","observerIndex","indexOf","splice","addAccessTokenChangeObserver","removeAccessTokenChangeObserver","getAuthenticationInfoOrNull","forceRefresh","currentTimeSecs","getAccessTokenForOrg","activeOrgAccessToken","fetchedAt","redirectToSignupPage","location","href","redirectToLoginPage","redirectToAccountPage","redirectToOrgPage","redirectToCreateOrgPage","redirectToSetupSAMLPage","logout","redirectAfterLogout","logoutResponse","redirect_to","destroy","removeEventListener","onStorageChange","onOnlineOrFocus","disableRefreshOnFocus","clearInterval","addEventListener","setInterval","getActiveOrgId","Cookies","sameSite","secure"],"mappings":"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"}