Invalidate Sessions on Password Change#20
Open
Leon-JavaScript wants to merge 15 commits intomasterfrom
Open
Conversation
…r session invalidation on password change
- Updated password change endpoint to invalidate all sessions and issue a new session for the current device. - Refactored authentication middleware to support session tokens and API keys. - Introduced session caching layer to reduce database reads on authenticated requests. - Added geolocation support for session tracking, including city and country information. - Enhanced user agent parsing to categorize devices and operating systems. - Deprecated old session endpoints and redirected to new canonical URLs. - Updated Swagger documentation to reflect changes in session management and API structure.
Signed-off-by: Leon Marschke <70959426+Leon-JavaScript@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Leon Marschke <70959426+Leon-JavaScript@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Leon Marschke <70959426+Leon-JavaScript@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 25 changed files in this pull request and generated 14 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+92
to
+101
| export async function cacheGet<T>(key: string): Promise<T | null> { | ||
| const redis = await getRedis(); | ||
| if (redis) { | ||
| const raw = await redis.get(key); | ||
| if (!raw) return null; | ||
| try { | ||
| return JSON.parse(raw) as T; | ||
| } catch { | ||
| return null; | ||
| } |
src/lib/middleware.ts
Outdated
Comment on lines
42
to
50
| // API key path (any other Bearer value, e.g. tk_…) | ||
| const apiKeys = await prisma.apiKey.findMany({ | ||
| where: { revokedAt: null }, | ||
| select: { | ||
| id: true, | ||
| projectId: true, | ||
| keyHash: true, | ||
| role: true, | ||
| }, | ||
| select: { id: true, projectId: true, keyHash: true, role: true }, | ||
| }); | ||
|
|
||
| // Verify the provided API key against each stored hash | ||
|
|
||
| for (const keyRecord of apiKeys) { | ||
| const isValid = await verifyApiKey(apiKey, keyRecord.keyHash); | ||
| const isValid = await verifyApiKey(token, keyRecord.keyHash); | ||
| if (isValid) { |
src/lib/swagger.ts
Outdated
Comment on lines
+594
to
+605
| @@ -510,13 +600,152 @@ export const swaggerSpec = { | |||
| message: { | |||
| type: 'string', | |||
| }, | |||
| session: { | |||
| $ref: '#/components/schemas/SessionToken', | |||
| }, | |||
Comment on lines
+10
to
+17
| { params }: { params: Promise<{ sessionId: string }> }, | ||
| ) { | ||
| const match = request.nextUrl.pathname.match(/\/sessions\/([^/]+)$/); | ||
| const sessionId = match?.[1]; | ||
| if (!sessionId) { | ||
| return NextResponse.json({ error: 'Not found' }, { status: 404 }); | ||
| } | ||
| void params; |
src/app/api/auth/login/route.ts
Outdated
| email: user.email, | ||
| name: user.name, | ||
| }, | ||
| session, |
src/app/api/auth/signup/route.ts
Outdated
| email: user.email, | ||
| name: user.name, | ||
| }, | ||
| session, |
| | `SESSION_REFRESH_EXPIRES_DAYS` | Days until a session token can no longer be refreshed | `30` | ❌ | | ||
| | `REDIS_URL` | Redis connection string for session caching (e.g. `redis://localhost:6379`). Requires `npm install ioredis`. Falls back to in-process cache when unset. | - | ❌ | | ||
| | `GEOIP_ENABLED` | Set to `true` to geo-locate client IPs on session creation (city + country via ip-api.com) | `false` | ❌ | | ||
|
|
| # ── Optional: Redis cache ───────────────────────────────────── | ||
| # When set, validated session payloads are cached in Redis instead of the | ||
| # built-in in-process Map. Recommended for multi-instance deployments. | ||
| # Requires: npm install ioredis |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Leon Marschke <70959426+Leon-JavaScript@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR improves authentication security by embedding a password signature in JWT tokens. The signature, derived from the user's password hash, enables automatic invalidation of all active sessions when a user changes their password. Key updates include:
These enhancements ensure robust session management and protect user accounts from unauthorized access after password updates.