@svadmin/kinde 0.0.0-stage → 0.2.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/package.json CHANGED
@@ -1,6 +1,50 @@
1
1
  {
2
2
  "name": "@svadmin/kinde",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "Kinde AuthProvider adapter for svadmin",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "src/**/*.ts",
9
+ "!src/**/*.test.*",
10
+ "!src/**/*.spec.*"
11
+ ],
12
+ "main": "src/index.ts",
13
+ "types": "src/index.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./src/index.ts",
17
+ "default": "./src/index.ts"
18
+ }
19
+ },
20
+ "peerDependencies": {
21
+ "@svadmin/core": "^0.78.0"
22
+ },
23
+ "keywords": [
24
+ "svadmin",
25
+ "kinde",
26
+ "auth",
27
+ "auth-provider",
28
+ "identity",
29
+ "rbac"
30
+ ],
31
+ "license": "MIT",
32
+ "author": "zuohuadong",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/vibeunion/svadmin.git",
36
+ "directory": "packages/kinde"
37
+ },
38
+ "homepage": "https://github.com/vibeunion/svadmin#readme",
39
+ "bugs": {
40
+ "url": "https://github.com/vibeunion/svadmin/issues"
41
+ },
42
+ "svadmin": {
43
+ "capabilities": [
44
+ "auth"
45
+ ],
46
+ "core": "^0.55.0",
47
+ "stability": "stable",
48
+ "migration": null
49
+ }
50
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { createKindeAuthProvider } from './kinde-auth-provider.js';
2
+ export type {
3
+ KindeUserLike,
4
+ KindeClientLike,
5
+ KindeAuthOptions,
6
+ } from './kinde-auth-provider.js';
@@ -0,0 +1,136 @@
1
+ import type {
2
+ AuthProvider,
3
+ AuthActionResult,
4
+ CheckResult,
5
+ Identity,
6
+ AuthErrorResult,
7
+ } from '@svadmin/core';
8
+
9
+ export interface KindeUserLike {
10
+ id: string;
11
+ given_name?: string | null;
12
+ family_name?: string | null;
13
+ email?: string | null;
14
+ picture?: string | null;
15
+ [key: string]: unknown;
16
+ }
17
+
18
+ export interface KindeClientLike {
19
+ isAuthenticated: () => Promise<boolean>;
20
+ getUser: () => Promise<KindeUserLike | undefined>;
21
+ getUserProfile?: () => Promise<KindeUserLike | undefined>;
22
+ login?: (options?: Record<string, unknown>) => Promise<void>;
23
+ register?: (options?: Record<string, unknown>) => Promise<void>;
24
+ logout?: (options?: Record<string, unknown>) => Promise<void> | void;
25
+ getToken?: () => Promise<string>;
26
+ getPermissions?: () => Promise<{ permissions: string[]; orgCode?: string } | undefined>;
27
+ getOrganization?: () => Promise<{ orgCode: string } | undefined>;
28
+ }
29
+
30
+ export interface KindeAuthOptions {
31
+ /** Fallback login redirect path or URL */
32
+ loginUrl?: string;
33
+ /** Return URI after logout. Defaults to '/' */
34
+ logoutRedirectUri?: string;
35
+ /** Default fallback role when no permissions are found. Defaults to 'user' */
36
+ defaultRole?: string;
37
+ }
38
+
39
+ export function createKindeAuthProvider(
40
+ kinde: KindeClientLike,
41
+ options: KindeAuthOptions = {},
42
+ ): AuthProvider {
43
+ const defaultRole = options.defaultRole ?? 'user';
44
+
45
+ return {
46
+ async login(params: Record<string, unknown> = {}): Promise<AuthActionResult> {
47
+ try {
48
+ if (kinde.login) {
49
+ await kinde.login(params);
50
+ return { success: true };
51
+ }
52
+ if (options.loginUrl && typeof window !== 'undefined') {
53
+ window.location.href = options.loginUrl;
54
+ return { success: true };
55
+ }
56
+ return {
57
+ success: false,
58
+ error: {
59
+ name: 'KINDE_NOT_CONFIGURED',
60
+ message: 'Kinde client login method is not available.',
61
+ },
62
+ };
63
+ } catch (err: unknown) {
64
+ const error = err instanceof Error ? err : new Error(String(err));
65
+ return {
66
+ success: false,
67
+ error: {
68
+ name: error.name || 'KINDE_LOGIN_ERROR',
69
+ message: error.message,
70
+ },
71
+ };
72
+ }
73
+ },
74
+
75
+ async logout(params?: Record<string, unknown>): Promise<AuthActionResult> {
76
+ const returnTo = options.logoutRedirectUri ?? (typeof window !== 'undefined' ? window.location.origin : '/');
77
+ if (kinde.logout) {
78
+ await kinde.logout(params);
79
+ }
80
+ return { success: true, redirectTo: returnTo };
81
+ },
82
+
83
+ async check(): Promise<CheckResult> {
84
+ try {
85
+ const authenticated = await kinde.isAuthenticated();
86
+ if (authenticated) {
87
+ return { authenticated: true };
88
+ }
89
+ return {
90
+ authenticated: false,
91
+ ...(options.loginUrl ? { redirectTo: options.loginUrl } : {}),
92
+ };
93
+ } catch {
94
+ return {
95
+ authenticated: false,
96
+ ...(options.loginUrl ? { redirectTo: options.loginUrl } : {}),
97
+ };
98
+ }
99
+ },
100
+
101
+ async getIdentity(): Promise<Identity | null> {
102
+ const user = (await kinde.getUserProfile?.()) ?? (await kinde.getUser());
103
+ if (!user) return null;
104
+
105
+ const parts = [user.given_name, user.family_name].filter(Boolean);
106
+ const computedName = parts.length > 0 ? parts.join(' ') : 'Anonymous User';
107
+
108
+ return {
109
+ id: user.id ?? 'unknown',
110
+ name: computedName,
111
+ ...(user.email ? { email: user.email } : {}),
112
+ ...(user.picture ? { avatar: user.picture } : {}),
113
+ };
114
+ },
115
+
116
+ async getPermissions(): Promise<unknown> {
117
+ const perms = await kinde.getPermissions?.();
118
+ if (perms?.permissions && perms.permissions.length > 0) {
119
+ return perms.permissions;
120
+ }
121
+ return [defaultRole];
122
+ },
123
+
124
+ async onError(error: unknown): Promise<AuthErrorResult> {
125
+ const status = (error as { status?: number; statusCode?: number })?.status ??
126
+ (error as { status?: number; statusCode?: number })?.statusCode;
127
+ if (status === 401 || status === 403) {
128
+ return {
129
+ logout: true,
130
+ redirectTo: options.loginUrl ?? '/login',
131
+ };
132
+ }
133
+ return {};
134
+ },
135
+ };
136
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.