chore: adds session helper exports (#13367)

Creates/exports `addSessionToUser` helper and also exports the
`removeExpiredSessions` helper.
This commit is contained in:
Jarrod Flesch
2025-08-04 22:53:36 -04:00
committed by GitHub
parent 1d70d4d36c
commit 3b9dba8641
5 changed files with 78 additions and 41 deletions

View File

@@ -1,5 +1,3 @@
import { v4 as uuid } from 'uuid'
import type {
AuthOperationsFromCollectionSlug,
Collection,
@@ -24,7 +22,7 @@ import { getFieldsToSign } from '../getFieldsToSign.js'
import { getLoginOptions } from '../getLoginOptions.js'
import { isUserLocked } from '../isUserLocked.js'
import { jwtSign } from '../jwt.js'
import { removeExpiredSessions } from '../removeExpiredSessions.js'
import { addSessionToUser } from '../sessions.js'
import { authenticateLocalStrategy } from '../strategies/local/authenticate.js'
import { incrementLoginAttempts } from '../strategies/local/incrementLoginAttempts.js'
import { resetLoginAttempts } from '../strategies/local/resetLoginAttempts.js'
@@ -285,34 +283,15 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
user,
}
if (collectionConfig.auth.useSessions) {
// Add session to user
const newSessionID = uuid()
const now = new Date()
const tokenExpInMs = collectionConfig.auth.tokenExpiration * 1000
const expiresAt = new Date(now.getTime() + tokenExpInMs)
const { sid } = await addSessionToUser({
collectionConfig,
payload,
req,
user,
})
const session = { id: newSessionID, createdAt: now, expiresAt }
if (!user.sessions?.length) {
user.sessions = [session]
} else {
user.sessions = removeExpiredSessions(user.sessions)
user.sessions.push(session)
}
await payload.db.updateOne({
id: user.id,
collection: collectionConfig.slug,
data: user,
req,
returning: false,
})
user.collection = collectionConfig.slug
user._strategy = 'local-jwt'
fieldsToSignArgs.sid = newSessionID
if (sid) {
fieldsToSignArgs.sid = sid
}
const fieldsToSign = getFieldsToSign(fieldsToSignArgs)

View File

@@ -10,7 +10,7 @@ import { initTransaction } from '../../utilities/initTransaction.js'
import { killTransaction } from '../../utilities/killTransaction.js'
import { getFieldsToSign } from '../getFieldsToSign.js'
import { jwtSign } from '../jwt.js'
import { removeExpiredSessions } from '../removeExpiredSessions.js'
import { removeExpiredSessions } from '../sessions.js'
export type Result = {
exp: number

View File

@@ -1,10 +0,0 @@
import type { UserSession } from './types.js'
export const removeExpiredSessions = (sessions: UserSession[]) => {
const now = new Date()
return sessions.filter(({ expiresAt }) => {
const expiry = expiresAt instanceof Date ? expiresAt : new Date(expiresAt)
return expiry > now
})
}

View File

@@ -0,0 +1,67 @@
import { v4 as uuid } from 'uuid'
import type { SanitizedCollectionConfig } from '../collections/config/types.js'
import type { TypedUser } from '../index.js'
import type { Payload, PayloadRequest } from '../types/index.js'
import type { UserSession } from './types.js'
/**
* Removes expired sessions from an array of sessions
*/
export const removeExpiredSessions = (sessions: UserSession[]) => {
const now = new Date()
return sessions.filter(({ expiresAt }) => {
const expiry = expiresAt instanceof Date ? expiresAt : new Date(expiresAt)
return expiry > now
})
}
/**
* Adds a session to the user and removes expired sessions
* @returns The session ID (sid) if sessions are used
*/
export const addSessionToUser = async ({
collectionConfig,
payload,
req,
user,
}: {
collectionConfig: SanitizedCollectionConfig
payload: Payload
req: PayloadRequest
user: TypedUser
}): Promise<{ sid?: string }> => {
let sid: string | undefined
if (collectionConfig.auth.useSessions) {
// Add session to user
sid = uuid()
const now = new Date()
const tokenExpInMs = collectionConfig.auth.tokenExpiration * 1000
const expiresAt = new Date(now.getTime() + tokenExpInMs)
const session = { id: sid, createdAt: now, expiresAt }
if (!user.sessions?.length) {
user.sessions = [session]
} else {
user.sessions = removeExpiredSessions(user.sessions)
user.sessions.push(session)
}
await payload.db.updateOne({
id: user.id,
collection: collectionConfig.slug,
data: user,
req,
returning: false,
})
user.collection = collectionConfig.slug
user._strategy = 'local-jwt'
}
return {
sid,
}
}

View File

@@ -6,6 +6,7 @@ export {
parseCookies,
} from '../auth/cookies.js'
export { getLoginOptions } from '../auth/getLoginOptions.js'
export { addSessionToUser, removeExpiredSessions } from '../auth/sessions.js'
export { getFromImportMap } from '../bin/generateImportMap/utilities/getFromImportMap.js'
export { parsePayloadComponent } from '../bin/generateImportMap/utilities/parsePayloadComponent.js'
export { defaults as collectionDefaults } from '../collections/config/defaults.js'