@hanzo/iam 0.4.0 → 0.4.2
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/browser.js +2 -2
- package/dist/browser.js.map +1 -1
- package/dist/client.d.ts +21 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +32 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/react.d.ts +45 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +131 -0
- package/dist/react.js.map +1 -1
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -11
- package/src/browser.ts +2 -2
- package/src/client.ts +83 -0
- package/src/index.ts +2 -1
- package/src/react.ts +195 -1
- package/src/types.ts +20 -0
- package/dist/betterauth.d.ts +0 -62
- package/dist/betterauth.d.ts.map +0 -1
- package/dist/betterauth.js +0 -61
- package/dist/betterauth.js.map +0 -1
- package/dist/passport.d.ts +0 -44
- package/dist/passport.d.ts.map +0 -1
- package/dist/passport.js +0 -67
- package/dist/passport.js.map +0 -1
- package/src/betterauth.ts +0 -86
- package/src/passport.ts +0 -97
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/iam",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "TypeScript SDK for Hanzo IAM — OIDC auth, JWT validation, OAuth2 PKCE, user/org/project APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,14 +33,6 @@
|
|
|
33
33
|
"./nextauth": {
|
|
34
34
|
"types": "./dist/nextauth.d.ts",
|
|
35
35
|
"import": "./dist/nextauth.js"
|
|
36
|
-
},
|
|
37
|
-
"./passport": {
|
|
38
|
-
"types": "./dist/passport.d.ts",
|
|
39
|
-
"import": "./dist/passport.js"
|
|
40
|
-
},
|
|
41
|
-
"./betterauth": {
|
|
42
|
-
"types": "./dist/betterauth.d.ts",
|
|
43
|
-
"import": "./dist/betterauth.js"
|
|
44
36
|
}
|
|
45
37
|
},
|
|
46
38
|
"files": [
|
|
@@ -53,8 +45,8 @@
|
|
|
53
45
|
"build": "tsc",
|
|
54
46
|
"dev": "tsc --watch",
|
|
55
47
|
"clean": "rm -rf dist",
|
|
56
|
-
"prepare": "
|
|
57
|
-
"prepublishOnly": "
|
|
48
|
+
"prepare": "npm run clean && npm run build",
|
|
49
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
58
50
|
"test": "node --test --import tsx src/**/*.test.ts"
|
|
59
51
|
},
|
|
60
52
|
"dependencies": {
|
package/src/browser.ts
CHANGED
|
@@ -80,8 +80,8 @@ export class BrowserIamSdk {
|
|
|
80
80
|
this.discoveryCache = {
|
|
81
81
|
issuer: baseUrl,
|
|
82
82
|
authorization_endpoint: `${baseUrl}/login/oauth/authorize`,
|
|
83
|
-
token_endpoint: `${baseUrl}/
|
|
84
|
-
userinfo_endpoint: `${baseUrl}/
|
|
83
|
+
token_endpoint: `${baseUrl}/oauth/token`,
|
|
84
|
+
userinfo_endpoint: `${baseUrl}/oauth/userinfo`,
|
|
85
85
|
jwks_uri: `${baseUrl}/.well-known/jwks`,
|
|
86
86
|
response_types_supported: ["code", "token", "id_token"],
|
|
87
87
|
grant_types_supported: ["authorization_code", "implicit", "refresh_token"],
|
package/src/client.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
IamApiResponse,
|
|
8
8
|
IamUser,
|
|
9
9
|
IamOrganization,
|
|
10
|
+
IamInvitation,
|
|
10
11
|
IamProject,
|
|
11
12
|
OidcDiscovery,
|
|
12
13
|
TokenResponse,
|
|
@@ -289,6 +290,88 @@ export class IamClient {
|
|
|
289
290
|
return org ? [org] : [];
|
|
290
291
|
}
|
|
291
292
|
|
|
293
|
+
/** Create a new organization. */
|
|
294
|
+
async createOrganization(
|
|
295
|
+
org: Partial<IamOrganization>,
|
|
296
|
+
token?: string,
|
|
297
|
+
): Promise<IamApiResponse<IamOrganization>> {
|
|
298
|
+
return this.request<IamApiResponse<IamOrganization>>(
|
|
299
|
+
"/api/add-organization",
|
|
300
|
+
{ method: "POST", body: org, token },
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** Update an existing organization. */
|
|
305
|
+
async updateOrganization(
|
|
306
|
+
org: Partial<IamOrganization>,
|
|
307
|
+
token?: string,
|
|
308
|
+
): Promise<IamApiResponse<IamOrganization>> {
|
|
309
|
+
return this.request<IamApiResponse<IamOrganization>>(
|
|
310
|
+
"/api/update-organization",
|
|
311
|
+
{ method: "POST", body: org, token },
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Delete an organization by owner and name. */
|
|
316
|
+
async deleteOrganization(
|
|
317
|
+
org: { owner: string; name: string },
|
|
318
|
+
token?: string,
|
|
319
|
+
): Promise<IamApiResponse<IamOrganization>> {
|
|
320
|
+
return this.request<IamApiResponse<IamOrganization>>(
|
|
321
|
+
"/api/delete-organization",
|
|
322
|
+
{ method: "POST", body: org, token },
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// -----------------------------------------------------------------------
|
|
327
|
+
// Invitation
|
|
328
|
+
// -----------------------------------------------------------------------
|
|
329
|
+
|
|
330
|
+
/** List invitations for an owner (organization). */
|
|
331
|
+
async getInvitations(
|
|
332
|
+
owner: string,
|
|
333
|
+
token?: string,
|
|
334
|
+
): Promise<IamInvitation[]> {
|
|
335
|
+
const resp = await this.request<IamApiResponse<IamInvitation[]>>(
|
|
336
|
+
"/api/get-invitations",
|
|
337
|
+
{ params: { owner }, token },
|
|
338
|
+
);
|
|
339
|
+
return resp.data ?? [];
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** Create a new invitation. */
|
|
343
|
+
async createInvitation(
|
|
344
|
+
invitation: Partial<IamInvitation>,
|
|
345
|
+
token?: string,
|
|
346
|
+
): Promise<IamApiResponse<IamInvitation>> {
|
|
347
|
+
return this.request<IamApiResponse<IamInvitation>>(
|
|
348
|
+
"/api/add-invitation",
|
|
349
|
+
{ method: "POST", body: invitation, token },
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Send an invitation by owner and name. */
|
|
354
|
+
async sendInvitation(
|
|
355
|
+
invitation: { owner: string; name: string },
|
|
356
|
+
token?: string,
|
|
357
|
+
): Promise<IamApiResponse<IamInvitation>> {
|
|
358
|
+
return this.request<IamApiResponse<IamInvitation>>(
|
|
359
|
+
"/api/send-invitation",
|
|
360
|
+
{ method: "POST", body: invitation, token },
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/** Verify an invitation code. */
|
|
365
|
+
async verifyInvitation(
|
|
366
|
+
code: string,
|
|
367
|
+
token?: string,
|
|
368
|
+
): Promise<IamApiResponse<IamInvitation>> {
|
|
369
|
+
return this.request<IamApiResponse<IamInvitation>>(
|
|
370
|
+
"/api/verify-invitation",
|
|
371
|
+
{ params: { code }, token },
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
|
|
292
375
|
// -----------------------------------------------------------------------
|
|
293
376
|
// Project
|
|
294
377
|
// -----------------------------------------------------------------------
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* });
|
|
15
15
|
*
|
|
16
16
|
* const billing = new BillingClient({
|
|
17
|
-
* commerceUrl: "https://commerce.hanzo.ai",
|
|
17
|
+
* commerceUrl: "https://commerce-api.hanzo.ai/api",
|
|
18
18
|
* });
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
@@ -43,6 +43,7 @@ export type {
|
|
|
43
43
|
IamJwtClaims,
|
|
44
44
|
IamUser,
|
|
45
45
|
IamOrganization,
|
|
46
|
+
IamInvitation,
|
|
46
47
|
IamProject,
|
|
47
48
|
Subscription,
|
|
48
49
|
Plan,
|
package/src/react.ts
CHANGED
|
@@ -46,7 +46,7 @@ import type { ReactNode } from "react";
|
|
|
46
46
|
import { BrowserIamSdk } from "./browser.js";
|
|
47
47
|
import type { BrowserIamConfig } from "./browser.js";
|
|
48
48
|
import { IamClient } from "./client.js";
|
|
49
|
-
import type { IamUser, IamOrganization, IamProject, TokenResponse } from "./types.js";
|
|
49
|
+
import type { IamUser, IamOrganization, IamInvitation, IamProject, TokenResponse } from "./types.js";
|
|
50
50
|
|
|
51
51
|
// ---------------------------------------------------------------------------
|
|
52
52
|
// Types
|
|
@@ -589,6 +589,200 @@ export function useIamToken(): {
|
|
|
589
589
|
};
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
+
// ---------------------------------------------------------------------------
|
|
593
|
+
// useOrgManagement
|
|
594
|
+
// ---------------------------------------------------------------------------
|
|
595
|
+
|
|
596
|
+
export interface OrgManagementState {
|
|
597
|
+
/** Create a new organization. */
|
|
598
|
+
createOrg: (org: Partial<IamOrganization>) => Promise<void>;
|
|
599
|
+
/** Update an existing organization. */
|
|
600
|
+
updateOrg: (org: Partial<IamOrganization>) => Promise<void>;
|
|
601
|
+
/** Delete an organization by owner and name. */
|
|
602
|
+
deleteOrg: (org: { owner: string; name: string }) => Promise<void>;
|
|
603
|
+
/** Whether a mutation is in progress. */
|
|
604
|
+
isLoading: boolean;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Manage organization CRUD operations.
|
|
609
|
+
*
|
|
610
|
+
* Provides create, update, and delete methods that call the IAM API
|
|
611
|
+
* using the current user's access token.
|
|
612
|
+
*/
|
|
613
|
+
export function useOrgManagement(): OrgManagementState {
|
|
614
|
+
const { config, accessToken } = useIam();
|
|
615
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
616
|
+
|
|
617
|
+
const client = useMemo(
|
|
618
|
+
() =>
|
|
619
|
+
new IamClient({
|
|
620
|
+
serverUrl: config.serverUrl,
|
|
621
|
+
clientId: config.clientId,
|
|
622
|
+
}),
|
|
623
|
+
[config.serverUrl, config.clientId],
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
const createOrg = useCallback(
|
|
627
|
+
async (org: Partial<IamOrganization>) => {
|
|
628
|
+
setIsLoading(true);
|
|
629
|
+
try {
|
|
630
|
+
await client.createOrganization(org, accessToken ?? undefined);
|
|
631
|
+
} finally {
|
|
632
|
+
setIsLoading(false);
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
[client, accessToken],
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
const updateOrg = useCallback(
|
|
639
|
+
async (org: Partial<IamOrganization>) => {
|
|
640
|
+
setIsLoading(true);
|
|
641
|
+
try {
|
|
642
|
+
await client.updateOrganization(org, accessToken ?? undefined);
|
|
643
|
+
} finally {
|
|
644
|
+
setIsLoading(false);
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
[client, accessToken],
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
const deleteOrg = useCallback(
|
|
651
|
+
async (org: { owner: string; name: string }) => {
|
|
652
|
+
setIsLoading(true);
|
|
653
|
+
try {
|
|
654
|
+
await client.deleteOrganization(org, accessToken ?? undefined);
|
|
655
|
+
} finally {
|
|
656
|
+
setIsLoading(false);
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
[client, accessToken],
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
return { createOrg, updateOrg, deleteOrg, isLoading };
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// ---------------------------------------------------------------------------
|
|
666
|
+
// useInvitations
|
|
667
|
+
// ---------------------------------------------------------------------------
|
|
668
|
+
|
|
669
|
+
export interface InvitationsState {
|
|
670
|
+
/** All invitations for the organization. */
|
|
671
|
+
invitations: IamInvitation[];
|
|
672
|
+
/** Create a new invitation. */
|
|
673
|
+
createInvite: (invitation: Partial<IamInvitation>) => Promise<void>;
|
|
674
|
+
/** Send an existing invitation. */
|
|
675
|
+
sendInvite: (invitation: { owner: string; name: string }) => Promise<void>;
|
|
676
|
+
/** Verify an invitation code. */
|
|
677
|
+
verifyInvite: (code: string) => Promise<IamInvitation | null>;
|
|
678
|
+
/** Whether invitations are loading. */
|
|
679
|
+
isLoading: boolean;
|
|
680
|
+
/** Re-fetch the invitations list. */
|
|
681
|
+
refresh: () => Promise<void>;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Manage invitations for an organization.
|
|
686
|
+
*
|
|
687
|
+
* Fetches the invitation list on mount and provides create, send,
|
|
688
|
+
* and verify methods using the current user's access token.
|
|
689
|
+
*/
|
|
690
|
+
export function useInvitations(orgName: string): InvitationsState {
|
|
691
|
+
const { config, accessToken, isAuthenticated } = useIam();
|
|
692
|
+
const [invitations, setInvitations] = useState<IamInvitation[]>([]);
|
|
693
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
694
|
+
|
|
695
|
+
const client = useMemo(
|
|
696
|
+
() =>
|
|
697
|
+
new IamClient({
|
|
698
|
+
serverUrl: config.serverUrl,
|
|
699
|
+
clientId: config.clientId,
|
|
700
|
+
}),
|
|
701
|
+
[config.serverUrl, config.clientId],
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
const fetchInvitations = useCallback(async () => {
|
|
705
|
+
if (!isAuthenticated || !accessToken || !orgName) return;
|
|
706
|
+
setIsLoading(true);
|
|
707
|
+
try {
|
|
708
|
+
const data = await client.getInvitations(orgName, accessToken);
|
|
709
|
+
setInvitations(data);
|
|
710
|
+
} catch {
|
|
711
|
+
setInvitations([]);
|
|
712
|
+
} finally {
|
|
713
|
+
setIsLoading(false);
|
|
714
|
+
}
|
|
715
|
+
}, [client, orgName, accessToken, isAuthenticated]);
|
|
716
|
+
|
|
717
|
+
// Fetch invitations on mount and when orgName changes
|
|
718
|
+
useEffect(() => {
|
|
719
|
+
if (!isAuthenticated || !accessToken || !orgName) {
|
|
720
|
+
setInvitations([]);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
let cancelled = false;
|
|
725
|
+
|
|
726
|
+
const load = async () => {
|
|
727
|
+
setIsLoading(true);
|
|
728
|
+
try {
|
|
729
|
+
const data = await client.getInvitations(orgName, accessToken);
|
|
730
|
+
if (!cancelled) setInvitations(data);
|
|
731
|
+
} catch {
|
|
732
|
+
if (!cancelled) setInvitations([]);
|
|
733
|
+
} finally {
|
|
734
|
+
if (!cancelled) setIsLoading(false);
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
load();
|
|
739
|
+
return () => {
|
|
740
|
+
cancelled = true;
|
|
741
|
+
};
|
|
742
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
743
|
+
}, [isAuthenticated, accessToken, orgName, config.serverUrl, config.clientId]);
|
|
744
|
+
|
|
745
|
+
const createInvite = useCallback(
|
|
746
|
+
async (invitation: Partial<IamInvitation>) => {
|
|
747
|
+
setIsLoading(true);
|
|
748
|
+
try {
|
|
749
|
+
await client.createInvitation(invitation, accessToken ?? undefined);
|
|
750
|
+
await fetchInvitations();
|
|
751
|
+
} finally {
|
|
752
|
+
setIsLoading(false);
|
|
753
|
+
}
|
|
754
|
+
},
|
|
755
|
+
[client, accessToken, fetchInvitations],
|
|
756
|
+
);
|
|
757
|
+
|
|
758
|
+
const sendInvite = useCallback(
|
|
759
|
+
async (invitation: { owner: string; name: string }) => {
|
|
760
|
+
setIsLoading(true);
|
|
761
|
+
try {
|
|
762
|
+
await client.sendInvitation(invitation, accessToken ?? undefined);
|
|
763
|
+
} finally {
|
|
764
|
+
setIsLoading(false);
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
[client, accessToken],
|
|
768
|
+
);
|
|
769
|
+
|
|
770
|
+
const verifyInvite = useCallback(
|
|
771
|
+
async (code: string): Promise<IamInvitation | null> => {
|
|
772
|
+
setIsLoading(true);
|
|
773
|
+
try {
|
|
774
|
+
const resp = await client.verifyInvitation(code, accessToken ?? undefined);
|
|
775
|
+
return resp.data ?? null;
|
|
776
|
+
} finally {
|
|
777
|
+
setIsLoading(false);
|
|
778
|
+
}
|
|
779
|
+
},
|
|
780
|
+
[client, accessToken],
|
|
781
|
+
);
|
|
782
|
+
|
|
783
|
+
return { invitations, createInvite, sendInvite, verifyInvite, isLoading, refresh: fetchInvitations };
|
|
784
|
+
}
|
|
785
|
+
|
|
592
786
|
// Re-export context for advanced use
|
|
593
787
|
export { IamContext };
|
|
594
788
|
|
package/src/types.ts
CHANGED
|
@@ -226,6 +226,26 @@ export type IamOrder = Order;
|
|
|
226
226
|
export type IamUsageRecord = UsageRecord;
|
|
227
227
|
export type IamUsageSummary = UsageSummary;
|
|
228
228
|
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
// Invitation
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
|
|
233
|
+
export type IamInvitation = {
|
|
234
|
+
owner: string;
|
|
235
|
+
name: string;
|
|
236
|
+
displayName?: string;
|
|
237
|
+
code: string;
|
|
238
|
+
quota: number;
|
|
239
|
+
usedCount: number;
|
|
240
|
+
application?: string;
|
|
241
|
+
email?: string;
|
|
242
|
+
phone?: string;
|
|
243
|
+
signupGroup?: string;
|
|
244
|
+
state?: string;
|
|
245
|
+
createdTime?: string;
|
|
246
|
+
updatedTime?: string;
|
|
247
|
+
};
|
|
248
|
+
|
|
229
249
|
// ---------------------------------------------------------------------------
|
|
230
250
|
// Project
|
|
231
251
|
// ---------------------------------------------------------------------------
|
package/dist/betterauth.d.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BetterAuth SSO provider configuration for Hanzo 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 { hanzoIamProvider } from "@hanzo/iam/betterauth";
|
|
11
|
-
*
|
|
12
|
-
* export const auth = betterAuth({
|
|
13
|
-
* socialProviders: [
|
|
14
|
-
* hanzoIamProvider({
|
|
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 HanzoIamSocialProvider {
|
|
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 Hanzo IAM.
|
|
54
|
-
*
|
|
55
|
-
* Works with BetterAuth's SSO plugin or generic OAuth integration.
|
|
56
|
-
* Uses the standard Hanzo IAM / Casdoor OIDC endpoints.
|
|
57
|
-
*/
|
|
58
|
-
export declare function hanzoIamProvider(config: IamConfig & {
|
|
59
|
-
redirectUri?: string;
|
|
60
|
-
}): HanzoIamSocialProvider;
|
|
61
|
-
export { hanzoIamProvider as hanzoIamSocialProvider };
|
|
62
|
-
//# sourceMappingURL=betterauth.d.ts.map
|
package/dist/betterauth.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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,sBAAsB;IACrC,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,gBAAgB,CAC9B,MAAM,EAAE,SAAS,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,sBAAsB,CA6BxB;AAGD,OAAO,EAAE,gBAAgB,IAAI,sBAAsB,EAAE,CAAC"}
|
package/dist/betterauth.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BetterAuth SSO provider configuration for Hanzo 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 { hanzoIamProvider } from "@hanzo/iam/betterauth";
|
|
11
|
-
*
|
|
12
|
-
* export const auth = betterAuth({
|
|
13
|
-
* socialProviders: [
|
|
14
|
-
* hanzoIamProvider({
|
|
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 Hanzo IAM.
|
|
27
|
-
*
|
|
28
|
-
* Works with BetterAuth's SSO plugin or generic OAuth integration.
|
|
29
|
-
* Uses the standard Hanzo IAM / Casdoor OIDC endpoints.
|
|
30
|
-
*/
|
|
31
|
-
export function hanzoIamProvider(config) {
|
|
32
|
-
const baseUrl = config.serverUrl.replace(/\/+$/, "");
|
|
33
|
-
return {
|
|
34
|
-
id: "hanzo-iam",
|
|
35
|
-
name: "Hanzo IAM",
|
|
36
|
-
type: "oidc",
|
|
37
|
-
issuer: baseUrl,
|
|
38
|
-
clientId: config.clientId,
|
|
39
|
-
clientSecret: config.clientSecret,
|
|
40
|
-
authorization: {
|
|
41
|
-
url: `${baseUrl}/login/oauth/authorize`,
|
|
42
|
-
params: { scope: "openid profile email" },
|
|
43
|
-
},
|
|
44
|
-
token: { url: `${baseUrl}/api/login/oauth/access_token` },
|
|
45
|
-
userinfo: { url: `${baseUrl}/api/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 alias
|
|
60
|
-
export { hanzoIamProvider as hanzoIamSocialProvider };
|
|
61
|
-
//# sourceMappingURL=betterauth.js.map
|
package/dist/betterauth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"betterauth.js","sourceRoot":"","sources":["../src/betterauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAsBH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA4C;IAE5C,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAErD,OAAO;QACL,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,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,wBAAwB;YACvC,MAAM,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;SAC1C;QACD,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,+BAA+B,EAAE;QACzD,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,eAAe,EAAE;QAC5C,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,6BAA6B;AAC7B,OAAO,EAAE,gBAAgB,IAAI,sBAAsB,EAAE,CAAC"}
|
package/dist/passport.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Passport.js OAuth2 strategy factory for Hanzo IAM.
|
|
3
|
-
*
|
|
4
|
-
* Creates a pre-configured passport-oauth2 strategy that authenticates
|
|
5
|
-
* against hanzo.id with PKCE and fetches user info on callback.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* import passport from "passport";
|
|
10
|
-
* import { createIamPassportStrategy } from "@hanzo/iam/passport";
|
|
11
|
-
*
|
|
12
|
-
* passport.use("iam", createIamPassportStrategy({
|
|
13
|
-
* serverUrl: "https://hanzo.id",
|
|
14
|
-
* clientId: "hanzo-kms-client-id",
|
|
15
|
-
* clientSecret: process.env.IAM_CLIENT_SECRET!,
|
|
16
|
-
* callbackUrl: "https://kms.hanzo.ai/api/v1/sso/oidc/callback",
|
|
17
|
-
* }));
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* @packageDocumentation
|
|
21
|
-
*/
|
|
22
|
-
import type { IamConfig } from "./types.js";
|
|
23
|
-
export interface IamPassportConfig extends IamConfig {
|
|
24
|
-
/** Full callback URL for OAuth2 redirect. */
|
|
25
|
-
callbackUrl: string;
|
|
26
|
-
/** OAuth2 scopes. Default: "openid profile email". */
|
|
27
|
-
scope?: string;
|
|
28
|
-
}
|
|
29
|
-
export interface IamPassportUser {
|
|
30
|
-
accessToken: string;
|
|
31
|
-
refreshToken?: string;
|
|
32
|
-
userinfo: Record<string, unknown>;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Create a Passport OAuth2 strategy for Hanzo IAM.
|
|
36
|
-
*
|
|
37
|
-
* Requires `passport-oauth2` as a peer dependency.
|
|
38
|
-
* Returns an OAuth2Strategy instance ready to pass to `passport.use()`.
|
|
39
|
-
*
|
|
40
|
-
* The verify callback fetches userinfo from the IAM server and passes
|
|
41
|
-
* `{ accessToken, refreshToken, userinfo }` as the user object.
|
|
42
|
-
*/
|
|
43
|
-
export declare function createIamPassportStrategy(config: IamPassportConfig): unknown;
|
|
44
|
-
//# sourceMappingURL=passport.d.ts.map
|
package/dist/passport.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"passport.d.ts","sourceRoot":"","sources":["../src/passport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAgDT"}
|
package/dist/passport.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Passport.js OAuth2 strategy factory for Hanzo IAM.
|
|
3
|
-
*
|
|
4
|
-
* Creates a pre-configured passport-oauth2 strategy that authenticates
|
|
5
|
-
* against hanzo.id with PKCE and fetches user info on callback.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* import passport from "passport";
|
|
10
|
-
* import { createIamPassportStrategy } from "@hanzo/iam/passport";
|
|
11
|
-
*
|
|
12
|
-
* passport.use("iam", createIamPassportStrategy({
|
|
13
|
-
* serverUrl: "https://hanzo.id",
|
|
14
|
-
* clientId: "hanzo-kms-client-id",
|
|
15
|
-
* clientSecret: process.env.IAM_CLIENT_SECRET!,
|
|
16
|
-
* callbackUrl: "https://kms.hanzo.ai/api/v1/sso/oidc/callback",
|
|
17
|
-
* }));
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* @packageDocumentation
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* Create a Passport OAuth2 strategy for Hanzo IAM.
|
|
24
|
-
*
|
|
25
|
-
* Requires `passport-oauth2` as a peer dependency.
|
|
26
|
-
* Returns an OAuth2Strategy instance ready to pass to `passport.use()`.
|
|
27
|
-
*
|
|
28
|
-
* The verify callback fetches userinfo from the IAM server and passes
|
|
29
|
-
* `{ accessToken, refreshToken, userinfo }` as the user object.
|
|
30
|
-
*/
|
|
31
|
-
export function createIamPassportStrategy(config) {
|
|
32
|
-
// Dynamic import to keep passport-oauth2 as optional peer dep.
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
34
|
-
const { Strategy: OAuth2Strategy } = require("passport-oauth2");
|
|
35
|
-
const baseUrl = config.serverUrl.replace(/\/+$/, "");
|
|
36
|
-
const verify = async (...args) => {
|
|
37
|
-
// passReqToCallback=true: (req, accessToken, refreshToken, profile, done)
|
|
38
|
-
const accessToken = args[1];
|
|
39
|
-
const refreshToken = args[2];
|
|
40
|
-
const done = args[4];
|
|
41
|
-
try {
|
|
42
|
-
const res = await fetch(`${baseUrl}/api/userinfo`, {
|
|
43
|
-
headers: { Authorization: `Bearer ${accessToken}` },
|
|
44
|
-
});
|
|
45
|
-
if (!res.ok) {
|
|
46
|
-
return done(new Error(`IAM userinfo failed: ${res.status}`));
|
|
47
|
-
}
|
|
48
|
-
const userinfo = (await res.json());
|
|
49
|
-
done(null, { accessToken, refreshToken, userinfo });
|
|
50
|
-
}
|
|
51
|
-
catch (err) {
|
|
52
|
-
done(err instanceof Error ? err : new Error(String(err)));
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
return new OAuth2Strategy({
|
|
56
|
-
authorizationURL: `${baseUrl}/login/oauth/authorize`,
|
|
57
|
-
tokenURL: `${baseUrl}/api/login/oauth/access_token`,
|
|
58
|
-
clientID: config.clientId,
|
|
59
|
-
clientSecret: config.clientSecret ?? "",
|
|
60
|
-
callbackURL: config.callbackUrl,
|
|
61
|
-
scope: config.scope ?? "openid profile email",
|
|
62
|
-
state: true,
|
|
63
|
-
pkce: true,
|
|
64
|
-
passReqToCallback: true,
|
|
65
|
-
}, verify);
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=passport.js.map
|
package/dist/passport.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"passport.js","sourceRoot":"","sources":["../src/passport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAiBH;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAAyB;IAEzB,+DAA+D;IAC/D,iEAAiE;IACjE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAK7D,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,KAAK,EAClB,GAAG,IAAe,EACH,EAAE;QACjB,0EAA0E;QAC1E,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAW,CAAC;QACtC,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,CAAuB,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAwD,CAAC;QAE5E,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,eAAe,EAAE;gBACjD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE;aACpD,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAC;YAC/D,IAAI,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,IAAI,cAAc,CACvB;QACE,gBAAgB,EAAE,GAAG,OAAO,wBAAwB;QACpD,QAAQ,EAAE,GAAG,OAAO,+BAA+B;QACnD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE;QACvC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,sBAAsB;QAC7C,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,iBAAiB,EAAE,IAAI;KACxB,EACD,MAAM,CACP,CAAC;AACJ,CAAC"}
|