@hanzo/iam 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/auth.d.ts +1 -1
  2. package/dist/auth.js +3 -3
  3. package/dist/auth.js.map +1 -1
  4. package/dist/betterauth.d.ts +67 -0
  5. package/dist/betterauth.d.ts.map +1 -0
  6. package/dist/betterauth.js +64 -0
  7. package/dist/betterauth.js.map +1 -0
  8. package/dist/browser.d.ts +87 -4
  9. package/dist/browser.d.ts.map +1 -1
  10. package/dist/browser.js +229 -8
  11. package/dist/browser.js.map +1 -1
  12. package/dist/client.d.ts +11 -22
  13. package/dist/client.d.ts.map +1 -1
  14. package/dist/client.js +39 -96
  15. package/dist/client.js.map +1 -1
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -3
  19. package/dist/index.js.map +1 -1
  20. package/dist/nextauth.d.ts +12 -10
  21. package/dist/nextauth.d.ts.map +1 -1
  22. package/dist/nextauth.js +12 -11
  23. package/dist/nextauth.js.map +1 -1
  24. package/dist/passport.d.ts +44 -0
  25. package/dist/passport.d.ts.map +1 -0
  26. package/dist/passport.js +67 -0
  27. package/dist/passport.js.map +1 -0
  28. package/dist/pkce.d.ts +2 -2
  29. package/dist/pkce.js +2 -2
  30. package/dist/react.d.ts +8 -94
  31. package/dist/react.d.ts.map +1 -1
  32. package/dist/react.js +23 -454
  33. package/dist/react.js.map +1 -1
  34. package/dist/types.d.ts +1 -16
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/types.js +1 -1
  37. package/package.json +16 -7
  38. package/src/auth.ts +3 -3
  39. package/src/betterauth.ts +91 -0
  40. package/src/browser.ts +255 -11
  41. package/src/client.ts +47 -154
  42. package/src/index.ts +3 -4
  43. package/src/nextauth.ts +15 -13
  44. package/src/passport.ts +97 -0
  45. package/src/pkce.ts +2 -2
  46. package/src/react.ts +28 -635
  47. package/src/types.ts +1 -21
package/dist/auth.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * JWT validation using jose library + OIDC JWKS discovery.
3
3
  *
4
- * Validates access/ID tokens issued by Hanzo IAM (Casdoor).
4
+ * Validates access/ID tokens issued by Hanzo IAM.
5
5
  */
6
6
  import type { IamConfig, IamAuthResult } from "./types.js";
7
7
  /** Clear cached JWKS key sets (useful for testing or key rotation). */
package/dist/auth.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * JWT validation using jose library + OIDC JWKS discovery.
3
3
  *
4
- * Validates access/ID tokens issued by Hanzo IAM (Casdoor).
4
+ * Validates access/ID tokens issued by Hanzo IAM.
5
5
  */
6
6
  import { createRemoteJWKSet, jwtVerify } from "jose";
7
7
  // ---------------------------------------------------------------------------
@@ -90,7 +90,7 @@ export async function validateToken(token, config) {
90
90
  return { ok: false, reason: "iam_token_expired" };
91
91
  }
92
92
  if (message.includes("audience")) {
93
- // Retry without audience check - some Casdoor configs don't set aud
93
+ // Retry without audience check - some IAM configs don't set aud
94
94
  try {
95
95
  const result = await jwtVerify(token, keySet, {
96
96
  issuer,
@@ -115,7 +115,7 @@ export async function validateToken(token, config) {
115
115
  if (!sub) {
116
116
  return { ok: false, reason: "iam_subject_missing" };
117
117
  }
118
- // Casdoor sub format is "org/username" - extract owner
118
+ // IAM sub format is "org/username" - extract owner
119
119
  const parts = sub.split("/");
120
120
  const owner = parts.length > 1 ? parts[0] : config.orgName ?? "unknown";
121
121
  return {
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * BetterAuth SSO provider configuration for IAM.
3
+ *
4
+ * Returns a provider config object compatible with BetterAuth's
5
+ * `socialProviders` or generic OAuth plugin.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { betterAuth } from "better-auth";
10
+ * import { iamProvider } from "@hanzo/iam/betterauth";
11
+ *
12
+ * export const auth = betterAuth({
13
+ * socialProviders: [
14
+ * iamProvider({
15
+ * serverUrl: process.env.IAM_SERVER_URL!,
16
+ * clientId: process.env.IAM_CLIENT_ID!,
17
+ * clientSecret: process.env.IAM_CLIENT_SECRET!,
18
+ * }),
19
+ * ],
20
+ * });
21
+ * ```
22
+ *
23
+ * @packageDocumentation
24
+ */
25
+ import type { IamConfig } from "./types.js";
26
+ export interface IamSocialProvider {
27
+ id: string;
28
+ name: string;
29
+ type: "oidc";
30
+ issuer: string;
31
+ clientId: string;
32
+ clientSecret?: string;
33
+ authorization: {
34
+ url: string;
35
+ params: {
36
+ scope: string;
37
+ };
38
+ };
39
+ token: {
40
+ url: string;
41
+ };
42
+ userinfo: {
43
+ url: string;
44
+ };
45
+ profile: (profile: Record<string, unknown>) => {
46
+ id: string;
47
+ name: string;
48
+ email: string;
49
+ image: string | null;
50
+ };
51
+ }
52
+ /**
53
+ * Create a BetterAuth-compatible social provider for IAM.
54
+ *
55
+ * Works with BetterAuth's SSO plugin or generic OAuth integration.
56
+ * Uses standard OIDC endpoints.
57
+ */
58
+ export declare function iamProvider(config: IamConfig & {
59
+ redirectUri?: string;
60
+ }): IamSocialProvider;
61
+ /** @deprecated Use iamProvider instead */
62
+ export { iamProvider as hanzoIamProvider };
63
+ /** @deprecated Use iamProvider instead */
64
+ export { iamProvider as hanzoIamSocialProvider };
65
+ /** @deprecated Use IamSocialProvider instead */
66
+ export type { IamSocialProvider as HanzoIamSocialProvider };
67
+ //# sourceMappingURL=betterauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"betterauth.d.ts","sourceRoot":"","sources":["../src/betterauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAC1D,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;QAC7C,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;KACtB,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,SAAS,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,iBAAiB,CA6BnB;AAGD,0CAA0C;AAC1C,OAAO,EAAE,WAAW,IAAI,gBAAgB,EAAE,CAAC;AAC3C,0CAA0C;AAC1C,OAAO,EAAE,WAAW,IAAI,sBAAsB,EAAE,CAAC;AACjD,gDAAgD;AAChD,YAAY,EAAE,iBAAiB,IAAI,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * BetterAuth SSO provider configuration for IAM.
3
+ *
4
+ * Returns a provider config object compatible with BetterAuth's
5
+ * `socialProviders` or generic OAuth plugin.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { betterAuth } from "better-auth";
10
+ * import { iamProvider } from "@hanzo/iam/betterauth";
11
+ *
12
+ * export const auth = betterAuth({
13
+ * socialProviders: [
14
+ * iamProvider({
15
+ * serverUrl: process.env.IAM_SERVER_URL!,
16
+ * clientId: process.env.IAM_CLIENT_ID!,
17
+ * clientSecret: process.env.IAM_CLIENT_SECRET!,
18
+ * }),
19
+ * ],
20
+ * });
21
+ * ```
22
+ *
23
+ * @packageDocumentation
24
+ */
25
+ /**
26
+ * Create a BetterAuth-compatible social provider for IAM.
27
+ *
28
+ * Works with BetterAuth's SSO plugin or generic OAuth integration.
29
+ * Uses standard OIDC endpoints.
30
+ */
31
+ export function iamProvider(config) {
32
+ const baseUrl = config.serverUrl.replace(/\/+$/, "");
33
+ return {
34
+ id: "iam",
35
+ name: "IAM",
36
+ type: "oidc",
37
+ issuer: baseUrl,
38
+ clientId: config.clientId,
39
+ clientSecret: config.clientSecret,
40
+ authorization: {
41
+ url: `${baseUrl}/oauth/authorize`,
42
+ params: { scope: "openid profile email" },
43
+ },
44
+ token: { url: `${baseUrl}/oauth/token` },
45
+ userinfo: { url: `${baseUrl}/oauth/userinfo` },
46
+ profile(profile) {
47
+ return {
48
+ id: profile.sub ?? profile.id ?? "",
49
+ name: profile.displayName ??
50
+ profile.name ??
51
+ profile.preferred_username ??
52
+ "",
53
+ email: profile.email ?? "",
54
+ image: profile.avatar ?? profile.picture ?? null,
55
+ };
56
+ },
57
+ };
58
+ }
59
+ // Backwards-compatible aliases
60
+ /** @deprecated Use iamProvider instead */
61
+ export { iamProvider as hanzoIamProvider };
62
+ /** @deprecated Use iamProvider instead */
63
+ export { iamProvider as hanzoIamSocialProvider };
64
+ //# sourceMappingURL=betterauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"betterauth.js","sourceRoot":"","sources":["../src/betterauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAsBH;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,MAA4C;IAE5C,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAErD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,OAAO;QACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,aAAa,EAAE;YACb,GAAG,EAAE,GAAG,OAAO,kBAAkB;YACjC,MAAM,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;SAC1C;QACD,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,cAAc,EAAE;QACxC,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,iBAAiB,EAAE;QAC9C,OAAO,CAAC,OAAgC;YACtC,OAAO;gBACL,EAAE,EAAG,OAAO,CAAC,GAAc,IAAK,OAAO,CAAC,EAAa,IAAI,EAAE;gBAC3D,IAAI,EACD,OAAO,CAAC,WAAsB;oBAC9B,OAAO,CAAC,IAAe;oBACvB,OAAO,CAAC,kBAA6B;oBACtC,EAAE;gBACJ,KAAK,EAAG,OAAO,CAAC,KAAgB,IAAI,EAAE;gBACtC,KAAK,EAAG,OAAO,CAAC,MAAiB,IAAK,OAAO,CAAC,OAAkB,IAAI,IAAI;aACzE,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+BAA+B;AAC/B,0CAA0C;AAC1C,OAAO,EAAE,WAAW,IAAI,gBAAgB,EAAE,CAAC;AAC3C,0CAA0C;AAC1C,OAAO,EAAE,WAAW,IAAI,sBAAsB,EAAE,CAAC"}
package/dist/browser.d.ts CHANGED
@@ -4,10 +4,10 @@
4
4
  * Provides PKCE-based login redirect, code exchange, token refresh,
5
5
  * popup signin, and silent signin for single-page applications.
6
6
  *
7
- * Adapted and modernized from casdoor-js-sdk.
7
+ * Adapted and modernized for Hanzo IAM.
8
8
  */
9
9
  import type { IamConfig, TokenResponse } from "./types.js";
10
- export type BrowserIamConfig = IamConfig & {
10
+ export type IAMConfig = IamConfig & {
11
11
  /** OAuth2 redirect URI (e.g. "https://app.hanzo.bot/auth/callback"). */
12
12
  redirectUri: string;
13
13
  /** OAuth2 scopes (default: "openid profile email"). */
@@ -23,11 +23,11 @@ export type BrowserIamConfig = IamConfig & {
23
23
  */
24
24
  proxyBaseUrl?: string;
25
25
  };
26
- export declare class BrowserIamSdk {
26
+ export declare class IAM {
27
27
  private readonly config;
28
28
  private readonly storage;
29
29
  private discoveryCache;
30
- constructor(config: BrowserIamConfig);
30
+ constructor(config: IAMConfig);
31
31
  private getDiscovery;
32
32
  /**
33
33
  * Start the OAuth2 PKCE login flow by redirecting to the IAM authorize endpoint.
@@ -87,5 +87,88 @@ export declare class BrowserIamSdk {
87
87
  }): string;
88
88
  /** Build the user profile URL on the IAM server. */
89
89
  getUserProfileUrl(username: string): string;
90
+ /**
91
+ * Send a verification code to a phone or email destination.
92
+ *
93
+ * @param contact `{ phone, countryCode }` for SMS, `{ email }` for email.
94
+ * @param method Casdoor method: `login`, `signup`, `forget`, `mfaSetup`, etc.
95
+ */
96
+ sendVerificationCode(contact: {
97
+ phone: string;
98
+ countryCode: string;
99
+ } | {
100
+ email: string;
101
+ }, method?: "login" | "signup" | "forget" | "mfaSetup"): Promise<{
102
+ ok: boolean;
103
+ error?: string;
104
+ }>;
105
+ /**
106
+ * Look up whether a phone number is registered. Returns `{ exists: false }`
107
+ * on 404 or unknown numbers; `{ exists: true }` when Casdoor confirms a user.
108
+ */
109
+ lookupPhoneUser(phone: string, countryCode: string): Promise<{
110
+ exists: boolean;
111
+ error?: string;
112
+ }>;
113
+ /**
114
+ * Casdoor REST signup. Returns the new user's id on success.
115
+ *
116
+ * Phone signup flow: send phoneCode via `sendVerificationCode`, then call
117
+ * this with the OTP in `phoneCode`. Casdoor verifies the code internally.
118
+ * Email signup flow: same with `email` + `emailCode`.
119
+ */
120
+ signup(params: {
121
+ method: "email" | "phone";
122
+ name: string;
123
+ username?: string;
124
+ email?: string;
125
+ phone?: string;
126
+ countryCode?: string;
127
+ password?: string;
128
+ emailCode?: string;
129
+ phoneCode?: string;
130
+ }): Promise<{
131
+ id?: string;
132
+ ok: boolean;
133
+ error?: string;
134
+ }>;
135
+ /**
136
+ * REST login that returns an authorization code (Casdoor `/login`).
137
+ *
138
+ * Use this when you want the caller to drive the PKCE flow without a
139
+ * full redirect — collect credentials in your own UI, get a code back,
140
+ * then call `exchangeCodeForToken` to land tokens.
141
+ */
142
+ loginWithCredentials(params: {
143
+ username: string;
144
+ password: string;
145
+ type?: "code" | "token";
146
+ redirectUri?: string;
147
+ }): Promise<{
148
+ code?: string;
149
+ ok: boolean;
150
+ error?: string;
151
+ }>;
152
+ /**
153
+ * Exchange an authorization code for tokens using the stored PKCE verifier.
154
+ * Pairs with `loginWithCredentials` for a code → tokens round-trip.
155
+ */
156
+ exchangeCodeForToken(code: string, redirectUri?: string): Promise<TokenResponse>;
157
+ /**
158
+ * Phone OTP login: tries the numbered username variants Casdoor accepts
159
+ * (`{phone}`, `{countryCode}{phone}`), exchanges the resulting code for
160
+ * tokens. Returns the token response, or throws on failure.
161
+ */
162
+ loginWithPhoneOTP(params: {
163
+ phone: string;
164
+ countryCode: string;
165
+ code: string;
166
+ redirectUri?: string;
167
+ }): Promise<TokenResponse>;
168
+ /**
169
+ * Logout via Casdoor REST `/logout` (clears server-side session) and
170
+ * the local storage.
171
+ */
172
+ logout(): Promise<void>;
90
173
  }
91
174
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAC;AAmB1E,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG;IACzC,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,cAAc,CAA8B;gBAExC,MAAM,EAAE,gBAAgB;YAStB,YAAY;IAqC1B;;;;;OAKG;IACG,cAAc,CAAC,MAAM,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B3F;;;;;;OAMG;IACG,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAgFlE,+DAA+D;IACzD,kBAAkB,IAAI,OAAO,CAAC,aAAa,CAAC;IAqClD;;;OAGG;IACG,WAAW,CAAC,MAAM,CAAC,EAAE;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC3C,GAAG,OAAO,CAAC,aAAa,CAAC;IAiE1B;;;;OAIG;IACG,YAAY,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IA4DnE,OAAO,CAAC,WAAW;IAcnB,oDAAoD;IACpD,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,oCAAoC;IACpC,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,+BAA+B;IAC/B,UAAU,IAAI,MAAM,GAAG,IAAI;IAI3B,mDAAmD;IACnD,cAAc,IAAI,OAAO;IAMzB;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAgBnD,wCAAwC;IACxC,WAAW,IAAI,IAAI;IAanB,qFAAqF;IAC/E,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAsBrD,+CAA+C;IAC/C,YAAY,CAAC,MAAM,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM;IAW3D,oDAAoD;IACpD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAK5C"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
package/dist/browser.js CHANGED
@@ -4,9 +4,9 @@
4
4
  * Provides PKCE-based login redirect, code exchange, token refresh,
5
5
  * popup signin, and silent signin for single-page applications.
6
6
  *
7
- * Adapted and modernized from casdoor-js-sdk.
7
+ * Adapted and modernized for Hanzo IAM.
8
8
  */
9
- import { generatePkceChallenge, generateState } from "./pkce.js";
9
+ import { generatePKCEChallenge, generateState } from "./pkce.js";
10
10
  // ---------------------------------------------------------------------------
11
11
  // Storage keys
12
12
  // ---------------------------------------------------------------------------
@@ -17,7 +17,7 @@ const KEY_ACCESS_TOKEN = `${STORAGE_PREFIX}access_token`;
17
17
  const KEY_REFRESH_TOKEN = `${STORAGE_PREFIX}refresh_token`;
18
18
  const KEY_ID_TOKEN = `${STORAGE_PREFIX}id_token`;
19
19
  const KEY_EXPIRES_AT = `${STORAGE_PREFIX}expires_at`;
20
- export class BrowserIamSdk {
20
+ export class IAM {
21
21
  config;
22
22
  storage;
23
23
  discoveryCache = null;
@@ -34,7 +34,7 @@ export class BrowserIamSdk {
34
34
  const baseUrl = this.config.serverUrl.replace(/\/+$/, "");
35
35
  // Try fetching the OIDC discovery document. If it fails (e.g. due to
36
36
  // CORS when the IAM server doesn't send Access-Control-Allow-Origin),
37
- // construct a fallback from well-known Casdoor/Hanzo IAM endpoint paths.
37
+ // construct a fallback from well-known Hanzo IAM endpoint paths.
38
38
  try {
39
39
  const res = await fetch(`${baseUrl}/.well-known/openid-configuration`, {
40
40
  headers: { Accept: "application/json" },
@@ -49,7 +49,7 @@ export class BrowserIamSdk {
49
49
  }
50
50
  this.discoveryCache = {
51
51
  issuer: baseUrl,
52
- authorization_endpoint: `${baseUrl}/login/oauth/authorize`,
52
+ authorization_endpoint: `${baseUrl}/oauth/authorize`,
53
53
  token_endpoint: `${baseUrl}/oauth/token`,
54
54
  userinfo_endpoint: `${baseUrl}/oauth/userinfo`,
55
55
  jwks_uri: `${baseUrl}/.well-known/jwks`,
@@ -70,7 +70,7 @@ export class BrowserIamSdk {
70
70
  */
71
71
  async signinRedirect(params) {
72
72
  const discovery = await this.getDiscovery();
73
- const { codeVerifier, codeChallenge } = await generatePkceChallenge();
73
+ const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
74
74
  const state = generateState();
75
75
  this.storage.setItem(KEY_STATE, state);
76
76
  this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);
@@ -202,7 +202,7 @@ export class BrowserIamSdk {
202
202
  */
203
203
  async signinPopup(params) {
204
204
  const discovery = await this.getDiscovery();
205
- const { codeVerifier, codeChallenge } = await generatePkceChallenge();
205
+ const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
206
206
  const state = generateState();
207
207
  this.storage.setItem(KEY_STATE, state);
208
208
  this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);
@@ -260,7 +260,7 @@ export class BrowserIamSdk {
260
260
  */
261
261
  async signinSilent(timeoutMs = 5000) {
262
262
  const discovery = await this.getDiscovery();
263
- const { codeVerifier, codeChallenge } = await generatePkceChallenge();
263
+ const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
264
264
  const state = generateState();
265
265
  this.storage.setItem(KEY_STATE, state);
266
266
  this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);
@@ -409,5 +409,226 @@ export class BrowserIamSdk {
409
409
  const org = this.config.orgName ?? "built-in";
410
410
  return `${base}/users/${org}/${username}`;
411
411
  }
412
+ // -----------------------------------------------------------------------
413
+ // Casdoor REST surface (signup, OTP, REST login, phone lookup)
414
+ //
415
+ // The OIDC layer covers redirect/PKCE, token exchange, refresh, userinfo.
416
+ // These methods cover the Casdoor-native endpoints that don't have an OIDC
417
+ // analogue: phone/email OTP, custom signup with verification codes, and
418
+ // direct REST login that returns an authorization code in one round-trip
419
+ // (used as the bridge between OTP collection and `exchangeCode`).
420
+ //
421
+ // All paths are gateway-canonical (`/login`, `/signup`,
422
+ // `/send-verification-code`, `/get-phone-user`) — point `serverUrl` at the
423
+ // gateway prefix (e.g. `https://api.dev.satschel.com/v1/iam`) and the
424
+ // gateway proxies to Casdoor's `/api/*` internally.
425
+ // -----------------------------------------------------------------------
426
+ /**
427
+ * Send a verification code to a phone or email destination.
428
+ *
429
+ * @param contact `{ phone, countryCode }` for SMS, `{ email }` for email.
430
+ * @param method Casdoor method: `login`, `signup`, `forget`, `mfaSetup`, etc.
431
+ */
432
+ async sendVerificationCode(contact, method = "login") {
433
+ const isPhone = "phone" in contact;
434
+ const dest = isPhone ? contact.phone : contact.email;
435
+ const params = {
436
+ applicationId: `admin/${this.config.appName ?? "app"}`,
437
+ dest,
438
+ type: isPhone ? "phone" : "email",
439
+ method,
440
+ captchaType: "none",
441
+ captchaToken: "",
442
+ };
443
+ if (isPhone)
444
+ params.countryCode = contact.countryCode;
445
+ const url = `${this.config.serverUrl.replace(/\/+$/, "")}/send-verification-code`;
446
+ const res = await fetch(url, {
447
+ method: "POST",
448
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
449
+ body: new URLSearchParams(params).toString(),
450
+ });
451
+ const data = await res.json().catch(() => ({}));
452
+ if (data.status === "ok")
453
+ return { ok: true };
454
+ const msg = data.msg || `send-verification-code failed (${res.status})`;
455
+ // Provider misconfig is treated as soft success in dev — Casdoor still
456
+ // generates the code and stores it for verification.
457
+ if (msg.includes("SMS provider") || msg.includes("provider"))
458
+ return { ok: true };
459
+ return { ok: false, error: msg };
460
+ }
461
+ /**
462
+ * Look up whether a phone number is registered. Returns `{ exists: false }`
463
+ * on 404 or unknown numbers; `{ exists: true }` when Casdoor confirms a user.
464
+ */
465
+ async lookupPhoneUser(phone, countryCode) {
466
+ const url = `${this.config.serverUrl.replace(/\/+$/, "")}/get-phone-user`;
467
+ const res = await fetch(url, {
468
+ method: "POST",
469
+ headers: { "Content-Type": "application/json" },
470
+ body: JSON.stringify({
471
+ application: this.config.appName ?? "app",
472
+ phone,
473
+ countryCode,
474
+ }),
475
+ });
476
+ if (res.status === 404)
477
+ return { exists: false };
478
+ if (!res.ok)
479
+ return { exists: false, error: `lookupPhoneUser failed (${res.status})` };
480
+ return { exists: true };
481
+ }
482
+ /**
483
+ * Casdoor REST signup. Returns the new user's id on success.
484
+ *
485
+ * Phone signup flow: send phoneCode via `sendVerificationCode`, then call
486
+ * this with the OTP in `phoneCode`. Casdoor verifies the code internally.
487
+ * Email signup flow: same with `email` + `emailCode`.
488
+ */
489
+ async signup(params) {
490
+ const username = params.username ?? params.name;
491
+ const password = params.password ?? `Liq${Date.now()}!`;
492
+ const body = {
493
+ application: this.config.appName ?? "app",
494
+ organization: this.config.orgName ?? "built-in",
495
+ name: params.name,
496
+ username,
497
+ password,
498
+ confirm: password,
499
+ agreement: true,
500
+ };
501
+ if (params.method === "email") {
502
+ body.email = params.email;
503
+ if (params.emailCode)
504
+ body.emailCode = params.emailCode;
505
+ }
506
+ else {
507
+ body.phone = params.phone;
508
+ body.countryCode = params.countryCode;
509
+ if (params.phoneCode)
510
+ body.phoneCode = params.phoneCode;
511
+ if (params.email)
512
+ body.email = params.email;
513
+ if (params.emailCode)
514
+ body.emailCode = params.emailCode;
515
+ }
516
+ const url = `${this.config.serverUrl.replace(/\/+$/, "")}/signup`;
517
+ const res = await fetch(url, {
518
+ method: "POST",
519
+ headers: { "Content-Type": "application/json" },
520
+ body: JSON.stringify(body),
521
+ });
522
+ const data = await res.json().catch(() => ({}));
523
+ if (data.status === "ok")
524
+ return { ok: true, id: data.data2 || data.data };
525
+ return { ok: false, error: data.msg || `signup failed (${res.status})` };
526
+ }
527
+ /**
528
+ * REST login that returns an authorization code (Casdoor `/login`).
529
+ *
530
+ * Use this when you want the caller to drive the PKCE flow without a
531
+ * full redirect — collect credentials in your own UI, get a code back,
532
+ * then call `exchangeCodeForToken` to land tokens.
533
+ */
534
+ async loginWithCredentials(params) {
535
+ const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
536
+ this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);
537
+ const url = new URL(`${this.config.serverUrl.replace(/\/+$/, "")}/login`);
538
+ url.searchParams.set("code_challenge", codeChallenge);
539
+ url.searchParams.set("code_challenge_method", "S256");
540
+ const res = await fetch(url.toString(), {
541
+ method: "POST",
542
+ headers: { "Content-Type": "application/json" },
543
+ body: JSON.stringify({
544
+ application: this.config.appName ?? "app",
545
+ organization: this.config.orgName ?? "built-in",
546
+ username: params.username,
547
+ password: params.password,
548
+ type: params.type ?? "code",
549
+ clientId: this.config.clientId,
550
+ redirectUri: params.redirectUri ?? this.config.redirectUri,
551
+ codeChallenge,
552
+ codeChallengeMethod: "S256",
553
+ autoSignin: true,
554
+ }),
555
+ });
556
+ const data = await res.json().catch(() => ({}));
557
+ if (data.status === "ok" && data.data)
558
+ return { ok: true, code: data.data };
559
+ return { ok: false, error: data.msg || `login failed (${res.status})` };
560
+ }
561
+ /**
562
+ * Exchange an authorization code for tokens using the stored PKCE verifier.
563
+ * Pairs with `loginWithCredentials` for a code → tokens round-trip.
564
+ */
565
+ async exchangeCodeForToken(code, redirectUri) {
566
+ const codeVerifier = this.storage.getItem(KEY_CODE_VERIFIER);
567
+ if (!codeVerifier) {
568
+ throw new Error("Missing PKCE verifier — call loginWithCredentials() first");
569
+ }
570
+ this.storage.removeItem(KEY_CODE_VERIFIER);
571
+ const discovery = await this.getDiscovery();
572
+ const tokenUrl = this.config.proxyBaseUrl
573
+ ? `${this.config.proxyBaseUrl.replace(/\/+$/, "")}/auth/token`
574
+ : discovery.token_endpoint;
575
+ const body = new URLSearchParams({
576
+ grant_type: "authorization_code",
577
+ client_id: this.config.clientId,
578
+ code,
579
+ redirect_uri: redirectUri ?? this.config.redirectUri,
580
+ code_verifier: codeVerifier,
581
+ });
582
+ const res = await fetch(tokenUrl, {
583
+ method: "POST",
584
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
585
+ body: body.toString(),
586
+ });
587
+ if (!res.ok) {
588
+ const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
589
+ throw new Error(err.error_description || err.error || "Token exchange failed");
590
+ }
591
+ const tokens = (await res.json());
592
+ this.storeTokens(tokens);
593
+ return tokens;
594
+ }
595
+ /**
596
+ * Phone OTP login: tries the numbered username variants Casdoor accepts
597
+ * (`{phone}`, `{countryCode}{phone}`), exchanges the resulting code for
598
+ * tokens. Returns the token response, or throws on failure.
599
+ */
600
+ async loginWithPhoneOTP(params) {
601
+ const usernames = [params.phone, `${params.countryCode}${params.phone}`];
602
+ let lastError = "";
603
+ for (const username of usernames) {
604
+ const result = await this.loginWithCredentials({
605
+ username,
606
+ password: params.code,
607
+ redirectUri: params.redirectUri,
608
+ });
609
+ if (result.ok && result.code) {
610
+ return this.exchangeCodeForToken(result.code, params.redirectUri);
611
+ }
612
+ lastError = result.error ?? lastError;
613
+ }
614
+ throw new Error(lastError || "Phone OTP login failed");
615
+ }
616
+ /**
617
+ * Logout via Casdoor REST `/logout` (clears server-side session) and
618
+ * the local storage.
619
+ */
620
+ async logout() {
621
+ const token = this.storage.getItem(KEY_ACCESS_TOKEN);
622
+ try {
623
+ await fetch(`${this.config.serverUrl.replace(/\/+$/, "")}/oauth/logout`, {
624
+ method: "POST",
625
+ headers: token ? { Authorization: `Bearer ${token}` } : {},
626
+ });
627
+ }
628
+ catch {
629
+ // best-effort — local cleanup is what matters
630
+ }
631
+ this.clearTokens();
632
+ }
412
633
  }
413
634
  //# sourceMappingURL=browser.js.map