Superadmin impersonation, hardened auth/upload paths, dependency updates
- Add superadmin impersonation: sessions.impersonated_by (migration 0003) is stamped onto audit rows so impersonated actions are attributable, with a persistent ImpersonationBanner in the app shell. - Harden auth and upload handling across routes (safe redirect targets, filename sanitization, checkout grant handling). - Update dependencies: Sentry 8 -> 10, @fastify/static 8 -> 10, react-router-dom 6.30.6; add find-my-way / fast-uri overrides. - Add tests for safe-next, checkout-grant, and upload-filename. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4a1122a7c9
commit
eb36b81dc9
@@ -10,6 +10,8 @@ export interface AuthUser {
|
||||
isSuperadmin?: boolean;
|
||||
isSuspended?: boolean;
|
||||
emailVerified?: boolean;
|
||||
/** Superadmin id when this session was opened by admin impersonation, else null. */
|
||||
impersonatedBy?: string | null;
|
||||
}
|
||||
|
||||
interface MeResponse {
|
||||
@@ -69,3 +71,20 @@ export function useLogout() {
|
||||
onSuccess: () => qc.setQueryData(ME_KEY, null),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave an impersonated session. The server destroys the borrowed session outright, so there is
|
||||
* no session left to return to — the admin lands on the login page and signs in as themselves.
|
||||
*/
|
||||
export function useEndImpersonation() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation<void, ApiError>({
|
||||
mutationFn: async () => {
|
||||
await api.post('/api/auth/end-impersonation');
|
||||
},
|
||||
onSuccess: () => {
|
||||
qc.setQueryData(ME_KEY, null);
|
||||
qc.clear();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user