Files
Momento/memento-note/lib/audit-log.ts
Antigravity ee70e74bf5
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 5m39s
CI / Deploy production (on server) (push) Successful in 22s
fix: 5 bugs critiques de l'éditeur (Phase 1 audit)
1. replaceAll (Find & Replace) — une seule transaction ProseMirror
   au lieu d'un forEach cassé. Tous les matchs sont maintenant remplacés.

2. Link Preview unwrap — deleteNode() au lieu de clearer les attrs
   qui laissaient un nœud fantôme invisible dans le document.

3. Conversion Markdown → richtext — breaks: true dans marked.parse()
   Les simple newlines sont maintenant convertis en <br>.
   + préserve les blocs custom (toggle, callout, math, columns,
   outline, link-preview) en commentaires HTML lors de l'export MD.

4. emitNoteChange exercices — shape corrigée (type:'created' attend
   un objet Note, pas noteId/notebookId séparés).

5. Raccourcis clavier sans conflit :
   Cmd+Shift+C → Cmd+Alt+C (callout, avant: copier)
   Cmd+Shift+O → Cmd+Alt+O (outline, avant: historique/signets)
   Cmd+Shift+L → Cmd+Alt+L (colonnes, avant: lock screen macOS)
2026-06-20 15:48:18 +00:00

68 lines
1.9 KiB
TypeScript

import prisma from '@/lib/prisma'
export type AuditAction =
| 'LOGIN'
| 'LOGOUT'
| 'USER_CREATED'
| 'AI_REQUEST'
| 'DATA_EXPORT'
| 'ACCOUNT_DELETED'
| 'PASSWORD_RESET'
| 'AI_CONSENT_GRANTED'
| 'AI_CONSENT_REVOKED'
| 'SUBSCRIPTION_OVERRIDE'
| 'BILLING_CONFIG_UPDATED'
| 'PLAN_ENTITLEMENT_UPDATED'
export interface AuditLogParams {
userId?: string | null
action: AuditAction
resource?: string
metadata?: Record<string, unknown>
ip?: string
userAgent?: string
}
/** Fire-and-forget — never throws, safe to call anywhere */
export function logAuditEvent(params: AuditLogParams): void {
prisma.auditLog
.create({
data: {
userId: params.userId ?? null,
action: params.action,
resource: params.resource ?? null,
metadata: params.metadata ? (params.metadata as any) : undefined,
ip: params.ip ?? null,
userAgent: params.userAgent ?? null,
},
})
.catch((err: unknown) => console.error('[audit-log] write failed:', err))
}
/** Awaitable version for cases where ordering matters */
export async function logAuditEventAsync(params: AuditLogParams): Promise<void> {
try {
await prisma.auditLog.create({
data: {
userId: params.userId ?? null,
action: params.action,
resource: params.resource ?? null,
metadata: params.metadata ? (params.metadata as any) : undefined,
ip: params.ip ?? null,
userAgent: params.userAgent ?? null,
},
})
} catch (err) {
console.error('[audit-log] write failed:', err)
}
}
/** Extract IP from request headers (works behind Cloudflare / nginx) */
export function getClientIp(request: Request): string | undefined {
const cf = request.headers.get('cf-connecting-ip')
if (cf) return cf
const xff = request.headers.get('x-forwarded-for')
if (xff) return xff.split(',')[0].trim()
return undefined
}