Compare commits

...

4 Commits

Author SHA1 Message Date
argoyle 96453e1d15 Merge branch 'next-release' into 'main'
chore(release): prepare for 0.4.0

See merge request unboundsoftware/auth0mock!217
2025-12-29 13:19:27 +01:00
Unbound Release fd4f9c4052 chore(release): prepare for 0.4.0 2025-12-29 13:19:26 +01:00
argoyle ce5fd95bed Merge branch 'feat/session-expiration-cleanup' into 'main'
feat(session-cleanup): implement session expiration cleanup

See merge request unboundsoftware/auth0mock!216
2025-12-29 13:17:53 +01:00
argoyle 972cf3ba45 feat(session-cleanup): implement session expiration cleanup
adds a cleanup mechanism for expired sessions to prevent memory leaks by 
deleting sessions and challenges that exceed the defined TTL. Each session 
is assigned a creation timestamp, which is updated upon activity, and the 
cleanup process runs every minute to maintain optimal memory usage.
2025-12-29 13:14:46 +01:00
3 changed files with 34 additions and 2 deletions
+1 -1
View File
@@ -1 +1 @@
{"version":"0.3.0"}
{"version":"0.4.0"}
+5
View File
@@ -1,3 +1,8 @@
## [0.4.0] - 2025-12-29
### 🚀 Features
- *(session-cleanup)* Implement session expiration cleanup
## [0.3.0] - 2025-12-28
### 🚀 Features
+28 -1
View File
@@ -29,6 +29,25 @@ const users = initialUsers(process.env.USERS_FILE || './users.json')
const sessions = {}
const challenges = {}
// Session TTL in milliseconds (5 minutes)
const SESSION_TTL_MS = 5 * 60 * 1000
// Periodically clean up old sessions to prevent memory leaks
setInterval(() => {
const now = Date.now()
let cleaned = 0
for (const [key, session] of Object.entries(sessions)) {
if (session.createdAt && now - session.createdAt > SESSION_TTL_MS) {
delete sessions[key]
delete challenges[key]
cleaned++
}
}
if (cleaned > 0) {
debug(`Cleaned up ${cleaned} expired sessions`)
}
}, 60000) // Run every minute
const corsOpts = (req, cb) => {
cb(null, { origin: req.headers.origin })
}
@@ -163,7 +182,8 @@ app.post('/code', (req, res) => {
nonce: req.body.nonce,
clientId: req.body.clientId,
codeChallenge: req.body.codeChallenge,
customClaims: [claim]
customClaims: [claim],
createdAt: Date.now()
}
res.redirect(
`${req.body.redirect}?code=${code}&state=${encodeURIComponent(state)}`
@@ -185,7 +205,13 @@ app.get('/authorize', (req, res) => {
session.nonce = nonce
session.state = state
session.codeChallenge = codeChallenge
session.createdAt = Date.now() // Refresh timestamp
sessions[codeChallenge] = session
// Clean up old session entry if different key
if (code !== codeChallenge) {
delete sessions[code]
delete challenges[code]
}
res.redirect(`${redirect}?code=${codeChallenge}&state=${state}`)
return
}
@@ -197,6 +223,7 @@ app.get('/authorize', (req, res) => {
session.nonce = nonce
session.state = state
session.codeChallenge = codeChallenge
session.createdAt = Date.now() // Refresh timestamp
res.send(`
<!DOCTYPE html>
<html>