Add customer login activity logging
- Add CustomerLoginLog model to track customer login attempts - Record successful and failed customer logins - Capture email, IP address, and user agent for each attempt - Create /admin/customer-login-logs page to view activity - Show login stats (successes, failures, active customers) - Display browser/device and IP for each login attempt - Add "Customer login activity" link to admin menu - Monitor customer access patterns and detect suspicious activity - Last 30 days active customer count Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
ea6f9d2e25
commit
e69759081c
@@ -62,8 +62,14 @@ export async function loginCustomer(formData: FormData) {
|
||||
const next = safeNext(formData.get('next'));
|
||||
|
||||
const ip = getClientIp(headers());
|
||||
const userAgent = headers().get('user-agent') ?? undefined;
|
||||
|
||||
const { allowed } = await checkRateLimit(`login:customer:${ip}`, 5, 15 * 60 * 1000);
|
||||
if (!allowed) {
|
||||
// Log rate limited attempt
|
||||
await prisma.customerLoginLog.create({
|
||||
data: { success: false, email, ipAddress: ip, userAgent },
|
||||
});
|
||||
redirect(`/account/login?error=rate_limited&next=${encodeURIComponent(next)}`);
|
||||
}
|
||||
|
||||
@@ -71,9 +77,18 @@ export async function loginCustomer(formData: FormData) {
|
||||
const valid = customer ? await verifyPassword(password, customer.passwordHash) : false;
|
||||
|
||||
if (!customer || !valid) {
|
||||
// Log failed login attempt
|
||||
await prisma.customerLoginLog.create({
|
||||
data: { success: false, email, ipAddress: ip, userAgent },
|
||||
});
|
||||
redirect(`/account/login?error=invalid&next=${encodeURIComponent(next)}`);
|
||||
}
|
||||
|
||||
// Log successful login
|
||||
await prisma.customerLoginLog.create({
|
||||
data: { success: true, customerId: customer.id, email, ipAddress: ip, userAgent },
|
||||
});
|
||||
|
||||
await linkGuestOrders(customer.id, customer.email);
|
||||
await createSession(customer.id);
|
||||
redirect(next);
|
||||
|
||||
Reference in New Issue
Block a user