{"version":3,"sources":["../src/paths.ts","../src/betterauth.ts"],"names":[],"mappings":";;;AAoBO,IAAM,UAAA,GAAa;AAAA;AAAA,EAExB,SAAA,EAAW,mCAAA;AAAA;AAAA,EAEX,SAAA,EAAW,yBAAA;AAAA;AAAA,EAEX,KAAA,EAAO,qBAAA;AAAA;AAAA,EAEP,QAAA,EAAU,wBAAA;AAAA;AAAA,EAEV,IAAA,EAAM,0BAAA;AAAA;AAAA,EAEN,MAAA,EAAQ;AACV,CAAA;AA2DO,SAAS,cAAc,SAAA,EAA2B;AACvD,EAAA,OAAO,SAAA,CAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AACrC;AAQO,SAAS,MAAA,CAAO,WAAmB,GAAA,EAA0B;AAClE,EAAA,OAAO,GAAG,aAAA,CAAc,SAAS,CAAC,CAAA,EAAG,UAAA,CAAW,GAAG,CAAC,CAAA,CAAA;AACtD;;;ACtCO,SAAS,YAAY,MAAA,EAAuC;AACjE,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,OAAA;AAAA,IACZ,gBAAA,EAAkB,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,WAAW,CAAA;AAAA,IACtD,QAAA,EAAU,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAO,CAAA;AAAA,IAC1C,WAAA,EAAa,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,UAAU,CAAA;AAAA,IAChD,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,cAAc,MAAA,CAAO,YAAA;AAAA,IACrB,MAAA,EAAQ,CAAC,QAAA,EAAU,SAAA,EAAW,OAAO,CAAA;AAAA,IACrC,IAAA,EAAM,IAAA;AAAA,IACN,cAAA,EAAgB;AAAA,GAClB;AACF","file":"betterauth.cjs","sourcesContent":["/**\n * The single source of truth for Hanzo IAM OIDC endpoint paths.\n *\n * Hanzo IAM is a Casdoor-derived OIDC provider served per-brand from a\n * configurable origin (`serverUrl`): hanzo → https://iam.hanzo.ai,\n * lux → https://lux.id, zoo → https://zoo.id, bootnode → https://id.bootno.de.\n *\n * These are the ONLY paths. There is no legacy `/oauth/*` and no\n * `/api/login/*`. Every module in this SDK references `OIDC_PATHS` —\n * no path string is written anywhere else.\n *\n * CRITICAL GOTCHA: IAM serves a 200 `text/html` SPA catch-all for ANY\n * unregistered path. A client that hits a wrong path therefore gets a\n * 200 HTML body, not a 404 — silent breakage. So clients MUST hit these\n * exact paths, and a discovery round-trip must never be allowed to\n * resolve to a different path. The hard-coded fallbacks here are these\n * same values, so a failed discovery degrades to correct paths.\n */\n\n/** OIDC endpoint paths, relative to the brand `serverUrl`. */\nexport const OIDC_PATHS = {\n  /** OIDC discovery document. */\n  discovery: \"/.well-known/openid-configuration\",\n  /** Authorization endpoint (RFC 6749 §3.1). */\n  authorize: \"/v1/iam/oauth/authorize\",\n  /** Token endpoint (RFC 6749 §3.2). */\n  token: \"/v1/iam/oauth/token\",\n  /** UserInfo endpoint (OIDC Core §5.3). */\n  userinfo: \"/v1/iam/oauth/userinfo\",\n  /** JWKS endpoint (RFC 7517). */\n  jwks: \"/v1/iam/.well-known/jwks\",\n  /** RP-initiated logout endpoint (OIDC RP-Initiated Logout). */\n  logout: \"/v1/iam/oauth/logout\",\n} as const;\n\nexport type OidcPathKey = keyof typeof OIDC_PATHS;\n\n/**\n * Hanzo-IAM application paths that are NOT part of the OIDC spec — the\n * auth-method discovery endpoint and the onboarding state machine the\n * embedded views drive. Mounted under the same `/v1/iam` prefix.\n */\nexport const IAM_PATHS = {\n  /** Live list of enabled auth methods for the embedded login views. */\n  authMethods: \"/v1/iam/auth/methods\",\n  /** Onboarding state-machine base (steps append `/identity`, etc.). */\n  onboarding: \"/v1/iam/onboarding\",\n  /**\n   * Casdoor credential-login endpoint the embedded `<Login>` views POST to.\n   * `type=code` (a client `redirectUri` is present) mints an authorization\n   * code returned in `data`; `type=login` establishes the session cookie.\n   * This is what the deployed IAM actually authenticates against — the OIDC\n   * token endpoint's password/OTP grants are NOT enabled per-client.\n   */\n  login: \"/v1/iam/login\",\n  /** Send an email/SMS verification code (passwordless login). */\n  sendCode: \"/v1/iam/send-verification-code\",\n  /** Account registration. */\n  signup: \"/v1/iam/signup\",\n} as const;\n\nexport type IamPathKey = keyof typeof IAM_PATHS;\n\n/**\n * The canonical `serverUrl` origin for each Hanzo IAM brand. White-label\n * is host-based: one IAM deployment serves every brand and selects the\n * tenant by the origin it is reached on. This is the SINGLE place the\n * brand→origin mapping lives — adapters take a `brand` and resolve here\n * rather than each app hard-coding a hostname.\n */\nexport const BRAND_SERVER_URLS = {\n  hanzo: \"https://iam.hanzo.ai\",\n  lux: \"https://lux.id\",\n  zoo: \"https://zoo.id\",\n  bootnode: \"https://id.bootno.de\",\n  pars: \"https://pars.id\",\n} as const;\n\n/** A known Hanzo IAM brand key. */\nexport type IamBrand = keyof typeof BRAND_SERVER_URLS;\n\n/**\n * Resolve a brand to its canonical IAM `serverUrl`.\n *\n * @example\n * serverUrlForBrand(\"lux\") // → \"https://lux.id\"\n */\nexport function serverUrlForBrand(brand: IamBrand): string {\n  return BRAND_SERVER_URLS[brand];\n}\n\n/** Strip trailing slashes from a server origin so paths concat cleanly. */\nexport function trimServerUrl(serverUrl: string): string {\n  return serverUrl.replace(/\\/+$/, \"\");\n}\n\n/**\n * Build an absolute IAM endpoint URL from a server origin and a path key.\n *\n * @example\n * iamUrl(\"https://iam.hanzo.ai\", \"token\") // → \"https://iam.hanzo.ai/v1/iam/oauth/token\"\n */\nexport function iamUrl(serverUrl: string, key: OidcPathKey): string {\n  return `${trimServerUrl(serverUrl)}${OIDC_PATHS[key]}`;\n}\n","/**\n * better-auth `genericOAuth` provider configuration for Hanzo IAM.\n *\n * Returns ONE config entry to drop into better-auth's `genericOAuth`\n * plugin. The endpoints are pinned to the canonical IAM OIDC paths\n * (`OIDC_PATHS`) — no `discoveryUrl`, because IAM serves a 200 HTML SPA\n * catch-all for unregistered paths and a discovery round-trip must never\n * be allowed to resolve to the wrong path.\n *\n * @example\n * ```ts\n * import { betterAuth } from \"better-auth\";\n * import { genericOAuth } from \"better-auth/plugins\";\n * import { iamProvider } from \"@hanzo/iam/betterauth\";\n *\n * export const auth = betterAuth({\n *   plugins: [\n *     genericOAuth({\n *       config: [\n *         iamProvider({\n *           serverUrl: process.env.IAM_ENDPOINT!,      // e.g. https://iam.hanzo.ai\n *           clientId: process.env.IAM_CLIENT_ID!,\n *           clientSecret: process.env.IAM_CLIENT_SECRET!,\n *         }),\n *       ],\n *     }),\n *   ],\n * });\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Config } from \"./types.js\";\nimport { iamUrl } from \"./paths.js\";\n\n/**\n * A single `genericOAuth` provider config entry, as consumed by\n * better-auth's `genericOAuth({ config: [...] })` plugin.\n */\nexport interface IamGenericOAuthConfig {\n  /** Provider id better-auth routes by. `\"hanzo\"` for all Hanzo IAM brands. */\n  providerId: string;\n  /** Authorization endpoint URL. */\n  authorizationUrl: string;\n  /** Token endpoint URL. */\n  tokenUrl: string;\n  /** UserInfo endpoint URL. */\n  userInfoUrl: string;\n  /** OAuth2 client id. */\n  clientId: string;\n  /** OAuth2 client secret (confidential client). */\n  clientSecret?: string;\n  /** Requested scopes. */\n  scopes: string[];\n  /** Enable PKCE (S256). Always true. */\n  pkce: true;\n  /** Client authentication method at the token endpoint. */\n  authentication: \"basic\";\n}\n\n/**\n * Create a better-auth `genericOAuth` config entry for Hanzo IAM.\n *\n * Pass the result inside `genericOAuth({ config: [iamProvider(...)] })`.\n */\nexport function iamProvider(config: Config): IamGenericOAuthConfig {\n  return {\n    providerId: \"hanzo\",\n    authorizationUrl: iamUrl(config.serverUrl, \"authorize\"),\n    tokenUrl: iamUrl(config.serverUrl, \"token\"),\n    userInfoUrl: iamUrl(config.serverUrl, \"userinfo\"),\n    clientId: config.clientId,\n    clientSecret: config.clientSecret,\n    scopes: [\"openid\", \"profile\", \"email\"],\n    pkce: true,\n    authentication: \"basic\",\n  };\n}\n"]}