11import { redirect } from "@remix-run/server-runtime" ;
22import { prisma } from "~/db.server" ;
3+ import { logger } from "~/services/logger.server" ;
34import { SearchParams } from "~/routes/admin._index" ;
45import {
56 clearImpersonationId ,
67 commitImpersonationSession ,
8+ getImpersonationId ,
79 setImpersonationId ,
810} from "~/services/impersonation.server" ;
911import { requireUser } from "~/services/session.server" ;
12+ import { extractClientIp } from "~/utils/extractClientIp.server" ;
1013
1114const pageSize = 20 ;
1215
13- export async function adminGetUsers ( userId : string , { page, search } : SearchParams ) {
16+ export async function adminGetUsers (
17+ userId : string ,
18+ { page, search } : SearchParams ,
19+ ) {
1420 page = page || 1 ;
1521
1622 search = search ? decodeURIComponent ( search ) : undefined ;
@@ -212,6 +218,22 @@ export async function redirectWithImpersonation(request: Request, userId: string
212218 throw new Error ( "Unauthorized" ) ;
213219 }
214220
221+ const xff = request . headers . get ( "x-forwarded-for" ) ;
222+ const ipAddress = extractClientIp ( xff ) ;
223+
224+ try {
225+ await prisma . impersonationAuditLog . create ( {
226+ data : {
227+ action : "START" ,
228+ adminId : user . id ,
229+ targetId : userId ,
230+ ipAddress,
231+ } ,
232+ } ) ;
233+ } catch ( error ) {
234+ logger . error ( "Failed to create impersonation audit log" , { error, adminId : user . id , targetId : userId } ) ;
235+ }
236+
215237 const session = await setImpersonationId ( userId , request ) ;
216238
217239 return redirect ( path , {
@@ -220,6 +242,27 @@ export async function redirectWithImpersonation(request: Request, userId: string
220242}
221243
222244export async function clearImpersonation ( request : Request , path : string ) {
245+ const user = await requireUser ( request ) ;
246+ const targetId = await getImpersonationId ( request ) ;
247+
248+ if ( targetId ) {
249+ const xff = request . headers . get ( "x-forwarded-for" ) ;
250+ const ipAddress = extractClientIp ( xff ) ;
251+
252+ try {
253+ await prisma . impersonationAuditLog . create ( {
254+ data : {
255+ action : "STOP" ,
256+ adminId : user . id ,
257+ targetId,
258+ ipAddress,
259+ } ,
260+ } ) ;
261+ } catch ( error ) {
262+ logger . error ( "Failed to create impersonation audit log" , { error, adminId : user . id , targetId } ) ;
263+ }
264+ }
265+
223266 const session = await clearImpersonationId ( request ) ;
224267
225268 return redirect ( path , {
0 commit comments