Skip to content

Commit 6d88a13

Browse files
committed
fix: move session management and user delete to orpc
1 parent 3f781ed commit 6d88a13

File tree

3 files changed

+291
-165
lines changed

3 files changed

+291
-165
lines changed

app/features/user/manager/page-user.tsx

Lines changed: 107 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,28 @@ export const PageUser = (props: { params: { id: string } }) => {
6262
);
6363

6464
const deleteUser = async () => {
65-
const response = await authClient.admin.removeUser({
66-
userId: props.params.id,
67-
});
65+
try {
66+
await orpc.user.delete.call({ id: props.params.id });
67+
await Promise.all([
68+
// Invalidate users list
69+
queryClient.invalidateQueries({
70+
queryKey: orpc.user.getAll.key(),
71+
type: 'all',
72+
}),
73+
// Remove user from cache
74+
queryClient.removeQueries({
75+
queryKey: orpc.user.getById.key({ input: { id: props.params.id } }),
76+
}),
77+
]);
6878

69-
if (response.error) {
79+
// Redirect
80+
if (canGoBack) {
81+
router.history.back();
82+
} else {
83+
router.navigate({ to: '..', replace: true });
84+
}
85+
} catch {
7086
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 });
9187
}
9288
};
9389

@@ -218,7 +214,9 @@ export const PageUser = (props: { params: { id: string } }) => {
218214
</Card>
219215

220216
<div className="flex flex-2 flex-col">
221-
<UserSessions userId={props.params.id} />
217+
<WithPermission permission={{ session: ['list'] }}>
218+
<UserSessions userId={props.params.id} />
219+
</WithPermission>
222220
</div>
223221
</div>
224222
))
@@ -229,19 +227,8 @@ export const PageUser = (props: { params: { id: string } }) => {
229227
};
230228

231229
const UserSessions = (props: { userId: string }) => {
232-
const queryClient = useQueryClient();
233-
const currentSession = authClient.useSession();
234-
235230
const sessionsQuery = useInfiniteQuery(
236231
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,
245232
input: (cursor: string | undefined) => ({
246233
userId: props.userId,
247234
cursor,
@@ -253,42 +240,6 @@ const UserSessions = (props: { userId: string }) => {
253240
})
254241
);
255242

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-
292243
const ui = getUiState((set) => {
293244
if (sessionsQuery.status === 'pending') return set('pending');
294245
if (sessionsQuery.status === 'error') return set('error');
@@ -310,23 +261,9 @@ const UserSessions = (props: { userId: string }) => {
310261

311262
<WithPermission permission={{ session: ['revoke'] }}>
312263
<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>
264+
{ui.is('default') && (
265+
<RevokeAllSessionsButton userId={props.userId} />
266+
)}
330267
</DataListCell>
331268
</WithPermission>
332269
</DataListRow>
@@ -363,22 +300,10 @@ const UserSessions = (props: { userId: string }) => {
363300
</DataListCell>
364301
<WithPermission permission={{ session: ['revoke'] }}>
365302
<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>
303+
<RevokeSessionButton
304+
userId={props.userId}
305+
sessionToken={item.token}
306+
/>
382307
</DataListCell>
383308
</WithPermission>
384309
</DataListRow>
@@ -410,3 +335,80 @@ const UserSessions = (props: { userId: string }) => {
410335
</WithPermission>
411336
);
412337
};
338+
339+
const RevokeAllSessionsButton = (props: { userId: string }) => {
340+
const queryClient = useQueryClient();
341+
const currentSession = authClient.useSession();
342+
const revokeAllSessions = useMutation(
343+
orpc.user.revokeUserSessions.mutationOptions({
344+
onSuccess: async () => {
345+
await queryClient.invalidateQueries({
346+
queryKey: orpc.user.getUserSessions.key({
347+
input: { userId: props.userId },
348+
type: 'infinite',
349+
}),
350+
});
351+
},
352+
onError: () => {
353+
toast.error('Failed to revoke all sessions');
354+
},
355+
})
356+
);
357+
358+
return (
359+
<Button
360+
type="button"
361+
size="xs"
362+
variant="secondary"
363+
disabled={currentSession.data?.user.id === props.userId}
364+
loading={revokeAllSessions.isPending}
365+
onClick={() => {
366+
revokeAllSessions.mutate({
367+
id: props.userId,
368+
});
369+
}}
370+
>
371+
Revoke all
372+
</Button>
373+
);
374+
};
375+
376+
const RevokeSessionButton = (props: {
377+
userId: string;
378+
sessionToken: string;
379+
}) => {
380+
const queryClient = useQueryClient();
381+
const currentSession = authClient.useSession();
382+
const revokeSession = useMutation(
383+
orpc.user.revokeUserSession.mutationOptions({
384+
onSuccess: async () => {
385+
await queryClient.invalidateQueries({
386+
queryKey: orpc.user.getUserSessions.key({
387+
input: { userId: props.userId },
388+
type: 'infinite',
389+
}),
390+
});
391+
},
392+
onError: () => {
393+
toast.error('Failed to revoke sessions');
394+
},
395+
})
396+
);
397+
return (
398+
<Button
399+
type="button"
400+
size="xs"
401+
variant="secondary"
402+
disabled={currentSession.data?.session.token === props.sessionToken}
403+
loading={revokeSession.isPending}
404+
onClick={() => {
405+
revokeSession.mutate({
406+
id: props.userId,
407+
sessionToken: props.sessionToken,
408+
});
409+
}}
410+
>
411+
Revoke
412+
</Button>
413+
);
414+
};

app/server/orpc.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const base = os
1818
return await next({
1919
context: {
2020
user: session?.user,
21+
session: session?.session,
2122
db,
2223
},
2324
});
@@ -59,16 +60,17 @@ export const protectedProcedure = ({
5960
permission: Permission | null;
6061
}) =>
6162
base.use(async ({ context, next }) => {
62-
const { user } = context;
63+
const { user, session } = context;
6364

64-
if (!user) {
65+
if (!user || !session) {
6566
throw new ORPCError('UNAUTHORIZED');
6667
}
6768

6869
if (!permission) {
6970
return await next({
7071
context: {
7172
user,
73+
session,
7274
},
7375
});
7476
}
@@ -91,6 +93,7 @@ export const protectedProcedure = ({
9193
return await next({
9294
context: {
9395
user,
96+
session,
9497
},
9598
});
9699
});

0 commit comments

Comments
 (0)