Bug Description
When logging in via OIDC (OpenID Connect), the session is created in the database without userAgent and ipAddress fields. The checkSession() function in lib/session.ts then treats this session as a potential hijacking attempt and deletes it immediately, causing the user to be logged out on the next API call.
Root Cause
In controllers/auth.ts, the OIDC callback handler creates a session like this:
await prisma.session.create({
data: {
userId: user.id,
sessionToken: signed_token,
expires: new Date(Date.now() + 8 * 60 * 60 * 1000),
// Missing: userAgent and ipAddress
},
});
But lib/session.ts → checkSession() has anti-hijacking logic:
if (session.userAgent !== currentUserAgent && session.ipAddress !== currentIp) {
await prisma.session.delete({ where: { id: session.id } });
return null;
}
Since session.userAgent is null and currentUserAgent is a real user-agent string, the condition null !== "Mozilla/..." evaluates to true, and the session is deleted.
Expected Behavior
OIDC sessions should persist after login, just like email/password sessions.
Fix
Add userAgent and ipAddress to the OIDC session creation:
await prisma.session.create({
data: {
userId: user.id,
sessionToken: signed_token,
expires: new Date(Date.now() + 8 * 60 * 60 * 1000),
+ userAgent: request.headers["user-agent"] || "",
+ ipAddress: request.ip || "",
},
});
The same fix should be applied to both the OIDC and OAuth callback handlers.
Environment
- Peppermint version: 0.5.5 (Docker
pepperlabs/peppermint:latest)
- OIDC Provider: Zitadel (PKCE public client)
- Database: PostgreSQL
Bug Description
When logging in via OIDC (OpenID Connect), the session is created in the database without
userAgentandipAddressfields. ThecheckSession()function inlib/session.tsthen treats this session as a potential hijacking attempt and deletes it immediately, causing the user to be logged out on the next API call.Root Cause
In
controllers/auth.ts, the OIDC callback handler creates a session like this:But
lib/session.ts→checkSession()has anti-hijacking logic:Since
session.userAgentisnullandcurrentUserAgentis a real user-agent string, the conditionnull !== "Mozilla/..."evaluates totrue, and the session is deleted.Expected Behavior
OIDC sessions should persist after login, just like email/password sessions.
Fix
Add
userAgentandipAddressto the OIDC session creation:await prisma.session.create({ data: { userId: user.id, sessionToken: signed_token, expires: new Date(Date.now() + 8 * 60 * 60 * 1000), + userAgent: request.headers["user-agent"] || "", + ipAddress: request.ip || "", }, });The same fix should be applied to both the OIDC and OAuth callback handlers.
Environment
pepperlabs/peppermint:latest)