chore: adds session helper exports (#13367)
Creates/exports `addSessionToUser` helper and also exports the `removeExpiredSessions` helper.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
67
packages/payload/src/auth/sessions.ts
Normal file
67
packages/payload/src/auth/sessions.ts
Normal 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,
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user