@k3-universe/react-kit 0.0.29 → 0.0.31
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1023 -25
- package/dist/kit/builder/auth/components/Can.d.ts +13 -0
- package/dist/kit/builder/auth/components/Can.d.ts.map +1 -0
- package/dist/kit/builder/auth/components/RequireAuth.d.ts +45 -0
- package/dist/kit/builder/auth/components/RequireAuth.d.ts.map +1 -0
- package/dist/kit/builder/auth/components/ShowWhenAuthenticated.d.ts +8 -0
- package/dist/kit/builder/auth/components/ShowWhenAuthenticated.d.ts.map +1 -0
- package/dist/kit/builder/auth/components/ShowWhenError.d.ts +8 -0
- package/dist/kit/builder/auth/components/ShowWhenError.d.ts.map +1 -0
- package/dist/kit/builder/auth/components/ShowWhenLoading.d.ts +8 -0
- package/dist/kit/builder/auth/components/ShowWhenLoading.d.ts.map +1 -0
- package/dist/kit/builder/auth/components/ShowWhenUnauthenticated.d.ts +8 -0
- package/dist/kit/builder/auth/components/ShowWhenUnauthenticated.d.ts.map +1 -0
- package/dist/kit/builder/auth/components/withPermission.d.ts +7 -0
- package/dist/kit/builder/auth/components/withPermission.d.ts.map +1 -0
- package/dist/kit/builder/auth/hooks/action-hooks.d.ts +18 -0
- package/dist/kit/builder/auth/hooks/action-hooks.d.ts.map +1 -0
- package/dist/kit/builder/auth/hooks/core-hooks.d.ts +56 -0
- package/dist/kit/builder/auth/hooks/core-hooks.d.ts.map +1 -0
- package/dist/kit/builder/auth/hooks/index.d.ts +5 -0
- package/dist/kit/builder/auth/hooks/index.d.ts.map +1 -0
- package/dist/kit/builder/auth/hooks/permission-hooks.d.ts +18 -0
- package/dist/kit/builder/auth/hooks/permission-hooks.d.ts.map +1 -0
- package/dist/kit/builder/auth/hooks/token-hooks.d.ts +13 -0
- package/dist/kit/builder/auth/hooks/token-hooks.d.ts.map +1 -0
- package/dist/kit/builder/auth/index.d.ts +14 -8
- package/dist/kit/builder/auth/index.d.ts.map +1 -1
- package/dist/kit/builder/auth/{AuthProvider.d.ts → providers/AuthProvider.d.ts} +1 -1
- package/dist/kit/builder/auth/providers/AuthProvider.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/adapter-config.d.ts +31 -0
- package/dist/kit/builder/auth/types/adapter-config.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/adapter.d.ts +80 -0
- package/dist/kit/builder/auth/types/adapter.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/core.d.ts +16 -0
- package/dist/kit/builder/auth/types/core.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/index.d.ts +10 -0
- package/dist/kit/builder/auth/types/index.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/middleware.d.ts +11 -0
- package/dist/kit/builder/auth/types/middleware.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/permissions.d.ts +17 -0
- package/dist/kit/builder/auth/types/permissions.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/state.d.ts +13 -0
- package/dist/kit/builder/auth/types/state.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/storage.d.ts +20 -0
- package/dist/kit/builder/auth/types/storage.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/token-manager.d.ts +7 -0
- package/dist/kit/builder/auth/types/token-manager.d.ts.map +1 -0
- package/dist/kit/builder/auth/types/utils.d.ts +7 -0
- package/dist/kit/builder/auth/types/utils.d.ts.map +1 -0
- package/dist/kit/builder/auth/{adapter.d.ts → utils/auth-adapter.d.ts} +2 -2
- package/dist/kit/builder/auth/utils/auth-adapter.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/client-adapters/apollo-link.d.ts +4 -0
- package/dist/kit/builder/auth/utils/client-adapters/apollo-link.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/client-adapters/axios.d.ts +6 -0
- package/dist/kit/builder/auth/utils/client-adapters/axios.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/client-adapters/fetch.d.ts +6 -0
- package/dist/kit/builder/auth/utils/client-adapters/fetch.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/client-adapters/graphql.d.ts +9 -0
- package/dist/kit/builder/auth/utils/client-adapters/graphql.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/client-adapters/index.d.ts +7 -0
- package/dist/kit/builder/auth/utils/client-adapters/index.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/client-adapters/rest.d.ts +9 -0
- package/dist/kit/builder/auth/utils/client-adapters/rest.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/client-adapters/urql-exchange.d.ts +14 -0
- package/dist/kit/builder/auth/utils/client-adapters/urql-exchange.d.ts.map +1 -0
- package/dist/kit/builder/auth/{permission-checker.d.ts → utils/permission-checker.d.ts} +1 -1
- package/dist/kit/builder/auth/utils/permission-checker.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/storage/browser.d.ts +11 -0
- package/dist/kit/builder/auth/utils/storage/browser.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/storage/cookie.d.ts +3 -0
- package/dist/kit/builder/auth/utils/storage/cookie.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/storage/encryption.d.ts +7 -0
- package/dist/kit/builder/auth/utils/storage/encryption.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/storage/env.d.ts +2 -0
- package/dist/kit/builder/auth/utils/storage/env.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/storage/factory.d.ts +6 -0
- package/dist/kit/builder/auth/utils/storage/factory.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/storage/index.d.ts +7 -0
- package/dist/kit/builder/auth/utils/storage/index.d.ts.map +1 -0
- package/dist/kit/builder/auth/utils/storage/memory.d.ts +3 -0
- package/dist/kit/builder/auth/utils/storage/memory.d.ts.map +1 -0
- package/dist/kit/builder/auth/{token-manager.d.ts → utils/token-manager.d.ts} +1 -1
- package/dist/kit/builder/auth/utils/token-manager.d.ts.map +1 -0
- package/dist/kit/components/login/Login.d.ts +2 -1
- package/dist/kit/components/login/Login.d.ts.map +1 -1
- package/dist/kit/layouts/admin/components/AdminLayout.d.ts +2 -1
- package/dist/kit/layouts/admin/components/AdminLayout.d.ts.map +1 -1
- package/dist/kit/themes/clean-slate.css +28 -4
- package/dist/kit/themes/default.css +28 -4
- package/dist/kit/themes/minimal-modern.css +28 -4
- package/dist/kit/themes/spotify.css +28 -4
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/kit/builder/auth/components/Can.tsx +27 -0
- package/src/kit/builder/auth/components/RequireAuth.tsx +78 -0
- package/src/kit/builder/auth/components/ShowWhenAuthenticated.tsx +10 -0
- package/src/kit/builder/auth/components/ShowWhenError.tsx +10 -0
- package/src/kit/builder/auth/components/ShowWhenLoading.tsx +10 -0
- package/src/kit/builder/auth/components/ShowWhenUnauthenticated.tsx +10 -0
- package/src/kit/builder/auth/components/withPermission.tsx +23 -0
- package/src/kit/builder/auth/hooks/action-hooks.ts +34 -0
- package/src/kit/builder/auth/hooks/core-hooks.ts +65 -0
- package/src/kit/builder/auth/hooks/index.ts +4 -0
- package/src/kit/builder/auth/hooks/permission-hooks.ts +43 -0
- package/src/kit/builder/auth/hooks/token-hooks.ts +25 -0
- package/src/kit/builder/auth/index.ts +16 -18
- package/src/kit/builder/auth/{AuthProvider.tsx → providers/AuthProvider.tsx} +1 -1
- package/src/kit/builder/auth/types/adapter-config.ts +44 -0
- package/src/kit/builder/auth/types/adapter.ts +132 -0
- package/src/kit/builder/auth/types/core.ts +27 -0
- package/src/kit/builder/auth/types/index.ts +9 -0
- package/src/kit/builder/auth/types/middleware.ts +20 -0
- package/src/kit/builder/auth/types/permissions.ts +23 -0
- package/src/kit/builder/auth/types/state.ts +16 -0
- package/src/kit/builder/auth/types/storage.ts +21 -0
- package/src/kit/builder/auth/types/token-manager.ts +9 -0
- package/src/kit/builder/auth/types/utils.ts +55 -0
- package/src/kit/builder/auth/{adapter.ts → utils/auth-adapter.ts} +3 -2
- package/src/kit/builder/auth/utils/client-adapters/apollo-link.ts +30 -0
- package/src/kit/builder/auth/utils/client-adapters/axios.ts +61 -0
- package/src/kit/builder/auth/utils/client-adapters/fetch.ts +48 -0
- package/src/kit/builder/auth/utils/client-adapters/graphql.ts +60 -0
- package/src/kit/builder/auth/utils/client-adapters/index.ts +6 -0
- package/src/kit/builder/auth/utils/client-adapters/rest.ts +60 -0
- package/src/kit/builder/auth/utils/client-adapters/urql-exchange.ts +76 -0
- package/src/kit/builder/auth/{permission-checker.ts → utils/permission-checker.ts} +1 -1
- package/src/kit/builder/auth/utils/storage/browser.ts +99 -0
- package/src/kit/builder/auth/utils/storage/cookie.ts +116 -0
- package/src/kit/builder/auth/utils/storage/encryption.ts +80 -0
- package/src/kit/builder/auth/utils/storage/env.ts +2 -0
- package/src/kit/builder/auth/utils/storage/factory.ts +37 -0
- package/src/kit/builder/auth/utils/storage/index.ts +6 -0
- package/src/kit/builder/auth/utils/storage/memory.ts +15 -0
- package/src/kit/builder/auth/{token-manager.ts → utils/token-manager.ts} +1 -1
- package/src/kit/components/login/Login.tsx +36 -21
- package/src/kit/layouts/admin/components/AdminLayout.tsx +24 -17
- package/dist/kit/builder/auth/AuthProvider.d.ts.map +0 -1
- package/dist/kit/builder/auth/adapter.d.ts.map +0 -1
- package/dist/kit/builder/auth/client-adapters.d.ts +0 -149
- package/dist/kit/builder/auth/client-adapters.d.ts.map +0 -1
- package/dist/kit/builder/auth/components.d.ts +0 -119
- package/dist/kit/builder/auth/components.d.ts.map +0 -1
- package/dist/kit/builder/auth/hooks.d.ts +0 -158
- package/dist/kit/builder/auth/hooks.d.ts.map +0 -1
- package/dist/kit/builder/auth/permission-checker.d.ts.map +0 -1
- package/dist/kit/builder/auth/storage.d.ts +0 -17
- package/dist/kit/builder/auth/storage.d.ts.map +0 -1
- package/dist/kit/builder/auth/token-manager.d.ts.map +0 -1
- package/dist/kit/builder/auth/types.d.ts +0 -183
- package/dist/kit/builder/auth/types.d.ts.map +0 -1
- package/src/kit/builder/auth/client-adapters.ts +0 -398
- package/src/kit/builder/auth/components.tsx +0 -221
- package/src/kit/builder/auth/hooks.ts +0 -237
- package/src/kit/builder/auth/storage.ts +0 -366
- package/src/kit/builder/auth/types.ts +0 -393
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { RequireAuthProps } from '../types';
|
|
2
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component that requires authentication
|
|
6
|
+
* Optionally checks for specific roles and permissions
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* // Basic authentication check
|
|
11
|
+
* <RequireAuth fallback={<Login />}>
|
|
12
|
+
* <Dashboard />
|
|
13
|
+
* </RequireAuth>
|
|
14
|
+
*
|
|
15
|
+
* // With role check
|
|
16
|
+
* <RequireAuth
|
|
17
|
+
* roles="admin"
|
|
18
|
+
* fallback={<Forbidden />}
|
|
19
|
+
* loadingFallback={<Spinner />}
|
|
20
|
+
* >
|
|
21
|
+
* <AdminPanel />
|
|
22
|
+
* </RequireAuth>
|
|
23
|
+
*
|
|
24
|
+
* // With permission check
|
|
25
|
+
* <RequireAuth
|
|
26
|
+
* permissions={['post:edit', 'post:delete']}
|
|
27
|
+
* fallback={<Forbidden />}
|
|
28
|
+
* >
|
|
29
|
+
* <PostEditor />
|
|
30
|
+
* </RequireAuth>
|
|
31
|
+
*
|
|
32
|
+
* // Complex rule
|
|
33
|
+
* <RequireAuth
|
|
34
|
+
* roles={['admin', 'moderator']}
|
|
35
|
+
* permissions={{
|
|
36
|
+
* operator: 'OR',
|
|
37
|
+
* permissions: ['post:edit', 'post:delete']
|
|
38
|
+
* }}
|
|
39
|
+
* requireAll={false}
|
|
40
|
+
* fallback={<Forbidden />}
|
|
41
|
+
* >
|
|
42
|
+
* <ContentManager />
|
|
43
|
+
* </RequireAuth>
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function RequireAuth<
|
|
47
|
+
TRole extends string = string,
|
|
48
|
+
TPermission extends string = string,
|
|
49
|
+
>({
|
|
50
|
+
children,
|
|
51
|
+
fallback = null,
|
|
52
|
+
loadingFallback = null,
|
|
53
|
+
roles,
|
|
54
|
+
permissions,
|
|
55
|
+
requireAll = true,
|
|
56
|
+
}: RequireAuthProps<TRole, TPermission>) {
|
|
57
|
+
const { status, can } = useAuthContext();
|
|
58
|
+
|
|
59
|
+
if (status === 'loading' || status === 'idle') {
|
|
60
|
+
return loadingFallback;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (status !== 'authenticated') {
|
|
64
|
+
return fallback;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!roles && !permissions) {
|
|
68
|
+
return children;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const allowed = can({ roles, permissions, requireAll });
|
|
72
|
+
|
|
73
|
+
if (!allowed) {
|
|
74
|
+
return fallback;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return children;
|
|
78
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component that shows children only when authenticated.
|
|
6
|
+
*/
|
|
7
|
+
export function ShowWhenAuthenticated({ children }: { children: ReactNode }) {
|
|
8
|
+
const { status } = useAuthContext();
|
|
9
|
+
return status === 'authenticated' ? children : null;
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component that shows children only when there's an error.
|
|
6
|
+
*/
|
|
7
|
+
export function ShowWhenError({ children }: { children: ReactNode }) {
|
|
8
|
+
const { status } = useAuthContext();
|
|
9
|
+
return status === 'error' ? children : null;
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component that shows children only while loading.
|
|
6
|
+
*/
|
|
7
|
+
export function ShowWhenLoading({ children }: { children: ReactNode }) {
|
|
8
|
+
const { status } = useAuthContext();
|
|
9
|
+
return status === 'loading' ? children : null;
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component that shows children only when NOT authenticated.
|
|
6
|
+
*/
|
|
7
|
+
export function ShowWhenUnauthenticated({ children }: { children: ReactNode }) {
|
|
8
|
+
const { status } = useAuthContext();
|
|
9
|
+
return status === 'unauthenticated' ? children : null;
|
|
10
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
2
|
+
import type { WithPermissionOptions } from '../types';
|
|
3
|
+
import { useCan } from '../hooks';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Higher-order component that wraps a component with permission checks.
|
|
7
|
+
*/
|
|
8
|
+
export function withPermission<
|
|
9
|
+
TRole extends string = string,
|
|
10
|
+
TPermission extends string = string,
|
|
11
|
+
TProps extends Record<string, unknown> = Record<string, unknown>,
|
|
12
|
+
>(
|
|
13
|
+
Component: ComponentType<TProps>,
|
|
14
|
+
options: WithPermissionOptions<TRole, TPermission>,
|
|
15
|
+
): ComponentType<TProps> {
|
|
16
|
+
const WithPermissionWrapper = (props: TProps) => {
|
|
17
|
+
const allowed = useCan(options);
|
|
18
|
+
if (!allowed) return null;
|
|
19
|
+
return <Component {...props} />;
|
|
20
|
+
};
|
|
21
|
+
WithPermissionWrapper.displayName = `WithPermission(${Component.displayName ?? Component.name ?? 'Component'})`;
|
|
22
|
+
return WithPermissionWrapper as ComponentType<TProps>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AuthSession } from '../types';
|
|
2
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook to get the login function.
|
|
6
|
+
*/
|
|
7
|
+
export function useLogin<TCredentials = unknown>() {
|
|
8
|
+
const { login } = useAuthContext();
|
|
9
|
+
return login as ((credentials: TCredentials) => Promise<unknown>) | undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Hook to get the logout function.
|
|
14
|
+
*/
|
|
15
|
+
export function useLogout() {
|
|
16
|
+
const { logout } = useAuthContext();
|
|
17
|
+
return logout;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Hook to get the refresh function.
|
|
22
|
+
*/
|
|
23
|
+
export function useRefresh() {
|
|
24
|
+
const { refresh } = useAuthContext();
|
|
25
|
+
return refresh;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Hook to get the setSession function.
|
|
30
|
+
*/
|
|
31
|
+
export function useSetSession<TSession extends AuthSession>() {
|
|
32
|
+
const { setSession } = useAuthContext();
|
|
33
|
+
return setSession as (session: TSession | null) => Promise<unknown>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { AuthSession } from '../types';
|
|
2
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook to access the entire auth context
|
|
6
|
+
*/
|
|
7
|
+
export function useAuth() {
|
|
8
|
+
return useAuthContext();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Hook to get the current auth status
|
|
13
|
+
*/
|
|
14
|
+
export function useAuthStatus() {
|
|
15
|
+
const { status } = useAuthContext();
|
|
16
|
+
return status;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Hook to check if user is authenticated
|
|
21
|
+
*/
|
|
22
|
+
export function useIsAuthenticated() {
|
|
23
|
+
const { status } = useAuthContext();
|
|
24
|
+
return status === 'authenticated';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Hook to get the current session
|
|
29
|
+
*/
|
|
30
|
+
export function useAuthSession<TSession extends AuthSession>() {
|
|
31
|
+
const { session } = useAuthContext();
|
|
32
|
+
return session as TSession | null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Hook to get the current user
|
|
37
|
+
*/
|
|
38
|
+
export function useAuthUser<TUser>() {
|
|
39
|
+
const { user } = useAuthContext();
|
|
40
|
+
return user as TUser | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Hook to get user roles
|
|
45
|
+
*/
|
|
46
|
+
export function useAuthRoles<TRole extends string = string>() {
|
|
47
|
+
const { roles } = useAuthContext();
|
|
48
|
+
return roles as TRole[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Hook to get user permissions
|
|
53
|
+
*/
|
|
54
|
+
export function useAuthPermissions<TPermission extends string = string>() {
|
|
55
|
+
const { permissions } = useAuthContext();
|
|
56
|
+
return permissions as TPermission[];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Hook to get authentication error
|
|
61
|
+
*/
|
|
62
|
+
export function useAuthError() {
|
|
63
|
+
const { error } = useAuthContext();
|
|
64
|
+
return error;
|
|
65
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PermissionPolicy,
|
|
3
|
+
PermissionRule,
|
|
4
|
+
WithPermissionOptions,
|
|
5
|
+
} from '../types';
|
|
6
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hook to check if user has specific permission(s).
|
|
10
|
+
*/
|
|
11
|
+
export function usePermission<TPermission extends string = string>(
|
|
12
|
+
permission: TPermission | TPermission[] | PermissionPolicy<TPermission>,
|
|
13
|
+
options?: { requireAll?: boolean },
|
|
14
|
+
) {
|
|
15
|
+
const { hasPermission } = useAuthContext();
|
|
16
|
+
return hasPermission(permission, options);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Hook to check if user has specific role(s).
|
|
21
|
+
*/
|
|
22
|
+
export function useRole<TRole extends string = string>(
|
|
23
|
+
roles: TRole | TRole[],
|
|
24
|
+
options?: { requireAll?: boolean },
|
|
25
|
+
) {
|
|
26
|
+
const { hasRole } = useAuthContext();
|
|
27
|
+
return hasRole(roles, options);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Hook to check complex permission rules.
|
|
32
|
+
*/
|
|
33
|
+
export function useCan<
|
|
34
|
+
TRole extends string = string,
|
|
35
|
+
TPermission extends string = string,
|
|
36
|
+
>(
|
|
37
|
+
rule:
|
|
38
|
+
| WithPermissionOptions<TRole, TPermission>
|
|
39
|
+
| PermissionRule<TRole, TPermission>,
|
|
40
|
+
) {
|
|
41
|
+
const { can } = useAuthContext();
|
|
42
|
+
return can(rule as PermissionRule<TRole, TPermission>);
|
|
43
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useAuthContext } from '../providers/AuthProvider';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hook to get the current auth token.
|
|
5
|
+
*/
|
|
6
|
+
export function useAuthToken() {
|
|
7
|
+
const { getToken } = useAuthContext();
|
|
8
|
+
return getToken();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Hook to check if token is expired.
|
|
13
|
+
*/
|
|
14
|
+
export function useIsTokenExpired() {
|
|
15
|
+
const { isTokenExpired } = useAuthContext();
|
|
16
|
+
return isTokenExpired();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Hook to get time until token expiry in milliseconds.
|
|
21
|
+
*/
|
|
22
|
+
export function useTimeUntilExpiry() {
|
|
23
|
+
const { getTimeUntilExpiry } = useAuthContext();
|
|
24
|
+
return getTimeUntilExpiry();
|
|
25
|
+
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Core
|
|
3
3
|
// ============================================================================
|
|
4
4
|
|
|
5
|
-
export { createAuthAdapter } from
|
|
6
|
-
export { AuthProvider, useAuthContext } from
|
|
5
|
+
export { createAuthAdapter } from "./utils/auth-adapter";
|
|
6
|
+
export { AuthProvider, useAuthContext } from "./providers/AuthProvider";
|
|
7
7
|
|
|
8
8
|
// ============================================================================
|
|
9
9
|
// Storage
|
|
@@ -14,20 +14,20 @@ export {
|
|
|
14
14
|
createMemoryStorage,
|
|
15
15
|
createBrowserStorage,
|
|
16
16
|
createCookieStorage,
|
|
17
|
-
} from
|
|
17
|
+
} from "./utils/storage";
|
|
18
18
|
|
|
19
19
|
// ============================================================================
|
|
20
20
|
// Utilities
|
|
21
21
|
// ============================================================================
|
|
22
22
|
|
|
23
|
-
export { createTokenManager } from
|
|
23
|
+
export { createTokenManager } from "./utils/token-manager";
|
|
24
24
|
export {
|
|
25
25
|
expandPermissions,
|
|
26
26
|
expandRoles,
|
|
27
27
|
checkPermissions,
|
|
28
28
|
checkRoles,
|
|
29
29
|
evaluatePermissionRule,
|
|
30
|
-
} from
|
|
30
|
+
} from "./utils/permission-checker";
|
|
31
31
|
|
|
32
32
|
// ============================================================================
|
|
33
33
|
// Client Adapters
|
|
@@ -39,12 +39,12 @@ export {
|
|
|
39
39
|
createAxiosAuthInterceptor,
|
|
40
40
|
createAuthFetch,
|
|
41
41
|
createApolloAuthLink,
|
|
42
|
-
} from
|
|
42
|
+
} from "./utils/client-adapters";
|
|
43
43
|
|
|
44
44
|
export type {
|
|
45
45
|
GraphQLClientAdapterOptions,
|
|
46
46
|
RESTClientAdapterOptions,
|
|
47
|
-
} from
|
|
47
|
+
} from "./utils/client-adapters";
|
|
48
48
|
|
|
49
49
|
// ============================================================================
|
|
50
50
|
// Hooks
|
|
@@ -69,21 +69,19 @@ export {
|
|
|
69
69
|
useLogout,
|
|
70
70
|
useRefresh,
|
|
71
71
|
useSetSession,
|
|
72
|
-
} from
|
|
72
|
+
} from "./hooks";
|
|
73
73
|
|
|
74
74
|
// ============================================================================
|
|
75
75
|
// Components
|
|
76
76
|
// ============================================================================
|
|
77
77
|
|
|
78
|
-
export {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
ShowWhenError,
|
|
86
|
-
} from './components';
|
|
78
|
+
export { RequireAuth } from "./components/RequireAuth";
|
|
79
|
+
export { Can } from "./components/Can";
|
|
80
|
+
export { withPermission } from "./components/withPermission";
|
|
81
|
+
export { ShowWhenAuthenticated } from "./components/ShowWhenAuthenticated";
|
|
82
|
+
export { ShowWhenUnauthenticated } from "./components/ShowWhenUnauthenticated";
|
|
83
|
+
export { ShowWhenLoading } from "./components/ShowWhenLoading";
|
|
84
|
+
export { ShowWhenError } from "./components/ShowWhenError";
|
|
87
85
|
|
|
88
86
|
// ============================================================================
|
|
89
87
|
// Types
|
|
@@ -131,4 +129,4 @@ export type {
|
|
|
131
129
|
InferRole,
|
|
132
130
|
InferPermission,
|
|
133
131
|
InferCredentials,
|
|
134
|
-
} from
|
|
132
|
+
} from "./types";
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
useSyncExternalStore,
|
|
7
7
|
} from 'react';
|
|
8
8
|
import type { ReactNode } from 'react';
|
|
9
|
-
import type { AuthAdapter, AuthContextValue, AuthSession } from '
|
|
9
|
+
import type { AuthAdapter, AuthContextValue, AuthSession } from '../types';
|
|
10
10
|
|
|
11
11
|
type AnyAuthContextValue = AuthContextValue<
|
|
12
12
|
unknown,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AuthSession, RefreshStrategy } from './core';
|
|
2
|
+
import type { PermissionHierarchy, RoleHierarchy } from './permissions';
|
|
3
|
+
import type { AuthAdapterState } from './state';
|
|
4
|
+
import type { AuthMiddleware } from './middleware';
|
|
5
|
+
import type { TokenManager } from './token-manager';
|
|
6
|
+
import type { AuthStorage } from './storage';
|
|
7
|
+
|
|
8
|
+
export type AuthAdapterConfig<
|
|
9
|
+
TUser = unknown,
|
|
10
|
+
TRole extends string = string,
|
|
11
|
+
TPermission extends string = string,
|
|
12
|
+
TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
|
|
13
|
+
TUser,
|
|
14
|
+
TRole,
|
|
15
|
+
TPermission
|
|
16
|
+
>,
|
|
17
|
+
TCredentials = unknown,
|
|
18
|
+
> = {
|
|
19
|
+
storage?: AuthStorage<TSession>;
|
|
20
|
+
loadSession?: () => Promise<TSession | null>;
|
|
21
|
+
login?: (credentials: TCredentials) => Promise<TSession>;
|
|
22
|
+
logout?: (session: TSession | null) => Promise<void> | void;
|
|
23
|
+
refresh?: (session: TSession) => Promise<TSession>;
|
|
24
|
+
resolveUser?: (session: TSession | null) => TUser | null;
|
|
25
|
+
resolveRoles?: (session: TSession | null) => TRole[];
|
|
26
|
+
resolvePermissions?: (session: TSession | null) => TPermission[];
|
|
27
|
+
shouldRefresh?: (session: TSession) => boolean;
|
|
28
|
+
onStateChange?: (
|
|
29
|
+
state: AuthAdapterState<TSession, TUser, TRole, TPermission>,
|
|
30
|
+
) => void;
|
|
31
|
+
|
|
32
|
+
refreshStrategy?: RefreshStrategy;
|
|
33
|
+
refreshThreshold?: number;
|
|
34
|
+
autoRefresh?: boolean;
|
|
35
|
+
permissionHierarchy?: PermissionHierarchy<TPermission>;
|
|
36
|
+
roleHierarchy?: RoleHierarchy<TRole>;
|
|
37
|
+
middleware?: AuthMiddleware<TSession, TUser, TRole, TPermission>[];
|
|
38
|
+
tokenManager?: TokenManager;
|
|
39
|
+
retryConfig?: {
|
|
40
|
+
maxRetries?: number;
|
|
41
|
+
retryDelay?: number;
|
|
42
|
+
retryOn?: (error: unknown) => boolean;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { AuthSession } from './core';
|
|
2
|
+
import type { PermissionPolicy, PermissionRule } from './permissions';
|
|
3
|
+
import type { AuthAdapterState, AuthAdapterSubscriber } from './state';
|
|
4
|
+
|
|
5
|
+
export type AuthAdapter<
|
|
6
|
+
TUser = unknown,
|
|
7
|
+
TRole extends string = string,
|
|
8
|
+
TPermission extends string = string,
|
|
9
|
+
TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
|
|
10
|
+
TUser,
|
|
11
|
+
TRole,
|
|
12
|
+
TPermission
|
|
13
|
+
>,
|
|
14
|
+
TCredentials = unknown,
|
|
15
|
+
> = {
|
|
16
|
+
getState: () => AuthAdapterState<TSession, TUser, TRole, TPermission>;
|
|
17
|
+
subscribe: (
|
|
18
|
+
listener: AuthAdapterSubscriber<TSession, TUser, TRole, TPermission>,
|
|
19
|
+
) => () => void;
|
|
20
|
+
sync: () => Promise<AuthAdapterState<TSession, TUser, TRole, TPermission>>;
|
|
21
|
+
login?: (
|
|
22
|
+
credentials: TCredentials,
|
|
23
|
+
) => Promise<AuthAdapterState<TSession, TUser, TRole, TPermission>>;
|
|
24
|
+
logout: () => Promise<void>;
|
|
25
|
+
refresh: () => Promise<AuthAdapterState<TSession, TUser, TRole, TPermission>>;
|
|
26
|
+
setSession: (
|
|
27
|
+
session: TSession | null,
|
|
28
|
+
) => Promise<AuthAdapterState<TSession, TUser, TRole, TPermission>>;
|
|
29
|
+
hasRole: (
|
|
30
|
+
target: TRole | TRole[],
|
|
31
|
+
options?: { requireAll?: boolean },
|
|
32
|
+
) => boolean;
|
|
33
|
+
hasPermission: (
|
|
34
|
+
target: TPermission | TPermission[] | PermissionPolicy<TPermission>,
|
|
35
|
+
options?: { requireAll?: boolean },
|
|
36
|
+
) => boolean;
|
|
37
|
+
can: (rule: PermissionRule<TRole, TPermission>) => boolean;
|
|
38
|
+
getToken: () => string | null;
|
|
39
|
+
isTokenExpired: () => boolean;
|
|
40
|
+
getTimeUntilExpiry: () => number;
|
|
41
|
+
scheduleAutoRefresh?: () => () => void;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type AuthContextValue<
|
|
45
|
+
TUser = unknown,
|
|
46
|
+
TRole extends string = string,
|
|
47
|
+
TPermission extends string = string,
|
|
48
|
+
TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
|
|
49
|
+
TUser,
|
|
50
|
+
TRole,
|
|
51
|
+
TPermission
|
|
52
|
+
>,
|
|
53
|
+
TCredentials = unknown,
|
|
54
|
+
> = {
|
|
55
|
+
state: AuthAdapterState<TSession, TUser, TRole, TPermission>;
|
|
56
|
+
status: AuthAdapterState<TSession, TUser, TRole, TPermission>['status'];
|
|
57
|
+
session: TSession | null;
|
|
58
|
+
user: TUser | null;
|
|
59
|
+
roles: TRole[];
|
|
60
|
+
permissions: TPermission[];
|
|
61
|
+
error?: unknown;
|
|
62
|
+
login?: (
|
|
63
|
+
credentials: TCredentials,
|
|
64
|
+
) => Promise<AuthAdapterState<TSession, TUser, TRole, TPermission>>;
|
|
65
|
+
logout: () => Promise<void>;
|
|
66
|
+
refresh: () => Promise<AuthAdapterState<TSession, TUser, TRole, TPermission>>;
|
|
67
|
+
setSession: (
|
|
68
|
+
session: TSession | null,
|
|
69
|
+
) => Promise<AuthAdapterState<TSession, TUser, TRole, TPermission>>;
|
|
70
|
+
hasRole: (
|
|
71
|
+
target: TRole | TRole[],
|
|
72
|
+
options?: { requireAll?: boolean },
|
|
73
|
+
) => boolean;
|
|
74
|
+
hasPermission: (
|
|
75
|
+
target: TPermission | TPermission[] | PermissionPolicy<TPermission>,
|
|
76
|
+
options?: { requireAll?: boolean },
|
|
77
|
+
) => boolean;
|
|
78
|
+
can: (rule: PermissionRule<TRole, TPermission>) => boolean;
|
|
79
|
+
getToken: () => string | null;
|
|
80
|
+
isTokenExpired: () => boolean;
|
|
81
|
+
getTimeUntilExpiry: () => number;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type RequireAuthProps<
|
|
85
|
+
TRole extends string = string,
|
|
86
|
+
TPermission extends string = string,
|
|
87
|
+
> = {
|
|
88
|
+
children: React.ReactNode;
|
|
89
|
+
fallback?: React.ReactNode;
|
|
90
|
+
loadingFallback?: React.ReactNode;
|
|
91
|
+
roles?: TRole | TRole[];
|
|
92
|
+
permissions?: TPermission | TPermission[] | PermissionPolicy<TPermission>;
|
|
93
|
+
requireAll?: boolean;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type CanProps<
|
|
97
|
+
TRole extends string = string,
|
|
98
|
+
TPermission extends string = string,
|
|
99
|
+
> = {
|
|
100
|
+
children: React.ReactNode;
|
|
101
|
+
fallback?: React.ReactNode;
|
|
102
|
+
roles?: TRole | TRole[];
|
|
103
|
+
permissions?: TPermission | TPermission[] | PermissionPolicy<TPermission>;
|
|
104
|
+
requireAll?: boolean;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export type WithPermissionOptions<
|
|
108
|
+
TRole extends string = string,
|
|
109
|
+
TPermission extends string = string,
|
|
110
|
+
> = {
|
|
111
|
+
roles?: TRole | TRole[];
|
|
112
|
+
permissions?: TPermission | TPermission[] | PermissionPolicy<TPermission>;
|
|
113
|
+
requireAll?: boolean;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export type GraphQLAuthClient<TSession = unknown, TCredentials = unknown> = {
|
|
117
|
+
login: (credentials: TCredentials) => Promise<TSession>;
|
|
118
|
+
logout?: () => Promise<void>;
|
|
119
|
+
refresh?: (refreshToken: string) => Promise<TSession>;
|
|
120
|
+
getCurrentUser?: () => Promise<TSession>;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export type RESTAuthClient<TSession = unknown, TCredentials = unknown> = {
|
|
124
|
+
login: (credentials: TCredentials) => Promise<TSession>;
|
|
125
|
+
logout?: () => Promise<void>;
|
|
126
|
+
refresh?: (refreshToken: string) => Promise<TSession>;
|
|
127
|
+
getCurrentUser?: () => Promise<TSession>;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export type ClientAdapter<TSession = unknown, TCredentials = unknown> =
|
|
131
|
+
| GraphQLAuthClient<TSession, TCredentials>
|
|
132
|
+
| RESTAuthClient<TSession, TCredentials>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type AuthStatus =
|
|
2
|
+
| 'idle'
|
|
3
|
+
| 'loading'
|
|
4
|
+
| 'authenticated'
|
|
5
|
+
| 'unauthenticated'
|
|
6
|
+
| 'error';
|
|
7
|
+
|
|
8
|
+
export type TokenType = 'bearer' | 'jwt' | 'custom';
|
|
9
|
+
|
|
10
|
+
export type RefreshStrategy = 'auto' | 'manual' | 'sliding';
|
|
11
|
+
|
|
12
|
+
export type AuthSession<
|
|
13
|
+
TUser = unknown,
|
|
14
|
+
TRole = string,
|
|
15
|
+
TPermission = string,
|
|
16
|
+
> = {
|
|
17
|
+
user?: TUser | null;
|
|
18
|
+
accessToken?: string | null;
|
|
19
|
+
refreshToken?: string | null;
|
|
20
|
+
tokenType?: TokenType;
|
|
21
|
+
roles?: TRole[] | null;
|
|
22
|
+
permissions?: TPermission[] | null;
|
|
23
|
+
expiresAt?: number | null;
|
|
24
|
+
refreshExpiresAt?: number | null;
|
|
25
|
+
issuedAt?: number | null;
|
|
26
|
+
meta?: Record<string, unknown> | null;
|
|
27
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './core';
|
|
2
|
+
export * from './permissions';
|
|
3
|
+
export * from './state';
|
|
4
|
+
export * from './storage';
|
|
5
|
+
export * from './middleware';
|
|
6
|
+
export * from './token-manager';
|
|
7
|
+
export * from './adapter-config';
|
|
8
|
+
export * from './adapter';
|
|
9
|
+
export * from './utils';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AuthAdapterState } from './state';
|
|
2
|
+
|
|
3
|
+
export type AuthMiddleware<
|
|
4
|
+
TSession = unknown,
|
|
5
|
+
TUser = unknown,
|
|
6
|
+
TRole extends string = string,
|
|
7
|
+
TPermission extends string = string,
|
|
8
|
+
> = {
|
|
9
|
+
onBeforeLogin?: (credentials: unknown) => Promise<void> | void;
|
|
10
|
+
onAfterLogin?: (
|
|
11
|
+
state: AuthAdapterState<TSession, TUser, TRole, TPermission>,
|
|
12
|
+
) => Promise<void> | void;
|
|
13
|
+
onBeforeLogout?: () => Promise<void> | void;
|
|
14
|
+
onAfterLogout?: () => Promise<void> | void;
|
|
15
|
+
onRefresh?: (
|
|
16
|
+
state: AuthAdapterState<TSession, TUser, TRole, TPermission>,
|
|
17
|
+
) => Promise<void> | void;
|
|
18
|
+
onError?: (error: unknown) => Promise<void> | void;
|
|
19
|
+
onSessionExpired?: () => Promise<void> | void;
|
|
20
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type PermissionOperator = 'AND' | 'OR';
|
|
2
|
+
|
|
3
|
+
export type PermissionPolicy<TPermission extends string = string> = {
|
|
4
|
+
operator?: PermissionOperator;
|
|
5
|
+
permissions: TPermission[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type PermissionRule<
|
|
9
|
+
TRole extends string = string,
|
|
10
|
+
TPermission extends string = string,
|
|
11
|
+
> = {
|
|
12
|
+
roles?: TRole | TRole[];
|
|
13
|
+
permissions?: TPermission | TPermission[] | PermissionPolicy<TPermission>;
|
|
14
|
+
requireAll?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type PermissionHierarchy<TPermission extends string = string> = {
|
|
18
|
+
[key in TPermission]?: TPermission[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type RoleHierarchy<TRole extends string = string> = {
|
|
22
|
+
[key in TRole]?: TRole[];
|
|
23
|
+
};
|