1
0
Fork 0
mirror of synced 2024-09-20 03:08:18 +12:00
budibase/packages/backend-core/src/security/sessions.js

91 lines
2.5 KiB
JavaScript
Raw Normal View History

2021-07-07 05:10:04 +12:00
const redis = require("../redis/authRedis")
2022-01-26 11:54:50 +13:00
const { v4: uuidv4 } = require("uuid")
2021-07-07 05:10:04 +12:00
// a week in seconds
const EXPIRY_SECONDS = 86400 * 7
2021-07-07 05:10:04 +12:00
async function getSessionsForUser(userId) {
const client = await redis.getSessionClient()
2021-07-08 10:29:19 +12:00
const sessions = await client.scan(userId)
return sessions.map(session => session.value)
2021-07-07 05:10:04 +12:00
}
function makeSessionID(userId, sessionId) {
return `${userId}/${sessionId}`
}
async function invalidateSessions(userId, sessionIds = null) {
2021-07-07 05:10:04 +12:00
let sessions = []
// If no sessionIds, get all the sessions for the user
if (!sessionIds) {
2021-07-07 05:10:04 +12:00
sessions = await getSessionsForUser(userId)
sessions.forEach(
session =>
(session.key = makeSessionID(session.userId, session.sessionId))
)
} else {
// use the passed array of sessionIds
sessions = Array.isArray(sessionIds) ? sessionIds : [sessionIds]
sessions = sessions.map(sessionId => ({
key: makeSessionID(userId, sessionId),
}))
2021-07-07 05:10:04 +12:00
}
2021-07-07 05:10:04 +12:00
const client = await redis.getSessionClient()
const promises = []
for (let session of sessions) {
promises.push(client.delete(session.key))
}
await Promise.all(promises)
}
exports.createASession = async (userId, session) => {
// invalidate all other sessions
await invalidateSessions(userId)
const client = await redis.getSessionClient()
const sessionId = session.sessionId
if (!session.csrfToken) {
session.csrfToken = uuidv4()
}
session = {
createdAt: new Date().toISOString(),
lastAccessedAt: new Date().toISOString(),
...session,
userId,
}
await client.store(makeSessionID(userId, sessionId), session, EXPIRY_SECONDS)
}
2021-07-08 10:29:19 +12:00
exports.updateSessionTTL = async session => {
2021-07-07 05:10:04 +12:00
const client = await redis.getSessionClient()
2021-07-08 10:29:19 +12:00
const key = makeSessionID(session.userId, session.sessionId)
2021-07-08 10:30:14 +12:00
session.lastAccessedAt = new Date().toISOString()
2021-07-08 10:29:19 +12:00
await client.store(key, session, EXPIRY_SECONDS)
2021-07-07 05:10:04 +12:00
}
exports.endSession = async (userId, sessionId) => {
const client = await redis.getSessionClient()
await client.delete(makeSessionID(userId, sessionId))
}
exports.getSession = async (userId, sessionId) => {
try {
const client = await redis.getSessionClient()
return client.get(makeSessionID(userId, sessionId))
} catch (err) {
// if can't get session don't error, just don't return anything
return null
}
}
exports.getAllSessions = async () => {
const client = await redis.getSessionClient()
2021-07-08 10:29:19 +12:00
const sessions = await client.scan()
return sessions.map(session => session.value)
2021-07-07 05:10:04 +12:00
}
exports.getUserSessions = getSessionsForUser
exports.invalidateSessions = invalidateSessions