@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.
Files changed (157) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1023 -25
  4. package/dist/kit/builder/auth/components/Can.d.ts +13 -0
  5. package/dist/kit/builder/auth/components/Can.d.ts.map +1 -0
  6. package/dist/kit/builder/auth/components/RequireAuth.d.ts +45 -0
  7. package/dist/kit/builder/auth/components/RequireAuth.d.ts.map +1 -0
  8. package/dist/kit/builder/auth/components/ShowWhenAuthenticated.d.ts +8 -0
  9. package/dist/kit/builder/auth/components/ShowWhenAuthenticated.d.ts.map +1 -0
  10. package/dist/kit/builder/auth/components/ShowWhenError.d.ts +8 -0
  11. package/dist/kit/builder/auth/components/ShowWhenError.d.ts.map +1 -0
  12. package/dist/kit/builder/auth/components/ShowWhenLoading.d.ts +8 -0
  13. package/dist/kit/builder/auth/components/ShowWhenLoading.d.ts.map +1 -0
  14. package/dist/kit/builder/auth/components/ShowWhenUnauthenticated.d.ts +8 -0
  15. package/dist/kit/builder/auth/components/ShowWhenUnauthenticated.d.ts.map +1 -0
  16. package/dist/kit/builder/auth/components/withPermission.d.ts +7 -0
  17. package/dist/kit/builder/auth/components/withPermission.d.ts.map +1 -0
  18. package/dist/kit/builder/auth/hooks/action-hooks.d.ts +18 -0
  19. package/dist/kit/builder/auth/hooks/action-hooks.d.ts.map +1 -0
  20. package/dist/kit/builder/auth/hooks/core-hooks.d.ts +56 -0
  21. package/dist/kit/builder/auth/hooks/core-hooks.d.ts.map +1 -0
  22. package/dist/kit/builder/auth/hooks/index.d.ts +5 -0
  23. package/dist/kit/builder/auth/hooks/index.d.ts.map +1 -0
  24. package/dist/kit/builder/auth/hooks/permission-hooks.d.ts +18 -0
  25. package/dist/kit/builder/auth/hooks/permission-hooks.d.ts.map +1 -0
  26. package/dist/kit/builder/auth/hooks/token-hooks.d.ts +13 -0
  27. package/dist/kit/builder/auth/hooks/token-hooks.d.ts.map +1 -0
  28. package/dist/kit/builder/auth/index.d.ts +14 -8
  29. package/dist/kit/builder/auth/index.d.ts.map +1 -1
  30. package/dist/kit/builder/auth/{AuthProvider.d.ts → providers/AuthProvider.d.ts} +1 -1
  31. package/dist/kit/builder/auth/providers/AuthProvider.d.ts.map +1 -0
  32. package/dist/kit/builder/auth/types/adapter-config.d.ts +31 -0
  33. package/dist/kit/builder/auth/types/adapter-config.d.ts.map +1 -0
  34. package/dist/kit/builder/auth/types/adapter.d.ts +80 -0
  35. package/dist/kit/builder/auth/types/adapter.d.ts.map +1 -0
  36. package/dist/kit/builder/auth/types/core.d.ts +16 -0
  37. package/dist/kit/builder/auth/types/core.d.ts.map +1 -0
  38. package/dist/kit/builder/auth/types/index.d.ts +10 -0
  39. package/dist/kit/builder/auth/types/index.d.ts.map +1 -0
  40. package/dist/kit/builder/auth/types/middleware.d.ts +11 -0
  41. package/dist/kit/builder/auth/types/middleware.d.ts.map +1 -0
  42. package/dist/kit/builder/auth/types/permissions.d.ts +17 -0
  43. package/dist/kit/builder/auth/types/permissions.d.ts.map +1 -0
  44. package/dist/kit/builder/auth/types/state.d.ts +13 -0
  45. package/dist/kit/builder/auth/types/state.d.ts.map +1 -0
  46. package/dist/kit/builder/auth/types/storage.d.ts +20 -0
  47. package/dist/kit/builder/auth/types/storage.d.ts.map +1 -0
  48. package/dist/kit/builder/auth/types/token-manager.d.ts +7 -0
  49. package/dist/kit/builder/auth/types/token-manager.d.ts.map +1 -0
  50. package/dist/kit/builder/auth/types/utils.d.ts +7 -0
  51. package/dist/kit/builder/auth/types/utils.d.ts.map +1 -0
  52. package/dist/kit/builder/auth/{adapter.d.ts → utils/auth-adapter.d.ts} +2 -2
  53. package/dist/kit/builder/auth/utils/auth-adapter.d.ts.map +1 -0
  54. package/dist/kit/builder/auth/utils/client-adapters/apollo-link.d.ts +4 -0
  55. package/dist/kit/builder/auth/utils/client-adapters/apollo-link.d.ts.map +1 -0
  56. package/dist/kit/builder/auth/utils/client-adapters/axios.d.ts +6 -0
  57. package/dist/kit/builder/auth/utils/client-adapters/axios.d.ts.map +1 -0
  58. package/dist/kit/builder/auth/utils/client-adapters/fetch.d.ts +6 -0
  59. package/dist/kit/builder/auth/utils/client-adapters/fetch.d.ts.map +1 -0
  60. package/dist/kit/builder/auth/utils/client-adapters/graphql.d.ts +9 -0
  61. package/dist/kit/builder/auth/utils/client-adapters/graphql.d.ts.map +1 -0
  62. package/dist/kit/builder/auth/utils/client-adapters/index.d.ts +7 -0
  63. package/dist/kit/builder/auth/utils/client-adapters/index.d.ts.map +1 -0
  64. package/dist/kit/builder/auth/utils/client-adapters/rest.d.ts +9 -0
  65. package/dist/kit/builder/auth/utils/client-adapters/rest.d.ts.map +1 -0
  66. package/dist/kit/builder/auth/utils/client-adapters/urql-exchange.d.ts +14 -0
  67. package/dist/kit/builder/auth/utils/client-adapters/urql-exchange.d.ts.map +1 -0
  68. package/dist/kit/builder/auth/{permission-checker.d.ts → utils/permission-checker.d.ts} +1 -1
  69. package/dist/kit/builder/auth/utils/permission-checker.d.ts.map +1 -0
  70. package/dist/kit/builder/auth/utils/storage/browser.d.ts +11 -0
  71. package/dist/kit/builder/auth/utils/storage/browser.d.ts.map +1 -0
  72. package/dist/kit/builder/auth/utils/storage/cookie.d.ts +3 -0
  73. package/dist/kit/builder/auth/utils/storage/cookie.d.ts.map +1 -0
  74. package/dist/kit/builder/auth/utils/storage/encryption.d.ts +7 -0
  75. package/dist/kit/builder/auth/utils/storage/encryption.d.ts.map +1 -0
  76. package/dist/kit/builder/auth/utils/storage/env.d.ts +2 -0
  77. package/dist/kit/builder/auth/utils/storage/env.d.ts.map +1 -0
  78. package/dist/kit/builder/auth/utils/storage/factory.d.ts +6 -0
  79. package/dist/kit/builder/auth/utils/storage/factory.d.ts.map +1 -0
  80. package/dist/kit/builder/auth/utils/storage/index.d.ts +7 -0
  81. package/dist/kit/builder/auth/utils/storage/index.d.ts.map +1 -0
  82. package/dist/kit/builder/auth/utils/storage/memory.d.ts +3 -0
  83. package/dist/kit/builder/auth/utils/storage/memory.d.ts.map +1 -0
  84. package/dist/kit/builder/auth/{token-manager.d.ts → utils/token-manager.d.ts} +1 -1
  85. package/dist/kit/builder/auth/utils/token-manager.d.ts.map +1 -0
  86. package/dist/kit/components/login/Login.d.ts +2 -1
  87. package/dist/kit/components/login/Login.d.ts.map +1 -1
  88. package/dist/kit/layouts/admin/components/AdminLayout.d.ts +2 -1
  89. package/dist/kit/layouts/admin/components/AdminLayout.d.ts.map +1 -1
  90. package/dist/kit/themes/clean-slate.css +28 -4
  91. package/dist/kit/themes/default.css +28 -4
  92. package/dist/kit/themes/minimal-modern.css +28 -4
  93. package/dist/kit/themes/spotify.css +28 -4
  94. package/package.json +1 -1
  95. package/src/index.ts +1 -0
  96. package/src/kit/builder/auth/components/Can.tsx +27 -0
  97. package/src/kit/builder/auth/components/RequireAuth.tsx +78 -0
  98. package/src/kit/builder/auth/components/ShowWhenAuthenticated.tsx +10 -0
  99. package/src/kit/builder/auth/components/ShowWhenError.tsx +10 -0
  100. package/src/kit/builder/auth/components/ShowWhenLoading.tsx +10 -0
  101. package/src/kit/builder/auth/components/ShowWhenUnauthenticated.tsx +10 -0
  102. package/src/kit/builder/auth/components/withPermission.tsx +23 -0
  103. package/src/kit/builder/auth/hooks/action-hooks.ts +34 -0
  104. package/src/kit/builder/auth/hooks/core-hooks.ts +65 -0
  105. package/src/kit/builder/auth/hooks/index.ts +4 -0
  106. package/src/kit/builder/auth/hooks/permission-hooks.ts +43 -0
  107. package/src/kit/builder/auth/hooks/token-hooks.ts +25 -0
  108. package/src/kit/builder/auth/index.ts +16 -18
  109. package/src/kit/builder/auth/{AuthProvider.tsx → providers/AuthProvider.tsx} +1 -1
  110. package/src/kit/builder/auth/types/adapter-config.ts +44 -0
  111. package/src/kit/builder/auth/types/adapter.ts +132 -0
  112. package/src/kit/builder/auth/types/core.ts +27 -0
  113. package/src/kit/builder/auth/types/index.ts +9 -0
  114. package/src/kit/builder/auth/types/middleware.ts +20 -0
  115. package/src/kit/builder/auth/types/permissions.ts +23 -0
  116. package/src/kit/builder/auth/types/state.ts +16 -0
  117. package/src/kit/builder/auth/types/storage.ts +21 -0
  118. package/src/kit/builder/auth/types/token-manager.ts +9 -0
  119. package/src/kit/builder/auth/types/utils.ts +55 -0
  120. package/src/kit/builder/auth/{adapter.ts → utils/auth-adapter.ts} +3 -2
  121. package/src/kit/builder/auth/utils/client-adapters/apollo-link.ts +30 -0
  122. package/src/kit/builder/auth/utils/client-adapters/axios.ts +61 -0
  123. package/src/kit/builder/auth/utils/client-adapters/fetch.ts +48 -0
  124. package/src/kit/builder/auth/utils/client-adapters/graphql.ts +60 -0
  125. package/src/kit/builder/auth/utils/client-adapters/index.ts +6 -0
  126. package/src/kit/builder/auth/utils/client-adapters/rest.ts +60 -0
  127. package/src/kit/builder/auth/utils/client-adapters/urql-exchange.ts +76 -0
  128. package/src/kit/builder/auth/{permission-checker.ts → utils/permission-checker.ts} +1 -1
  129. package/src/kit/builder/auth/utils/storage/browser.ts +99 -0
  130. package/src/kit/builder/auth/utils/storage/cookie.ts +116 -0
  131. package/src/kit/builder/auth/utils/storage/encryption.ts +80 -0
  132. package/src/kit/builder/auth/utils/storage/env.ts +2 -0
  133. package/src/kit/builder/auth/utils/storage/factory.ts +37 -0
  134. package/src/kit/builder/auth/utils/storage/index.ts +6 -0
  135. package/src/kit/builder/auth/utils/storage/memory.ts +15 -0
  136. package/src/kit/builder/auth/{token-manager.ts → utils/token-manager.ts} +1 -1
  137. package/src/kit/components/login/Login.tsx +36 -21
  138. package/src/kit/layouts/admin/components/AdminLayout.tsx +24 -17
  139. package/dist/kit/builder/auth/AuthProvider.d.ts.map +0 -1
  140. package/dist/kit/builder/auth/adapter.d.ts.map +0 -1
  141. package/dist/kit/builder/auth/client-adapters.d.ts +0 -149
  142. package/dist/kit/builder/auth/client-adapters.d.ts.map +0 -1
  143. package/dist/kit/builder/auth/components.d.ts +0 -119
  144. package/dist/kit/builder/auth/components.d.ts.map +0 -1
  145. package/dist/kit/builder/auth/hooks.d.ts +0 -158
  146. package/dist/kit/builder/auth/hooks.d.ts.map +0 -1
  147. package/dist/kit/builder/auth/permission-checker.d.ts.map +0 -1
  148. package/dist/kit/builder/auth/storage.d.ts +0 -17
  149. package/dist/kit/builder/auth/storage.d.ts.map +0 -1
  150. package/dist/kit/builder/auth/token-manager.d.ts.map +0 -1
  151. package/dist/kit/builder/auth/types.d.ts +0 -183
  152. package/dist/kit/builder/auth/types.d.ts.map +0 -1
  153. package/src/kit/builder/auth/client-adapters.ts +0 -398
  154. package/src/kit/builder/auth/components.tsx +0 -221
  155. package/src/kit/builder/auth/hooks.ts +0 -237
  156. package/src/kit/builder/auth/storage.ts +0 -366
  157. package/src/kit/builder/auth/types.ts +0 -393
@@ -1,398 +0,0 @@
1
- import type {
2
- AuthAdapterConfig,
3
- AuthSession,
4
- GraphQLAuthClient,
5
- RESTAuthClient,
6
- } from './types';
7
-
8
- // ============================================================================
9
- // GraphQL Client Adapter
10
- // ============================================================================
11
-
12
- export type GraphQLClientAdapterOptions<
13
- TUser = unknown,
14
- TRole extends string = string,
15
- TPermission extends string = string,
16
- TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
17
- TUser,
18
- TRole,
19
- TPermission
20
- >,
21
- TCredentials = unknown,
22
- > = {
23
- client: GraphQLAuthClient<TSession, TCredentials>;
24
- resolveUser?: (session: TSession | null) => TUser | null;
25
- resolveRoles?: (session: TSession | null) => TRole[];
26
- resolvePermissions?: (session: TSession | null) => TPermission[];
27
- };
28
-
29
- /**
30
- * Creates an auth adapter config for GraphQL clients
31
- * Works with Apollo Client, urql, graphql-request, etc.
32
- *
33
- * @example
34
- * ```tsx
35
- * import { ApolloClient } from '@apollo/client';
36
- * import { createGraphQLAuthAdapter } from '@k3mart/react-kit/auth2';
37
- *
38
- * const apolloClient = new ApolloClient({ ... });
39
- *
40
- * const authConfig = createGraphQLAuthAdapter({
41
- * client: {
42
- * login: async (credentials) => {
43
- * const result = await apolloClient.mutate({
44
- * mutation: LOGIN_MUTATION,
45
- * variables: credentials,
46
- * });
47
- * return result.data.login;
48
- * },
49
- * logout: async () => {
50
- * await apolloClient.mutate({ mutation: LOGOUT_MUTATION });
51
- * },
52
- * refresh: async (refreshToken) => {
53
- * const result = await apolloClient.mutate({
54
- * mutation: REFRESH_MUTATION,
55
- * variables: { refreshToken },
56
- * });
57
- * return result.data.refresh;
58
- * },
59
- * getCurrentUser: async () => {
60
- * const result = await apolloClient.query({
61
- * query: GET_CURRENT_USER_QUERY,
62
- * });
63
- * return result.data.currentUser;
64
- * },
65
- * },
66
- * });
67
- * ```
68
- */
69
- export function createGraphQLAuthAdapter<
70
- TUser = unknown,
71
- TRole extends string = string,
72
- TPermission extends string = string,
73
- TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
74
- TUser,
75
- TRole,
76
- TPermission
77
- >,
78
- TCredentials = unknown,
79
- >(
80
- options: GraphQLClientAdapterOptions<
81
- TUser,
82
- TRole,
83
- TPermission,
84
- TSession,
85
- TCredentials
86
- >,
87
- ): Partial<
88
- AuthAdapterConfig<TUser, TRole, TPermission, TSession, TCredentials>
89
- > {
90
- return {
91
- login: options.client.login,
92
- logout: options.client.logout,
93
- refresh: options.client.refresh
94
- ? async (session: TSession) => {
95
- if (!session.refreshToken) {
96
- throw new Error('No refresh token available');
97
- }
98
- if (!options.client.refresh) {
99
- throw new Error('Refresh function not provided');
100
- }
101
- return await options.client.refresh(session.refreshToken);
102
- }
103
- : undefined,
104
- loadSession: options.client.getCurrentUser,
105
- resolveUser: options.resolveUser,
106
- resolveRoles: options.resolveRoles,
107
- resolvePermissions: options.resolvePermissions,
108
- };
109
- }
110
-
111
- // ============================================================================
112
- // REST Client Adapter
113
- // ============================================================================
114
-
115
- export type RESTClientAdapterOptions<
116
- TUser = unknown,
117
- TRole extends string = string,
118
- TPermission extends string = string,
119
- TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
120
- TUser,
121
- TRole,
122
- TPermission
123
- >,
124
- TCredentials = unknown,
125
- > = {
126
- client: RESTAuthClient<TSession, TCredentials>;
127
- resolveUser?: (session: TSession | null) => TUser | null;
128
- resolveRoles?: (session: TSession | null) => TRole[];
129
- resolvePermissions?: (session: TSession | null) => TPermission[];
130
- };
131
-
132
- /**
133
- * Creates an auth adapter config for REST API clients
134
- * Works with fetch, axios, ky, etc.
135
- *
136
- * @example
137
- * ```tsx
138
- * import axios from 'axios';
139
- * import { createRESTAuthAdapter } from '@k3mart/react-kit/auth2';
140
- *
141
- * const api = axios.create({ baseURL: 'https://api.example.com' });
142
- *
143
- * const authConfig = createRESTAuthAdapter({
144
- * client: {
145
- * login: async (credentials) => {
146
- * const response = await api.post('/auth/login', credentials);
147
- * return response.data;
148
- * },
149
- * logout: async () => {
150
- * await api.post('/auth/logout');
151
- * },
152
- * refresh: async (refreshToken) => {
153
- * const response = await api.post('/auth/refresh', { refreshToken });
154
- * return response.data;
155
- * },
156
- * getCurrentUser: async () => {
157
- * const response = await api.get('/auth/me');
158
- * return response.data;
159
- * },
160
- * },
161
- * });
162
- * ```
163
- */
164
- export function createRESTAuthAdapter<
165
- TUser = unknown,
166
- TRole extends string = string,
167
- TPermission extends string = string,
168
- TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
169
- TUser,
170
- TRole,
171
- TPermission
172
- >,
173
- TCredentials = unknown,
174
- >(
175
- options: RESTClientAdapterOptions<
176
- TUser,
177
- TRole,
178
- TPermission,
179
- TSession,
180
- TCredentials
181
- >,
182
- ): Partial<
183
- AuthAdapterConfig<TUser, TRole, TPermission, TSession, TCredentials>
184
- > {
185
- return {
186
- login: options.client.login,
187
- logout: options.client.logout,
188
- refresh: options.client.refresh
189
- ? async (session: TSession) => {
190
- if (!session.refreshToken) {
191
- throw new Error('No refresh token available');
192
- }
193
- if (!options.client.refresh) {
194
- throw new Error('Refresh function not provided');
195
- }
196
- return await options.client.refresh(session.refreshToken);
197
- }
198
- : undefined,
199
- loadSession: options.client.getCurrentUser,
200
- resolveUser: options.resolveUser,
201
- resolveRoles: options.resolveRoles,
202
- resolvePermissions: options.resolvePermissions,
203
- };
204
- }
205
-
206
- // ============================================================================
207
- // HTTP Interceptor Utilities
208
- // ============================================================================
209
-
210
- /**
211
- * Helper to create an axios interceptor that automatically adds auth token
212
- *
213
- * @example
214
- * ```tsx
215
- * import axios from 'axios';
216
- * import { createAxiosAuthInterceptor } from '@k3mart/react-kit/auth2';
217
- *
218
- * const api = axios.create({ baseURL: 'https://api.example.com' });
219
- *
220
- * createAxiosAuthInterceptor(api, authAdapter);
221
- * ```
222
- */
223
- export function createAxiosAuthInterceptor(
224
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
- axiosInstance: any,
226
- getToken: () => string | null,
227
- options?: {
228
- tokenType?: string;
229
- onTokenExpired?: () => void;
230
- refreshToken?: () => Promise<void>;
231
- },
232
- ) {
233
- const tokenType = options?.tokenType ?? 'Bearer';
234
-
235
- // Request interceptor
236
- axiosInstance.interceptors.request.use(
237
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
238
- async (config: any) => {
239
- const token = getToken();
240
- if (token) {
241
- config.headers.Authorization = `${tokenType} ${token}`;
242
- }
243
- return config;
244
- },
245
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
246
- (error: any) => Promise.reject(error),
247
- );
248
-
249
- // Response interceptor for token refresh
250
- if (options?.refreshToken) {
251
- axiosInstance.interceptors.response.use(
252
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
253
- (response: any) => response,
254
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
255
- async (error: any) => {
256
- const originalRequest = error.config;
257
-
258
- // If token expired and we haven't retried yet
259
- if (
260
- error.response?.status === 401 &&
261
- !originalRequest._retry &&
262
- options.refreshToken
263
- ) {
264
- originalRequest._retry = true;
265
-
266
- try {
267
- await options.refreshToken();
268
- const token = getToken();
269
- if (token) {
270
- originalRequest.headers.Authorization = `${tokenType} ${token}`;
271
- }
272
- return axiosInstance(originalRequest);
273
- } catch (refreshError) {
274
- options.onTokenExpired?.();
275
- return Promise.reject(refreshError);
276
- }
277
- }
278
-
279
- return Promise.reject(error);
280
- },
281
- );
282
- }
283
- }
284
-
285
- /**
286
- * Helper to create a fetch wrapper with auth token injection
287
- *
288
- * @example
289
- * ```tsx
290
- * import { createAuthFetch } from '@k3mart/react-kit/auth2';
291
- *
292
- * const authenticatedFetch = createAuthFetch(
293
- * () => authAdapter.getToken(),
294
- * {
295
- * onTokenExpired: () => authAdapter.logout(),
296
- * refreshToken: () => authAdapter.refresh(),
297
- * }
298
- * );
299
- *
300
- * // Use it like regular fetch
301
- * const response = await authenticatedFetch('/api/users');
302
- * ```
303
- */
304
- export function createAuthFetch(
305
- getToken: () => string | null,
306
- options?: {
307
- tokenType?: string;
308
- onTokenExpired?: () => void;
309
- refreshToken?: () => Promise<void>;
310
- },
311
- ): typeof fetch {
312
- const tokenType = options?.tokenType ?? 'Bearer';
313
-
314
- return async (
315
- input: RequestInfo | URL,
316
- init?: RequestInit,
317
- ): Promise<Response> => {
318
- const token = getToken();
319
- const headers = new Headers(init?.headers);
320
-
321
- if (token) {
322
- headers.set('Authorization', `${tokenType} ${token}`);
323
- }
324
-
325
- const response = await fetch(input, {
326
- ...init,
327
- headers,
328
- });
329
-
330
- // Handle token expiration
331
- if (response.status === 401 && options?.refreshToken) {
332
- try {
333
- await options.refreshToken();
334
- const newToken = getToken();
335
-
336
- if (newToken) {
337
- headers.set('Authorization', `${tokenType} ${newToken}`);
338
- return await fetch(input, {
339
- ...init,
340
- headers,
341
- });
342
- }
343
- } catch (error) {
344
- options.onTokenExpired?.();
345
- throw error;
346
- }
347
- }
348
-
349
- return response;
350
- };
351
- }
352
-
353
- /**
354
- * Helper to create Apollo Link with auth token injection
355
- *
356
- * @example
357
- * ```tsx
358
- * import { ApolloClient, InMemoryCache, from } from '@apollo/client';
359
- * import { createApolloAuthLink } from '@k3mart/react-kit/auth2';
360
- *
361
- * const authLink = createApolloAuthLink(() => authAdapter.getToken());
362
- *
363
- * const client = new ApolloClient({
364
- * link: from([authLink, httpLink]),
365
- * cache: new InMemoryCache(),
366
- * });
367
- * ```
368
- */
369
- export function createApolloAuthLink(
370
- getToken: () => string | null,
371
- options?: {
372
- tokenType?: string;
373
- },
374
- ) {
375
- const tokenType = options?.tokenType ?? 'Bearer';
376
-
377
- // This requires @apollo/client to be installed
378
- // We'll return a function that creates the link to avoid direct dependency
379
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
380
- return (ApolloLink: any) => {
381
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
382
- return new ApolloLink((operation: any, forward: any) => {
383
- const token = getToken();
384
-
385
- if (token) {
386
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
387
- operation.setContext(({ headers = {} }: any) => ({
388
- headers: {
389
- ...headers,
390
- authorization: `${tokenType} ${token}`,
391
- },
392
- }));
393
- }
394
-
395
- return forward(operation);
396
- });
397
- };
398
- }
@@ -1,221 +0,0 @@
1
- import type { ComponentType } from 'react';
2
- import type {
3
- CanProps,
4
- RequireAuthProps,
5
- WithPermissionOptions,
6
- } from './types';
7
- import { useAuthContext } from './AuthProvider';
8
- import { useCan } from './hooks';
9
-
10
- // ============================================================================
11
- // RequireAuth Component
12
- // ============================================================================
13
-
14
- /**
15
- * Component that requires authentication
16
- * Optionally checks for specific roles and permissions
17
- *
18
- * @example
19
- * ```tsx
20
- * // Basic authentication check
21
- * <RequireAuth fallback={<Login />}>
22
- * <Dashboard />
23
- * </RequireAuth>
24
- *
25
- * // With role check
26
- * <RequireAuth
27
- * roles="admin"
28
- * fallback={<Forbidden />}
29
- * loadingFallback={<Spinner />}
30
- * >
31
- * <AdminPanel />
32
- * </RequireAuth>
33
- *
34
- * // With permission check
35
- * <RequireAuth
36
- * permissions={['post:edit', 'post:delete']}
37
- * fallback={<Forbidden />}
38
- * >
39
- * <PostEditor />
40
- * </RequireAuth>
41
- *
42
- * // Complex rule
43
- * <RequireAuth
44
- * roles={['admin', 'moderator']}
45
- * permissions={{
46
- * operator: 'OR',
47
- * permissions: ['post:edit', 'post:delete']
48
- * }}
49
- * requireAll={false}
50
- * fallback={<Forbidden />}
51
- * >
52
- * <ContentManager />
53
- * </RequireAuth>
54
- * ```
55
- */
56
- export function RequireAuth<
57
- TRole extends string = string,
58
- TPermission extends string = string,
59
- >({
60
- children,
61
- fallback = null,
62
- loadingFallback = null,
63
- roles,
64
- permissions,
65
- requireAll = true,
66
- }: RequireAuthProps<TRole, TPermission>) {
67
- const { status, can } = useAuthContext();
68
-
69
- if (status === 'loading' || status === 'idle') {
70
- return loadingFallback;
71
- }
72
-
73
- if (status !== 'authenticated') {
74
- return fallback;
75
- }
76
-
77
- // If no specific roles/permissions required, just check authentication
78
- if (!roles && !permissions) {
79
- return children;
80
- }
81
-
82
- // Check role/permission rules
83
- const allowed = can({ roles, permissions, requireAll });
84
-
85
- if (!allowed) {
86
- return fallback;
87
- }
88
-
89
- return children;
90
- }
91
-
92
- // ============================================================================
93
- // Can Component
94
- // ============================================================================
95
-
96
- /**
97
- * Component for conditional rendering based on permissions
98
- * More flexible than RequireAuth - doesn't check authentication status
99
- *
100
- * @example
101
- * ```tsx
102
- * // Show button only if user can edit
103
- * <Can permissions="post:edit" fallback={<ReadOnlyView />}>
104
- * <EditButton />
105
- * </Can>
106
- *
107
- * // Show admin panel if user is admin
108
- * <Can roles="admin">
109
- * <AdminPanel />
110
- * </Can>
111
- *
112
- * // Complex permission check
113
- * <Can
114
- * roles={['admin', 'moderator']}
115
- * permissions={{
116
- * operator: 'OR',
117
- * permissions: ['post:edit', 'post:delete']
118
- * }}
119
- * requireAll={false}
120
- * >
121
- * <ManageButton />
122
- * </Can>
123
- * ```
124
- */
125
- export function Can<
126
- TRole extends string = string,
127
- TPermission extends string = string,
128
- >({
129
- children,
130
- fallback = null,
131
- roles,
132
- permissions,
133
- requireAll = true,
134
- }: CanProps<TRole, TPermission>) {
135
- const allowed = useCan({ roles, permissions, requireAll });
136
- if (!allowed) return fallback;
137
- return children;
138
- }
139
-
140
- // ============================================================================
141
- // Higher-Order Component
142
- // ============================================================================
143
-
144
- /**
145
- * Higher-order component that wraps a component with permission checks
146
- *
147
- * @example
148
- * ```tsx
149
- * const AdminButton = withPermission(Button, {
150
- * roles: 'admin'
151
- * });
152
- *
153
- * const EditButton = withPermission(Button, {
154
- * permissions: 'post:edit'
155
- * });
156
- *
157
- * // Use like regular component
158
- * <AdminButton onClick={handleAdmin}>Admin Action</AdminButton>
159
- * <EditButton onClick={handleEdit}>Edit Post</EditButton>
160
- * ```
161
- */
162
- export function withPermission<
163
- TRole extends string = string,
164
- TPermission extends string = string,
165
- TProps extends Record<string, unknown> = Record<string, unknown>,
166
- >(
167
- Component: ComponentType<TProps>,
168
- options: WithPermissionOptions<TRole, TPermission>,
169
- ): ComponentType<TProps> {
170
- const WithPermissionWrapper = (props: TProps) => {
171
- const allowed = useCan(options);
172
- if (!allowed) return null;
173
- return <Component {...props} />;
174
- };
175
- WithPermissionWrapper.displayName = `WithPermission(${Component.displayName ?? Component.name ?? 'Component'})`;
176
- return WithPermissionWrapper as ComponentType<TProps>;
177
- }
178
-
179
- // ============================================================================
180
- // Show/Hide Components
181
- // ============================================================================
182
-
183
- /**
184
- * Component that shows children only when authenticated
185
- */
186
- export function ShowWhenAuthenticated({
187
- children,
188
- }: {
189
- children: React.ReactNode;
190
- }) {
191
- const { status } = useAuthContext();
192
- return status === 'authenticated' ? children : null;
193
- }
194
-
195
- /**
196
- * Component that shows children only when NOT authenticated
197
- */
198
- export function ShowWhenUnauthenticated({
199
- children,
200
- }: {
201
- children: React.ReactNode;
202
- }) {
203
- const { status } = useAuthContext();
204
- return status === 'unauthenticated' ? children : null;
205
- }
206
-
207
- /**
208
- * Component that shows children only while loading
209
- */
210
- export function ShowWhenLoading({ children }: { children: React.ReactNode }) {
211
- const { status } = useAuthContext();
212
- return status === 'loading' ? children : null;
213
- }
214
-
215
- /**
216
- * Component that shows children only when there's an error
217
- */
218
- export function ShowWhenError({ children }: { children: React.ReactNode }) {
219
- const { status } = useAuthContext();
220
- return status === 'error' ? children : null;
221
- }