{"version":3,"file":"HeadlessB2BRBACClient.mjs","sources":["../../../../../../../../core/src/HeadlessClients/b2b/HeadlessB2BRBACClient.ts"],"sourcesContent":["import { IHeadlessB2BRBACClient, PermissionsMap } from '../../public/b2b/rbac';\nimport { StytchProjectConfigurationInput } from '../../public/typeConfig';\nimport { RBACPolicy, RBACPolicyRaw } from '../../rbac';\nimport { IB2BSubscriptionService } from '../../SubscriptionService';\nimport { logger } from '../../utils';\n\ntype CachedConfig = {\n  rbacPolicy: RBACPolicyRaw | null;\n};\n\ntype DynamicConfig = Promise<CachedConfig>;\n\nexport class HeadlessB2BRBACClient<TProjectConfiguration extends StytchProjectConfigurationInput>\n  implements IHeadlessB2BRBACClient\n{\n  private cachedPolicy: RBACPolicy | null;\n  private policyPromise: Promise<RBACPolicy>;\n  constructor(\n    cachedConfig: CachedConfig,\n    dynamicConfig: DynamicConfig,\n    private _subscriptionService: IB2BSubscriptionService<TProjectConfiguration>,\n  ) {\n    this.cachedPolicy = cachedConfig.rbacPolicy ? RBACPolicy.fromJSON(cachedConfig.rbacPolicy) : null;\n    this.policyPromise = dynamicConfig.then((data) => {\n      if (!data.rbacPolicy) {\n        logger.error('Unable to retrieve RBAC policy from servers. Assuming caller has no permissions.');\n        return new RBACPolicy([], []);\n      }\n      // Update the existing policy too, so isAuthorizedSync will be up-to-date\n      this.cachedPolicy = RBACPolicy.fromJSON(data.rbacPolicy);\n      return this.cachedPolicy;\n    });\n  }\n\n  /**\n   * Gets the effective policy for the current session by merging project policy with org custom roles\n   */\n  private async getEffectivePolicy(): Promise<RBACPolicy> {\n    const projectPolicy = await this.policyPromise;\n    const organization = this._subscriptionService.getOrganization();\n\n    // If no org or no custom roles, just return project policy\n    if (!organization?.custom_roles?.length) {\n      return projectPolicy;\n    }\n\n    return projectPolicy.mergeWithCustomRoles(organization.custom_roles);\n  }\n\n  /**\n   * Gets the effective policy synchronously for the current session\n   * Uses cached policies only\n   */\n  private getEffectivePolicySync(): RBACPolicy | null {\n    if (!this.cachedPolicy) {\n      return null;\n    }\n\n    const organization = this._subscriptionService.getOrganization();\n\n    // If no custom roles, just return project policy\n    if (!organization?.custom_roles?.length) {\n      return this.cachedPolicy;\n    }\n\n    return this.cachedPolicy.mergeWithCustomRoles(organization.custom_roles);\n  }\n\n  allPermissions<Permissions extends Record<string, string>>() {\n    return this.getEffectivePolicy().then(\n      (policy) => policy.allPermissionsForCaller(this.roleIds()) as PermissionsMap<Permissions>,\n    );\n  }\n\n  isAuthorizedSync: IHeadlessB2BRBACClient['isAuthorizedSync'] = (resourceId, action) => {\n    const effectivePolicy = this.getEffectivePolicySync();\n    return !!effectivePolicy?.callerIsAuthorized(this.roleIds(), resourceId as string, action as unknown as string);\n  };\n\n  isAuthorized: IHeadlessB2BRBACClient['isAuthorized'] = (resourceId, action) => {\n    return this.getEffectivePolicy().then((policy) =>\n      policy.callerIsAuthorized(this.roleIds(), resourceId as string, action as unknown as string),\n    );\n  };\n\n  private roleIds() {\n    const session = this._subscriptionService.getSession();\n    if (!session) {\n      return [];\n    }\n    // Although session.roles is guaranteed to exist for fresh data, there is a minuscule chance\n    // that the member session stored in localstorage clientside comes from before roles were added to\n    // the API response - in which case session.roles will be undefined and this will crash\n    // TODO: [AUTH-2294] We can safely remove this ~3mos after RBAC is released\n    return session.roles ?? [];\n  }\n}\n"],"names":["HeadlessB2BRBACClient","cachedPolicy","policyPromise","cachedConfig","dynamicConfig","_subscriptionService","rbacPolicy","RBACPolicy","fromJSON","then","data","logger","error","getEffectivePolicy","projectPolicy","organization","getOrganization","custom_roles","length","mergeWithCustomRoles","getEffectivePolicySync","allPermissions","policy","allPermissionsForCaller","roleIds","isAuthorizedSync","resourceId","action","effectivePolicy","callerIsAuthorized","isAuthorized","session","getSession","roles"],"mappings":"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"}