{"version":3,"file":"authorization-Un7v7f6J.mjs","names":["TYPES_TO_OBJECTS: TypesToConfig","checkOrgAuthorization: CheckOrgAuthorization","checkBillingAuthorization: CheckBillingAuthorization","org: string[]","user: string[]","config","checkReverificationAuthorization: CheckReverificationAuthorization"],"sources":["../../src/authorization.ts"],"sourcesContent":["import type {\n  ActClaim,\n  CheckAuthorizationWithCustomPermissions,\n  GetToken,\n  JwtPayload,\n  OrganizationCustomPermissionKey,\n  OrganizationCustomRoleKey,\n  PendingSessionOptions,\n  ReverificationConfig,\n  SessionStatusClaim,\n  SessionVerificationLevel,\n  SessionVerificationTypes,\n  SignOut,\n  UseAuthReturn,\n} from './types';\n\ntype TypesToConfig = Record<SessionVerificationTypes, Exclude<ReverificationConfig, SessionVerificationTypes>>;\ntype AuthorizationOptions = {\n  userId: string | null | undefined;\n  orgId: string | null | undefined;\n  orgRole: string | null | undefined;\n  orgPermissions: string[] | null | undefined;\n  factorVerificationAge: [number, number] | null;\n  features: string | null | undefined;\n  plans: string | null | undefined;\n};\n\ntype CheckOrgAuthorization = (\n  params: { role?: OrganizationCustomRoleKey; permission?: OrganizationCustomPermissionKey },\n  options: Pick<AuthorizationOptions, 'orgId' | 'orgRole' | 'orgPermissions'>,\n) => boolean | null;\n\ntype CheckBillingAuthorization = (\n  params: { feature?: string; plan?: string },\n  options: Pick<AuthorizationOptions, 'plans' | 'features'>,\n) => boolean | null;\n\ntype CheckReverificationAuthorization = (\n  params: {\n    reverification?: ReverificationConfig;\n  },\n  { factorVerificationAge }: AuthorizationOptions,\n) => boolean | null;\n\nconst TYPES_TO_OBJECTS: TypesToConfig = {\n  strict_mfa: {\n    afterMinutes: 10,\n    level: 'multi_factor',\n  },\n  strict: {\n    afterMinutes: 10,\n    level: 'second_factor',\n  },\n  moderate: {\n    afterMinutes: 60,\n    level: 'second_factor',\n  },\n  lax: {\n    afterMinutes: 1_440,\n    level: 'second_factor',\n  },\n};\n\nconst ALLOWED_LEVELS = new Set<SessionVerificationLevel>(['first_factor', 'second_factor', 'multi_factor']);\n\nconst ALLOWED_TYPES = new Set<SessionVerificationTypes>(['strict_mfa', 'strict', 'moderate', 'lax']);\n\nconst ORG_SCOPES = new Set(['o', 'org', 'organization']);\nconst USER_SCOPES = new Set(['u', 'user']);\n\n// Helper functions\nconst isValidMaxAge = (maxAge: any) => typeof maxAge === 'number' && maxAge > 0;\nconst isValidLevel = (level: any) => ALLOWED_LEVELS.has(level);\nconst isValidVerificationType = (type: any) => ALLOWED_TYPES.has(type);\n\nconst prefixWithOrg = (value: string) => value.replace(/^(org:)*/, 'org:');\n\n/**\n * Checks if a user has the required organization-level authorization.\n * Verifies if the user has the specified role or permission within their organization.\n *\n * @returns null, if unable to determine due to missing data or unspecified role/permission.\n */\nconst checkOrgAuthorization: CheckOrgAuthorization = (params, options) => {\n  const { orgId, orgRole, orgPermissions } = options;\n  if (!params.role && !params.permission) {\n    return null;\n  }\n\n  if (!orgId || !orgRole || !orgPermissions) {\n    return null;\n  }\n\n  if (params.permission) {\n    return orgPermissions.includes(prefixWithOrg(params.permission));\n  }\n\n  if (params.role) {\n    return prefixWithOrg(orgRole) === prefixWithOrg(params.role);\n  }\n  return null;\n};\n\nconst checkForFeatureOrPlan = (claim: string, featureOrPlan: string) => {\n  const { org: orgFeatures, user: userFeatures } = splitByScope(claim);\n  const [rawScope, rawId] = featureOrPlan.split(':');\n  const hasExplicitScope = rawId !== undefined;\n  const scope = rawScope;\n  const id = rawId || rawScope;\n\n  if (hasExplicitScope && !ORG_SCOPES.has(scope) && !USER_SCOPES.has(scope)) {\n    throw new Error(`Invalid scope: ${scope}`);\n  }\n\n  if (hasExplicitScope) {\n    if (ORG_SCOPES.has(scope)) {\n      return orgFeatures.includes(id);\n    }\n    if (USER_SCOPES.has(scope)) {\n      return userFeatures.includes(id);\n    }\n  }\n\n  // Since org scoped features will not exist if there is not an active org, merging is safe.\n  return [...orgFeatures, ...userFeatures].includes(id);\n};\n\nconst checkBillingAuthorization: CheckBillingAuthorization = (params, options) => {\n  const { features, plans } = options;\n\n  if (params.feature && features) {\n    return checkForFeatureOrPlan(features, params.feature);\n  }\n\n  if (params.plan && plans) {\n    return checkForFeatureOrPlan(plans, params.plan);\n  }\n  return null;\n};\n\nconst splitByScope = (fea: string | null | undefined) => {\n  const org: string[] = [];\n  const user: string[] = [];\n\n  if (!fea) {\n    return { org, user };\n  }\n\n  const parts = fea.split(',');\n  for (let i = 0; i < parts.length; i++) {\n    const part = parts[i].trim();\n    const colonIndex = part.indexOf(':');\n    if (colonIndex === -1) {\n      throw new Error(`Invalid claim element (missing colon): ${part}`);\n    }\n    const scope = part.slice(0, colonIndex);\n    const value = part.slice(colonIndex + 1);\n\n    if (scope === 'o') {\n      org.push(value);\n    } else if (scope === 'u') {\n      user.push(value);\n    } else if (scope === 'ou' || scope === 'uo') {\n      org.push(value);\n      user.push(value);\n    }\n  }\n\n  return { org, user };\n};\n\nconst validateReverificationConfig = (config: ReverificationConfig | undefined | null) => {\n  if (!config) {\n    return false;\n  }\n\n  const convertConfigToObject = (config: ReverificationConfig) => {\n    if (typeof config === 'string') {\n      return TYPES_TO_OBJECTS[config];\n    }\n    return config;\n  };\n\n  const isValidStringValue = typeof config === 'string' && isValidVerificationType(config);\n  const isValidObjectValue =\n    typeof config === 'object' && isValidLevel(config.level) && isValidMaxAge(config.afterMinutes);\n\n  if (isValidStringValue || isValidObjectValue) {\n    return convertConfigToObject.bind(null, config);\n  }\n\n  return false;\n};\n\n/**\n * Evaluates if the user meets re-verification authentication requirements.\n * Compares the user's factor verification ages against the specified maxAge.\n * Handles different verification levels (first factor, second factor, multi-factor).\n *\n * @returns null, if requirements or verification data are missing.\n */\nconst checkReverificationAuthorization: CheckReverificationAuthorization = (params, { factorVerificationAge }) => {\n  if (!params.reverification || !factorVerificationAge) {\n    return null;\n  }\n\n  const isValidReverification = validateReverificationConfig(params.reverification);\n  if (!isValidReverification) {\n    return null;\n  }\n\n  const { level, afterMinutes } = isValidReverification();\n  const [factor1Age, factor2Age] = factorVerificationAge;\n\n  // -1 indicates the factor group (1fa,2fa) is not enabled\n  // -1 for 1fa is not a valid scenario, but we need to make sure we handle it properly\n  const isValidFactor1 = factor1Age !== -1 ? afterMinutes > factor1Age : null;\n  const isValidFactor2 = factor2Age !== -1 ? afterMinutes > factor2Age : null;\n\n  switch (level) {\n    case 'first_factor':\n      return isValidFactor1;\n    case 'second_factor':\n      return factor2Age !== -1 ? isValidFactor2 : isValidFactor1;\n    case 'multi_factor':\n      return factor2Age === -1 ? isValidFactor1 : isValidFactor1 && isValidFactor2;\n  }\n};\n\n/**\n * Creates a function for comprehensive user authorization checks.\n * Combines organization-level and reverification authentication checks.\n * The returned function authorizes if both checks pass, or if at least one passes\n * when the other is indeterminate. Fails if userId is missing.\n */\nconst createCheckAuthorization = (options: AuthorizationOptions): CheckAuthorizationWithCustomPermissions => {\n  return (params): boolean => {\n    if (!options.userId) {\n      return false;\n    }\n\n    const billingAuthorization = checkBillingAuthorization(params, options);\n    const orgAuthorization = checkOrgAuthorization(params, options);\n    const reverificationAuthorization = checkReverificationAuthorization(params, options);\n\n    if ([billingAuthorization || orgAuthorization, reverificationAuthorization].some(a => a === null)) {\n      return [billingAuthorization || orgAuthorization, reverificationAuthorization].some(a => a === true);\n    }\n\n    return [billingAuthorization || orgAuthorization, reverificationAuthorization].every(a => a === true);\n  };\n};\n\ntype AuthStateOptions = {\n  authObject: {\n    userId?: string | null;\n    sessionId?: string | null;\n    sessionStatus?: SessionStatusClaim | null;\n    sessionClaims?: JwtPayload | null;\n    actor?: ActClaim | null;\n    orgId?: string | null;\n    orgRole?: OrganizationCustomRoleKey | null;\n    orgSlug?: string | null;\n    orgPermissions?: OrganizationCustomPermissionKey[] | null;\n    getToken: GetToken;\n    signOut: SignOut;\n    has: (params: Parameters<CheckAuthorizationWithCustomPermissions>[0]) => boolean;\n  };\n  options: PendingSessionOptions;\n};\n\n/**\n * Shared utility function that centralizes auth state resolution logic,\n * preventing duplication across different packages.\n *\n * @internal\n */\nconst resolveAuthState = ({\n  authObject: {\n    sessionId,\n    sessionStatus,\n    userId,\n    actor,\n    orgId,\n    orgRole,\n    orgSlug,\n    signOut,\n    getToken,\n    has,\n    sessionClaims,\n  },\n  options: { treatPendingAsSignedOut = true },\n}: AuthStateOptions): UseAuthReturn | undefined => {\n  if (sessionId === undefined && userId === undefined) {\n    return {\n      actor: undefined,\n      getToken,\n      has: () => false,\n      isLoaded: false,\n      isSignedIn: undefined,\n      orgId: undefined,\n      orgRole: undefined,\n      orgSlug: undefined,\n      sessionClaims: undefined,\n      sessionId,\n      signOut,\n      userId,\n    } as const;\n  }\n\n  if (sessionId === null && userId === null) {\n    return {\n      actor: null,\n      getToken,\n      has: () => false,\n      isLoaded: true,\n      isSignedIn: false,\n      orgId: null,\n      orgRole: null,\n      orgSlug: null,\n      sessionClaims: null,\n      sessionId,\n      signOut,\n      userId,\n    } as const;\n  }\n\n  if (treatPendingAsSignedOut && sessionStatus === 'pending') {\n    return {\n      actor: null,\n      getToken,\n      has: () => false,\n      isLoaded: true,\n      isSignedIn: false,\n      orgId: null,\n      orgRole: null,\n      orgSlug: null,\n      sessionClaims: null,\n      sessionId: null,\n      signOut,\n      userId: null,\n    } as const;\n  }\n\n  if (!!sessionId && !!sessionClaims && !!userId && !!orgId && !!orgRole) {\n    return {\n      actor: actor || null,\n      getToken,\n      has,\n      isLoaded: true,\n      isSignedIn: true,\n      orgId,\n      orgRole,\n      orgSlug: orgSlug || null,\n      sessionClaims,\n      sessionId,\n      signOut,\n      userId,\n    } as const;\n  }\n\n  if (!!sessionId && !!sessionClaims && !!userId && !orgId) {\n    return {\n      actor: actor || null,\n      getToken,\n      has,\n      isLoaded: true,\n      isSignedIn: true,\n      orgId: null,\n      orgRole: null,\n      orgSlug: null,\n      sessionClaims,\n      sessionId,\n      signOut,\n      userId,\n    } as const;\n  }\n};\n\nexport { createCheckAuthorization, resolveAuthState, splitByScope, validateReverificationConfig };\n"],"mappings":"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"}