@@ -12,7 +12,6 @@ import { toast } from 'sonner';
12
12
import { match } from 'ts-pattern' ;
13
13
14
14
import { authClient } from '@/lib/auth/client' ;
15
- import { Role } from '@/lib/auth/permissions' ;
16
15
import { orpc } from '@/lib/orpc/client' ;
17
16
import { getUiState } from '@/lib/ui-state' ;
18
17
@@ -62,32 +61,28 @@ export const PageUser = (props: { params: { id: string } }) => {
62
61
) ;
63
62
64
63
const deleteUser = async ( ) => {
65
- const response = await authClient . admin . removeUser ( {
66
- userId : props . params . id ,
67
- } ) ;
64
+ try {
65
+ await orpc . user . delete . call ( { id : props . params . id } ) ;
66
+ await Promise . all ( [
67
+ // Invalidate users list
68
+ queryClient . invalidateQueries ( {
69
+ queryKey : orpc . user . getAll . key ( ) ,
70
+ type : 'all' ,
71
+ } ) ,
72
+ // Remove user from cache
73
+ queryClient . removeQueries ( {
74
+ queryKey : orpc . user . getById . key ( { input : { id : props . params . id } } ) ,
75
+ } ) ,
76
+ ] ) ;
68
77
69
- if ( response . error ) {
78
+ // Redirect
79
+ if ( canGoBack ) {
80
+ router . history . back ( ) ;
81
+ } else {
82
+ router . navigate ( { to : '..' , replace : true } ) ;
83
+ }
84
+ } catch {
70
85
toast . error ( 'Failed to delete the user' ) ;
71
- return ;
72
- }
73
-
74
- await Promise . all ( [
75
- // Invalidate users list
76
- queryClient . invalidateQueries ( {
77
- queryKey : orpc . user . getAll . key ( ) ,
78
- type : 'all' ,
79
- } ) ,
80
- // Remove user from cache
81
- queryClient . removeQueries ( {
82
- queryKey : orpc . user . getById . key ( { input : { id : props . params . id } } ) ,
83
- } ) ,
84
- ] ) ;
85
-
86
- // Redirect
87
- if ( canGoBack ) {
88
- router . history . back ( ) ;
89
- } else {
90
- router . navigate ( { to : '..' , replace : true } ) ;
91
86
}
92
87
} ;
93
88
@@ -218,7 +213,9 @@ export const PageUser = (props: { params: { id: string } }) => {
218
213
</ Card >
219
214
220
215
< div className = "flex flex-2 flex-col" >
221
- < UserSessions userId = { props . params . id } />
216
+ < WithPermission permission = { { session : [ 'list' ] } } >
217
+ < UserSessions userId = { props . params . id } />
218
+ </ WithPermission >
222
219
</ div >
223
220
</ div >
224
221
) )
@@ -229,19 +226,8 @@ export const PageUser = (props: { params: { id: string } }) => {
229
226
} ;
230
227
231
228
const UserSessions = ( props : { userId : string } ) => {
232
- const queryClient = useQueryClient ( ) ;
233
- const currentSession = authClient . useSession ( ) ;
234
-
235
229
const sessionsQuery = useInfiniteQuery (
236
230
orpc . user . getUserSessions . infiniteOptions ( {
237
- enabled : currentSession . data ?. user . role
238
- ? authClient . admin . checkRolePermission ( {
239
- role : currentSession . data . user . role as Role ,
240
- permission : {
241
- session : [ 'list' ] ,
242
- } ,
243
- } )
244
- : false ,
245
231
input : ( cursor : string | undefined ) => ( {
246
232
userId : props . userId ,
247
233
cursor,
@@ -253,42 +239,6 @@ const UserSessions = (props: { userId: string }) => {
253
239
} )
254
240
) ;
255
241
256
- const revokeAllSessions = useMutation ( {
257
- mutationFn : async ( { userId } : { userId : string } ) => {
258
- const response = await authClient . admin . revokeUserSessions ( {
259
- userId,
260
- } ) ;
261
- if ( response . error ) {
262
- throw new Error ( response . error . message ) ;
263
- }
264
- await queryClient . invalidateQueries ( {
265
- queryKey : orpc . user . getUserSessions . key ( {
266
- input : { userId : props . userId } ,
267
- type : 'infinite' ,
268
- } ) ,
269
- } ) ;
270
- return response . data ;
271
- } ,
272
- } ) ;
273
-
274
- const revokeSession = useMutation ( {
275
- mutationFn : async ( { sessionToken } : { sessionToken : string } ) => {
276
- const response = await authClient . admin . revokeUserSession ( {
277
- sessionToken,
278
- } ) ;
279
- if ( response . error ) {
280
- throw new Error ( response . error . message ) ;
281
- }
282
- await queryClient . invalidateQueries ( {
283
- queryKey : orpc . user . getUserSessions . key ( {
284
- input : { userId : props . userId } ,
285
- type : 'infinite' ,
286
- } ) ,
287
- } ) ;
288
- return response . data ;
289
- } ,
290
- } ) ;
291
-
292
242
const ui = getUiState ( ( set ) => {
293
243
if ( sessionsQuery . status === 'pending' ) return set ( 'pending' ) ;
294
244
if ( sessionsQuery . status === 'error' ) return set ( 'error' ) ;
@@ -310,23 +260,9 @@ const UserSessions = (props: { userId: string }) => {
310
260
311
261
< WithPermission permission = { { session : [ 'revoke' ] } } >
312
262
< DataListCell className = "flex-none" >
313
- < Button
314
- type = "button"
315
- size = "sm"
316
- variant = "secondary"
317
- disabled = {
318
- currentSession . data ?. user . id === props . userId ||
319
- ui . is ( 'empty' )
320
- }
321
- loading = { revokeAllSessions . isPending }
322
- onClick = { ( ) => {
323
- revokeAllSessions . mutate ( {
324
- userId : props . userId ,
325
- } ) ;
326
- } }
327
- >
328
- Revoke all
329
- </ Button >
263
+ { ui . is ( 'default' ) && (
264
+ < RevokeAllSessionsButton userId = { props . userId } />
265
+ ) }
330
266
</ DataListCell >
331
267
</ WithPermission >
332
268
</ DataListRow >
@@ -363,22 +299,10 @@ const UserSessions = (props: { userId: string }) => {
363
299
</ DataListCell >
364
300
< WithPermission permission = { { session : [ 'revoke' ] } } >
365
301
< DataListCell className = "flex-none" >
366
- < Button
367
- type = "button"
368
- size = "xs"
369
- variant = "secondary"
370
- disabled = {
371
- currentSession . data ?. session . token === item . token
372
- }
373
- loading = { revokeSession . isPending }
374
- onClick = { ( ) => {
375
- revokeSession . mutate ( {
376
- sessionToken : item . token ,
377
- } ) ;
378
- } }
379
- >
380
- Revoke
381
- </ Button >
302
+ < RevokeSessionButton
303
+ userId = { props . userId }
304
+ sessionToken = { item . token }
305
+ />
382
306
</ DataListCell >
383
307
</ WithPermission >
384
308
</ DataListRow >
@@ -410,3 +334,80 @@ const UserSessions = (props: { userId: string }) => {
410
334
</ WithPermission >
411
335
) ;
412
336
} ;
337
+
338
+ const RevokeAllSessionsButton = ( props : { userId : string } ) => {
339
+ const queryClient = useQueryClient ( ) ;
340
+ const currentSession = authClient . useSession ( ) ;
341
+ const revokeAllSessions = useMutation (
342
+ orpc . user . revokeUserSessions . mutationOptions ( {
343
+ onSuccess : async ( ) => {
344
+ await queryClient . invalidateQueries ( {
345
+ queryKey : orpc . user . getUserSessions . key ( {
346
+ input : { userId : props . userId } ,
347
+ type : 'infinite' ,
348
+ } ) ,
349
+ } ) ;
350
+ } ,
351
+ onError : ( ) => {
352
+ toast . error ( 'Failed to revoke all sessions' ) ;
353
+ } ,
354
+ } )
355
+ ) ;
356
+
357
+ return (
358
+ < Button
359
+ type = "button"
360
+ size = "xs"
361
+ variant = "secondary"
362
+ disabled = { currentSession . data ?. user . id === props . userId }
363
+ loading = { revokeAllSessions . isPending }
364
+ onClick = { ( ) => {
365
+ revokeAllSessions . mutate ( {
366
+ id : props . userId ,
367
+ } ) ;
368
+ } }
369
+ >
370
+ Revoke all
371
+ </ Button >
372
+ ) ;
373
+ } ;
374
+
375
+ const RevokeSessionButton = ( props : {
376
+ userId : string ;
377
+ sessionToken : string ;
378
+ } ) => {
379
+ const queryClient = useQueryClient ( ) ;
380
+ const currentSession = authClient . useSession ( ) ;
381
+ const revokeSession = useMutation (
382
+ orpc . user . revokeUserSession . mutationOptions ( {
383
+ onSuccess : async ( ) => {
384
+ await queryClient . invalidateQueries ( {
385
+ queryKey : orpc . user . getUserSessions . key ( {
386
+ input : { userId : props . userId } ,
387
+ type : 'infinite' ,
388
+ } ) ,
389
+ } ) ;
390
+ } ,
391
+ onError : ( ) => {
392
+ toast . error ( 'Failed to revoke sessions' ) ;
393
+ } ,
394
+ } )
395
+ ) ;
396
+ return (
397
+ < Button
398
+ type = "button"
399
+ size = "xs"
400
+ variant = "secondary"
401
+ disabled = { currentSession . data ?. session . token === props . sessionToken }
402
+ loading = { revokeSession . isPending }
403
+ onClick = { ( ) => {
404
+ revokeSession . mutate ( {
405
+ id : props . userId ,
406
+ sessionToken : props . sessionToken ,
407
+ } ) ;
408
+ } }
409
+ >
410
+ Revoke
411
+ </ Button >
412
+ ) ;
413
+ } ;
0 commit comments