@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.
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +3 -3
- package/dist/auth.js.map +1 -1
- package/dist/betterauth.d.ts +67 -0
- package/dist/betterauth.d.ts.map +1 -0
- package/dist/betterauth.js +64 -0
- package/dist/betterauth.js.map +1 -0
- package/dist/browser.d.ts +87 -4
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +229 -8
- package/dist/browser.js.map +1 -1
- package/dist/client.d.ts +11 -22
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +39 -96
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/nextauth.d.ts +12 -10
- package/dist/nextauth.d.ts.map +1 -1
- package/dist/nextauth.js +12 -11
- package/dist/nextauth.js.map +1 -1
- package/dist/passport.d.ts +44 -0
- package/dist/passport.d.ts.map +1 -0
- package/dist/passport.js +67 -0
- package/dist/passport.js.map +1 -0
- package/dist/pkce.d.ts +2 -2
- package/dist/pkce.js +2 -2
- package/dist/react.d.ts +8 -94
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +23 -454
- package/dist/react.js.map +1 -1
- package/dist/types.d.ts +1 -16
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +16 -7
- package/src/auth.ts +3 -3
- package/src/betterauth.ts +91 -0
- package/src/browser.ts +255 -11
- package/src/client.ts +47 -154
- package/src/index.ts +3 -4
- package/src/nextauth.ts +15 -13
- package/src/passport.ts +97 -0
- package/src/pkce.ts +2 -2
- package/src/react.ts +28 -635
- package/src/types.ts +1 -21
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,SAAS,GAAG;IACtB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAMF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAMF,MAAM,MAAM,YAAY,GAAG;IACzB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,8BAA8B;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAMF,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAMF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAMF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC;AAC3C,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC;AAC3B,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC;AACjC,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC;AACjC,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC;AAC7B,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC;AACzC,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC;AAM3C,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/iam",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "TypeScript SDK for Hanzo IAM
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "TypeScript SDK for Hanzo IAM \u2014 OIDC auth, JWT validation, OAuth2 PKCE, user/org/project APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.js"
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
12
13
|
},
|
|
13
14
|
"./auth": {
|
|
14
15
|
"types": "./dist/auth.d.ts",
|
|
15
|
-
"import": "./dist/auth.js"
|
|
16
|
+
"import": "./dist/auth.js",
|
|
17
|
+
"default": "./dist/auth.js"
|
|
16
18
|
},
|
|
17
19
|
"./browser": {
|
|
18
20
|
"types": "./dist/browser.d.ts",
|
|
@@ -33,6 +35,14 @@
|
|
|
33
35
|
"./nextauth": {
|
|
34
36
|
"types": "./dist/nextauth.d.ts",
|
|
35
37
|
"import": "./dist/nextauth.js"
|
|
38
|
+
},
|
|
39
|
+
"./passport": {
|
|
40
|
+
"types": "./dist/passport.d.ts",
|
|
41
|
+
"import": "./dist/passport.js"
|
|
42
|
+
},
|
|
43
|
+
"./betterauth": {
|
|
44
|
+
"types": "./dist/betterauth.d.ts",
|
|
45
|
+
"import": "./dist/betterauth.js"
|
|
36
46
|
}
|
|
37
47
|
},
|
|
38
48
|
"files": [
|
|
@@ -45,8 +55,8 @@
|
|
|
45
55
|
"build": "tsc",
|
|
46
56
|
"dev": "tsc --watch",
|
|
47
57
|
"clean": "rm -rf dist",
|
|
48
|
-
"prepare": "
|
|
49
|
-
"prepublishOnly": "
|
|
58
|
+
"prepare": "pnpm clean && pnpm build",
|
|
59
|
+
"prepublishOnly": "pnpm clean && pnpm build",
|
|
50
60
|
"test": "node --test --import tsx src/**/*.test.ts"
|
|
51
61
|
},
|
|
52
62
|
"dependencies": {
|
|
@@ -68,7 +78,6 @@
|
|
|
68
78
|
"keywords": [
|
|
69
79
|
"hanzo",
|
|
70
80
|
"iam",
|
|
71
|
-
"casdoor",
|
|
72
81
|
"oidc",
|
|
73
82
|
"oauth2",
|
|
74
83
|
"pkce",
|
package/src/auth.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
|
|
4
|
+
* Validates access/ID tokens issued by Hanzo IAM.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { createRemoteJWKSet, jwtVerify, type JWTPayload } from "jose";
|
|
@@ -109,7 +109,7 @@ export async function validateToken(
|
|
|
109
109
|
return { ok: false, reason: "iam_token_expired" };
|
|
110
110
|
}
|
|
111
111
|
if (message.includes("audience")) {
|
|
112
|
-
// Retry without audience check - some
|
|
112
|
+
// Retry without audience check - some IAM configs don't set aud
|
|
113
113
|
try {
|
|
114
114
|
const result = await jwtVerify(token, keySet, {
|
|
115
115
|
issuer,
|
|
@@ -137,7 +137,7 @@ export async function validateToken(
|
|
|
137
137
|
return { ok: false, reason: "iam_subject_missing" };
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
//
|
|
140
|
+
// IAM sub format is "org/username" - extract owner
|
|
141
141
|
const parts = sub.split("/");
|
|
142
142
|
const owner = parts.length > 1 ? parts[0] : config.orgName ?? "unknown";
|
|
143
143
|
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
import type { IamConfig } from "./types.js";
|
|
27
|
+
|
|
28
|
+
export interface IamSocialProvider {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
type: "oidc";
|
|
32
|
+
issuer: string;
|
|
33
|
+
clientId: string;
|
|
34
|
+
clientSecret?: string;
|
|
35
|
+
authorization: { url: string; params: { scope: string } };
|
|
36
|
+
token: { url: string };
|
|
37
|
+
userinfo: { url: string };
|
|
38
|
+
profile: (profile: Record<string, unknown>) => {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
email: string;
|
|
42
|
+
image: string | null;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a BetterAuth-compatible social provider for IAM.
|
|
48
|
+
*
|
|
49
|
+
* Works with BetterAuth's SSO plugin or generic OAuth integration.
|
|
50
|
+
* Uses standard OIDC endpoints.
|
|
51
|
+
*/
|
|
52
|
+
export function iamProvider(
|
|
53
|
+
config: IamConfig & { redirectUri?: string },
|
|
54
|
+
): IamSocialProvider {
|
|
55
|
+
const baseUrl = config.serverUrl.replace(/\/+$/, "");
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
id: "iam",
|
|
59
|
+
name: "IAM",
|
|
60
|
+
type: "oidc",
|
|
61
|
+
issuer: baseUrl,
|
|
62
|
+
clientId: config.clientId,
|
|
63
|
+
clientSecret: config.clientSecret,
|
|
64
|
+
authorization: {
|
|
65
|
+
url: `${baseUrl}/oauth/authorize`,
|
|
66
|
+
params: { scope: "openid profile email" },
|
|
67
|
+
},
|
|
68
|
+
token: { url: `${baseUrl}/oauth/token` },
|
|
69
|
+
userinfo: { url: `${baseUrl}/oauth/userinfo` },
|
|
70
|
+
profile(profile: Record<string, unknown>) {
|
|
71
|
+
return {
|
|
72
|
+
id: (profile.sub as string) ?? (profile.id as string) ?? "",
|
|
73
|
+
name:
|
|
74
|
+
(profile.displayName as string) ??
|
|
75
|
+
(profile.name as string) ??
|
|
76
|
+
(profile.preferred_username as string) ??
|
|
77
|
+
"",
|
|
78
|
+
email: (profile.email as string) ?? "",
|
|
79
|
+
image: (profile.avatar as string) ?? (profile.picture as string) ?? null,
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Backwards-compatible aliases
|
|
86
|
+
/** @deprecated Use iamProvider instead */
|
|
87
|
+
export { iamProvider as hanzoIamProvider };
|
|
88
|
+
/** @deprecated Use iamProvider instead */
|
|
89
|
+
export { iamProvider as hanzoIamSocialProvider };
|
|
90
|
+
/** @deprecated Use IamSocialProvider instead */
|
|
91
|
+
export type { IamSocialProvider as HanzoIamSocialProvider };
|
package/src/browser.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
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
|
|
7
|
+
* Adapted and modernized for Hanzo IAM.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { IamConfig, TokenResponse, OidcDiscovery } from "./types.js";
|
|
11
|
-
import {
|
|
11
|
+
import { generatePKCEChallenge, generateState } from "./pkce.js";
|
|
12
12
|
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
14
|
// Storage keys
|
|
@@ -26,7 +26,7 @@ const KEY_EXPIRES_AT = `${STORAGE_PREFIX}expires_at`;
|
|
|
26
26
|
// Browser IAM SDK
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
28
|
|
|
29
|
-
export type
|
|
29
|
+
export type IAMConfig = IamConfig & {
|
|
30
30
|
/** OAuth2 redirect URI (e.g. "https://app.hanzo.bot/auth/callback"). */
|
|
31
31
|
redirectUri: string;
|
|
32
32
|
/** OAuth2 scopes (default: "openid profile email"). */
|
|
@@ -43,12 +43,12 @@ export type BrowserIamConfig = IamConfig & {
|
|
|
43
43
|
proxyBaseUrl?: string;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
export class
|
|
47
|
-
private readonly config:
|
|
46
|
+
export class IAM {
|
|
47
|
+
private readonly config: IAMConfig;
|
|
48
48
|
private readonly storage: Storage;
|
|
49
49
|
private discoveryCache: OidcDiscovery | null = null;
|
|
50
50
|
|
|
51
|
-
constructor(config:
|
|
51
|
+
constructor(config: IAMConfig) {
|
|
52
52
|
this.config = config;
|
|
53
53
|
this.storage = config.storage ?? sessionStorage;
|
|
54
54
|
}
|
|
@@ -64,7 +64,7 @@ export class BrowserIamSdk {
|
|
|
64
64
|
|
|
65
65
|
// Try fetching the OIDC discovery document. If it fails (e.g. due to
|
|
66
66
|
// CORS when the IAM server doesn't send Access-Control-Allow-Origin),
|
|
67
|
-
// construct a fallback from well-known
|
|
67
|
+
// construct a fallback from well-known Hanzo IAM endpoint paths.
|
|
68
68
|
try {
|
|
69
69
|
const res = await fetch(`${baseUrl}/.well-known/openid-configuration`, {
|
|
70
70
|
headers: { Accept: "application/json" },
|
|
@@ -79,7 +79,7 @@ export class BrowserIamSdk {
|
|
|
79
79
|
|
|
80
80
|
this.discoveryCache = {
|
|
81
81
|
issuer: baseUrl,
|
|
82
|
-
authorization_endpoint: `${baseUrl}/
|
|
82
|
+
authorization_endpoint: `${baseUrl}/oauth/authorize`,
|
|
83
83
|
token_endpoint: `${baseUrl}/oauth/token`,
|
|
84
84
|
userinfo_endpoint: `${baseUrl}/oauth/userinfo`,
|
|
85
85
|
jwks_uri: `${baseUrl}/.well-known/jwks`,
|
|
@@ -102,7 +102,7 @@ export class BrowserIamSdk {
|
|
|
102
102
|
*/
|
|
103
103
|
async signinRedirect(params?: { additionalParams?: Record<string, string> }): Promise<void> {
|
|
104
104
|
const discovery = await this.getDiscovery();
|
|
105
|
-
const { codeVerifier, codeChallenge } = await
|
|
105
|
+
const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
|
|
106
106
|
const state = generateState();
|
|
107
107
|
|
|
108
108
|
this.storage.setItem(KEY_STATE, state);
|
|
@@ -265,7 +265,7 @@ export class BrowserIamSdk {
|
|
|
265
265
|
additionalParams?: Record<string, string>;
|
|
266
266
|
}): Promise<TokenResponse> {
|
|
267
267
|
const discovery = await this.getDiscovery();
|
|
268
|
-
const { codeVerifier, codeChallenge } = await
|
|
268
|
+
const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
|
|
269
269
|
const state = generateState();
|
|
270
270
|
|
|
271
271
|
this.storage.setItem(KEY_STATE, state);
|
|
@@ -335,7 +335,7 @@ export class BrowserIamSdk {
|
|
|
335
335
|
*/
|
|
336
336
|
async signinSilent(timeoutMs = 5000): Promise<TokenResponse | null> {
|
|
337
337
|
const discovery = await this.getDiscovery();
|
|
338
|
-
const { codeVerifier, codeChallenge } = await
|
|
338
|
+
const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
|
|
339
339
|
const state = generateState();
|
|
340
340
|
|
|
341
341
|
this.storage.setItem(KEY_STATE, state);
|
|
@@ -504,4 +504,248 @@ export class BrowserIamSdk {
|
|
|
504
504
|
const org = this.config.orgName ?? "built-in";
|
|
505
505
|
return `${base}/users/${org}/${username}`;
|
|
506
506
|
}
|
|
507
|
+
|
|
508
|
+
// -----------------------------------------------------------------------
|
|
509
|
+
// Casdoor REST surface (signup, OTP, REST login, phone lookup)
|
|
510
|
+
//
|
|
511
|
+
// The OIDC layer covers redirect/PKCE, token exchange, refresh, userinfo.
|
|
512
|
+
// These methods cover the Casdoor-native endpoints that don't have an OIDC
|
|
513
|
+
// analogue: phone/email OTP, custom signup with verification codes, and
|
|
514
|
+
// direct REST login that returns an authorization code in one round-trip
|
|
515
|
+
// (used as the bridge between OTP collection and `exchangeCode`).
|
|
516
|
+
//
|
|
517
|
+
// All paths are gateway-canonical (`/login`, `/signup`,
|
|
518
|
+
// `/send-verification-code`, `/get-phone-user`) — point `serverUrl` at the
|
|
519
|
+
// gateway prefix (e.g. `https://api.dev.satschel.com/v1/iam`) and the
|
|
520
|
+
// gateway proxies to Casdoor's `/api/*` internally.
|
|
521
|
+
// -----------------------------------------------------------------------
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Send a verification code to a phone or email destination.
|
|
525
|
+
*
|
|
526
|
+
* @param contact `{ phone, countryCode }` for SMS, `{ email }` for email.
|
|
527
|
+
* @param method Casdoor method: `login`, `signup`, `forget`, `mfaSetup`, etc.
|
|
528
|
+
*/
|
|
529
|
+
async sendVerificationCode(
|
|
530
|
+
contact: { phone: string; countryCode: string } | { email: string },
|
|
531
|
+
method: "login" | "signup" | "forget" | "mfaSetup" = "login",
|
|
532
|
+
): Promise<{ ok: boolean; error?: string }> {
|
|
533
|
+
const isPhone = "phone" in contact;
|
|
534
|
+
const dest = isPhone ? contact.phone : contact.email;
|
|
535
|
+
const params: Record<string, string> = {
|
|
536
|
+
applicationId: `admin/${this.config.appName ?? "app"}`,
|
|
537
|
+
dest,
|
|
538
|
+
type: isPhone ? "phone" : "email",
|
|
539
|
+
method,
|
|
540
|
+
captchaType: "none",
|
|
541
|
+
captchaToken: "",
|
|
542
|
+
};
|
|
543
|
+
if (isPhone) params.countryCode = contact.countryCode;
|
|
544
|
+
|
|
545
|
+
const url = `${this.config.serverUrl.replace(/\/+$/, "")}/send-verification-code`;
|
|
546
|
+
const res = await fetch(url, {
|
|
547
|
+
method: "POST",
|
|
548
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
549
|
+
body: new URLSearchParams(params).toString(),
|
|
550
|
+
});
|
|
551
|
+
const data = await res.json().catch(() => ({}));
|
|
552
|
+
if (data.status === "ok") return { ok: true };
|
|
553
|
+
const msg = (data.msg as string) || `send-verification-code failed (${res.status})`;
|
|
554
|
+
// Provider misconfig is treated as soft success in dev — Casdoor still
|
|
555
|
+
// generates the code and stores it for verification.
|
|
556
|
+
if (msg.includes("SMS provider") || msg.includes("provider")) return { ok: true };
|
|
557
|
+
return { ok: false, error: msg };
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Look up whether a phone number is registered. Returns `{ exists: false }`
|
|
562
|
+
* on 404 or unknown numbers; `{ exists: true }` when Casdoor confirms a user.
|
|
563
|
+
*/
|
|
564
|
+
async lookupPhoneUser(phone: string, countryCode: string): Promise<{ exists: boolean; error?: string }> {
|
|
565
|
+
const url = `${this.config.serverUrl.replace(/\/+$/, "")}/get-phone-user`;
|
|
566
|
+
const res = await fetch(url, {
|
|
567
|
+
method: "POST",
|
|
568
|
+
headers: { "Content-Type": "application/json" },
|
|
569
|
+
body: JSON.stringify({
|
|
570
|
+
application: this.config.appName ?? "app",
|
|
571
|
+
phone,
|
|
572
|
+
countryCode,
|
|
573
|
+
}),
|
|
574
|
+
});
|
|
575
|
+
if (res.status === 404) return { exists: false };
|
|
576
|
+
if (!res.ok) return { exists: false, error: `lookupPhoneUser failed (${res.status})` };
|
|
577
|
+
return { exists: true };
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Casdoor REST signup. Returns the new user's id on success.
|
|
582
|
+
*
|
|
583
|
+
* Phone signup flow: send phoneCode via `sendVerificationCode`, then call
|
|
584
|
+
* this with the OTP in `phoneCode`. Casdoor verifies the code internally.
|
|
585
|
+
* Email signup flow: same with `email` + `emailCode`.
|
|
586
|
+
*/
|
|
587
|
+
async signup(params: {
|
|
588
|
+
method: "email" | "phone";
|
|
589
|
+
name: string;
|
|
590
|
+
username?: string;
|
|
591
|
+
email?: string;
|
|
592
|
+
phone?: string;
|
|
593
|
+
countryCode?: string;
|
|
594
|
+
password?: string;
|
|
595
|
+
emailCode?: string;
|
|
596
|
+
phoneCode?: string;
|
|
597
|
+
}): Promise<{ id?: string; ok: boolean; error?: string }> {
|
|
598
|
+
const username = params.username ?? params.name;
|
|
599
|
+
const password = params.password ?? `Liq${Date.now()}!`;
|
|
600
|
+
const body: Record<string, unknown> = {
|
|
601
|
+
application: this.config.appName ?? "app",
|
|
602
|
+
organization: this.config.orgName ?? "built-in",
|
|
603
|
+
name: params.name,
|
|
604
|
+
username,
|
|
605
|
+
password,
|
|
606
|
+
confirm: password,
|
|
607
|
+
agreement: true,
|
|
608
|
+
};
|
|
609
|
+
if (params.method === "email") {
|
|
610
|
+
body.email = params.email;
|
|
611
|
+
if (params.emailCode) body.emailCode = params.emailCode;
|
|
612
|
+
} else {
|
|
613
|
+
body.phone = params.phone;
|
|
614
|
+
body.countryCode = params.countryCode;
|
|
615
|
+
if (params.phoneCode) body.phoneCode = params.phoneCode;
|
|
616
|
+
if (params.email) body.email = params.email;
|
|
617
|
+
if (params.emailCode) body.emailCode = params.emailCode;
|
|
618
|
+
}
|
|
619
|
+
const url = `${this.config.serverUrl.replace(/\/+$/, "")}/signup`;
|
|
620
|
+
const res = await fetch(url, {
|
|
621
|
+
method: "POST",
|
|
622
|
+
headers: { "Content-Type": "application/json" },
|
|
623
|
+
body: JSON.stringify(body),
|
|
624
|
+
});
|
|
625
|
+
const data = await res.json().catch(() => ({}));
|
|
626
|
+
if (data.status === "ok") return { ok: true, id: data.data2 || data.data };
|
|
627
|
+
return { ok: false, error: (data.msg as string) || `signup failed (${res.status})` };
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* REST login that returns an authorization code (Casdoor `/login`).
|
|
632
|
+
*
|
|
633
|
+
* Use this when you want the caller to drive the PKCE flow without a
|
|
634
|
+
* full redirect — collect credentials in your own UI, get a code back,
|
|
635
|
+
* then call `exchangeCodeForToken` to land tokens.
|
|
636
|
+
*/
|
|
637
|
+
async loginWithCredentials(params: {
|
|
638
|
+
username: string;
|
|
639
|
+
password: string;
|
|
640
|
+
type?: "code" | "token";
|
|
641
|
+
redirectUri?: string;
|
|
642
|
+
}): Promise<{ code?: string; ok: boolean; error?: string }> {
|
|
643
|
+
const { codeVerifier, codeChallenge } = await generatePKCEChallenge();
|
|
644
|
+
this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);
|
|
645
|
+
|
|
646
|
+
const url = new URL(`${this.config.serverUrl.replace(/\/+$/, "")}/login`);
|
|
647
|
+
url.searchParams.set("code_challenge", codeChallenge);
|
|
648
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
649
|
+
|
|
650
|
+
const res = await fetch(url.toString(), {
|
|
651
|
+
method: "POST",
|
|
652
|
+
headers: { "Content-Type": "application/json" },
|
|
653
|
+
body: JSON.stringify({
|
|
654
|
+
application: this.config.appName ?? "app",
|
|
655
|
+
organization: this.config.orgName ?? "built-in",
|
|
656
|
+
username: params.username,
|
|
657
|
+
password: params.password,
|
|
658
|
+
type: params.type ?? "code",
|
|
659
|
+
clientId: this.config.clientId,
|
|
660
|
+
redirectUri: params.redirectUri ?? this.config.redirectUri,
|
|
661
|
+
codeChallenge,
|
|
662
|
+
codeChallengeMethod: "S256",
|
|
663
|
+
autoSignin: true,
|
|
664
|
+
}),
|
|
665
|
+
});
|
|
666
|
+
const data = await res.json().catch(() => ({}));
|
|
667
|
+
if (data.status === "ok" && data.data) return { ok: true, code: data.data as string };
|
|
668
|
+
return { ok: false, error: (data.msg as string) || `login failed (${res.status})` };
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Exchange an authorization code for tokens using the stored PKCE verifier.
|
|
673
|
+
* Pairs with `loginWithCredentials` for a code → tokens round-trip.
|
|
674
|
+
*/
|
|
675
|
+
async exchangeCodeForToken(code: string, redirectUri?: string): Promise<TokenResponse> {
|
|
676
|
+
const codeVerifier = this.storage.getItem(KEY_CODE_VERIFIER);
|
|
677
|
+
if (!codeVerifier) {
|
|
678
|
+
throw new Error("Missing PKCE verifier — call loginWithCredentials() first");
|
|
679
|
+
}
|
|
680
|
+
this.storage.removeItem(KEY_CODE_VERIFIER);
|
|
681
|
+
|
|
682
|
+
const discovery = await this.getDiscovery();
|
|
683
|
+
const tokenUrl = this.config.proxyBaseUrl
|
|
684
|
+
? `${this.config.proxyBaseUrl.replace(/\/+$/, "")}/auth/token`
|
|
685
|
+
: discovery.token_endpoint;
|
|
686
|
+
|
|
687
|
+
const body = new URLSearchParams({
|
|
688
|
+
grant_type: "authorization_code",
|
|
689
|
+
client_id: this.config.clientId,
|
|
690
|
+
code,
|
|
691
|
+
redirect_uri: redirectUri ?? this.config.redirectUri,
|
|
692
|
+
code_verifier: codeVerifier,
|
|
693
|
+
});
|
|
694
|
+
const res = await fetch(tokenUrl, {
|
|
695
|
+
method: "POST",
|
|
696
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
697
|
+
body: body.toString(),
|
|
698
|
+
});
|
|
699
|
+
if (!res.ok) {
|
|
700
|
+
const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
701
|
+
throw new Error((err as Record<string, string>).error_description || (err as Record<string, string>).error || "Token exchange failed");
|
|
702
|
+
}
|
|
703
|
+
const tokens = (await res.json()) as TokenResponse;
|
|
704
|
+
this.storeTokens(tokens);
|
|
705
|
+
return tokens;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Phone OTP login: tries the numbered username variants Casdoor accepts
|
|
710
|
+
* (`{phone}`, `{countryCode}{phone}`), exchanges the resulting code for
|
|
711
|
+
* tokens. Returns the token response, or throws on failure.
|
|
712
|
+
*/
|
|
713
|
+
async loginWithPhoneOTP(params: {
|
|
714
|
+
phone: string;
|
|
715
|
+
countryCode: string;
|
|
716
|
+
code: string;
|
|
717
|
+
redirectUri?: string;
|
|
718
|
+
}): Promise<TokenResponse> {
|
|
719
|
+
const usernames = [params.phone, `${params.countryCode}${params.phone}`];
|
|
720
|
+
let lastError = "";
|
|
721
|
+
for (const username of usernames) {
|
|
722
|
+
const result = await this.loginWithCredentials({
|
|
723
|
+
username,
|
|
724
|
+
password: params.code,
|
|
725
|
+
redirectUri: params.redirectUri,
|
|
726
|
+
});
|
|
727
|
+
if (result.ok && result.code) {
|
|
728
|
+
return this.exchangeCodeForToken(result.code, params.redirectUri);
|
|
729
|
+
}
|
|
730
|
+
lastError = result.error ?? lastError;
|
|
731
|
+
}
|
|
732
|
+
throw new Error(lastError || "Phone OTP login failed");
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Logout via Casdoor REST `/logout` (clears server-side session) and
|
|
737
|
+
* the local storage.
|
|
738
|
+
*/
|
|
739
|
+
async logout(): Promise<void> {
|
|
740
|
+
const token = this.storage.getItem(KEY_ACCESS_TOKEN);
|
|
741
|
+
try {
|
|
742
|
+
await fetch(`${this.config.serverUrl.replace(/\/+$/, "")}/oauth/logout`, {
|
|
743
|
+
method: "POST",
|
|
744
|
+
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
745
|
+
});
|
|
746
|
+
} catch {
|
|
747
|
+
// best-effort — local cleanup is what matters
|
|
748
|
+
}
|
|
749
|
+
this.clearTokens();
|
|
750
|
+
}
|
|
507
751
|
}
|