payload 4.0.0-internal.4cbdd50 → 4.0.0-internal.5214550
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/dist/admin/RichText.d.ts +1 -21
- package/dist/admin/RichText.d.ts.map +1 -1
- package/dist/admin/RichText.js.map +1 -1
- package/dist/admin/forms/Field.d.ts +2 -2
- package/dist/admin/forms/Field.d.ts.map +1 -1
- package/dist/admin/forms/Field.js.map +1 -1
- package/dist/admin/forms/Form.d.ts +0 -29
- package/dist/admin/forms/Form.d.ts.map +1 -1
- package/dist/admin/forms/Form.js.map +1 -1
- package/dist/admin/functions/index.d.ts +1 -1
- package/dist/admin/functions/index.js.map +1 -1
- package/dist/admin/types.d.ts +1 -0
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/admin/types.js.map +1 -1
- package/dist/auth/operations/auth.d.ts +2 -2
- package/dist/auth/operations/auth.d.ts.map +1 -1
- package/dist/auth/operations/auth.js.map +1 -1
- package/dist/auth/operations/login.d.ts +2 -1
- package/dist/auth/operations/login.d.ts.map +1 -1
- package/dist/auth/operations/login.js.map +1 -1
- package/dist/auth/operations/me.js.map +1 -1
- package/dist/auth/operations/refresh.d.ts.map +1 -1
- package/dist/auth/operations/refresh.js +9 -3
- package/dist/auth/operations/refresh.js.map +1 -1
- package/dist/auth/operations/resetPassword.d.ts.map +1 -1
- package/dist/auth/operations/resetPassword.js.map +1 -1
- package/dist/auth/sendVerificationEmail.d.ts +2 -2
- package/dist/auth/sendVerificationEmail.d.ts.map +1 -1
- package/dist/auth/sendVerificationEmail.js +1 -1
- package/dist/auth/sendVerificationEmail.js.map +1 -1
- package/dist/auth/sessions.d.ts +4 -5
- package/dist/auth/sessions.d.ts.map +1 -1
- package/dist/auth/sessions.js +5 -3
- package/dist/auth/sessions.js.map +1 -1
- package/dist/auth/strategies/apiKey.js.map +1 -1
- package/dist/auth/strategies/local/incrementLoginAttempts.d.ts +2 -2
- package/dist/auth/strategies/local/incrementLoginAttempts.d.ts.map +1 -1
- package/dist/auth/strategies/local/incrementLoginAttempts.js +1 -1
- package/dist/auth/strategies/local/incrementLoginAttempts.js.map +1 -1
- package/dist/auth/types.d.ts +28 -21
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/bin/generateImportMap/iterateCollections.d.ts.map +1 -1
- package/dist/bin/generateImportMap/iterateCollections.js +10 -0
- package/dist/bin/generateImportMap/iterateCollections.js.map +1 -1
- package/dist/collections/config/client.d.ts +1 -1
- package/dist/collections/config/client.d.ts.map +1 -1
- package/dist/collections/config/client.js +1 -0
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/config/defaults.d.ts +0 -4
- package/dist/collections/config/defaults.d.ts.map +1 -1
- package/dist/collections/config/defaults.js +0 -15
- package/dist/collections/config/defaults.js.map +1 -1
- package/dist/collections/config/types.d.ts +6 -0
- package/dist/collections/config/types.d.ts.map +1 -1
- package/dist/collections/config/types.js.map +1 -1
- package/dist/collections/operations/findDistinct.d.ts.map +1 -1
- package/dist/collections/operations/findDistinct.js +1 -0
- package/dist/collections/operations/findDistinct.js.map +1 -1
- package/dist/collections/operations/local/count.d.ts +3 -3
- package/dist/collections/operations/local/count.d.ts.map +1 -1
- package/dist/collections/operations/local/count.js.map +1 -1
- package/dist/collections/operations/local/countVersions.d.ts +3 -3
- package/dist/collections/operations/local/countVersions.d.ts.map +1 -1
- package/dist/collections/operations/local/countVersions.js.map +1 -1
- package/dist/collections/operations/local/create.d.ts +3 -3
- package/dist/collections/operations/local/create.d.ts.map +1 -1
- package/dist/collections/operations/local/create.js.map +1 -1
- package/dist/collections/operations/local/delete.d.ts +3 -3
- package/dist/collections/operations/local/delete.d.ts.map +1 -1
- package/dist/collections/operations/local/delete.js.map +1 -1
- package/dist/collections/operations/local/duplicate.d.ts +3 -3
- package/dist/collections/operations/local/duplicate.d.ts.map +1 -1
- package/dist/collections/operations/local/duplicate.js.map +1 -1
- package/dist/collections/operations/local/find.d.ts +3 -3
- package/dist/collections/operations/local/find.d.ts.map +1 -1
- package/dist/collections/operations/local/find.js.map +1 -1
- package/dist/collections/operations/local/findByID.d.ts +3 -3
- package/dist/collections/operations/local/findByID.d.ts.map +1 -1
- package/dist/collections/operations/local/findByID.js.map +1 -1
- package/dist/collections/operations/local/findDistinct.d.ts +2 -2
- package/dist/collections/operations/local/findDistinct.d.ts.map +1 -1
- package/dist/collections/operations/local/findDistinct.js.map +1 -1
- package/dist/collections/operations/local/findVersionByID.d.ts +3 -3
- package/dist/collections/operations/local/findVersionByID.d.ts.map +1 -1
- package/dist/collections/operations/local/findVersionByID.js.map +1 -1
- package/dist/collections/operations/local/findVersions.d.ts +3 -3
- package/dist/collections/operations/local/findVersions.d.ts.map +1 -1
- package/dist/collections/operations/local/findVersions.js.map +1 -1
- package/dist/collections/operations/local/restoreVersion.d.ts +3 -3
- package/dist/collections/operations/local/restoreVersion.d.ts.map +1 -1
- package/dist/collections/operations/local/restoreVersion.js.map +1 -1
- package/dist/collections/operations/local/update.d.ts +3 -3
- package/dist/collections/operations/local/update.d.ts.map +1 -1
- package/dist/collections/operations/local/update.js.map +1 -1
- package/dist/collections/operations/utilities/types.d.ts +0 -9
- package/dist/collections/operations/utilities/types.d.ts.map +1 -1
- package/dist/collections/operations/utilities/types.js.map +1 -1
- package/dist/config/client.d.ts +2 -2
- package/dist/config/client.d.ts.map +1 -1
- package/dist/config/client.js.map +1 -1
- package/dist/config/defaults.d.ts +0 -4
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +0 -78
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/definePlugin.d.ts +10 -10
- package/dist/config/definePlugin.d.ts.map +1 -1
- package/dist/config/definePlugin.js +7 -11
- package/dist/config/definePlugin.js.map +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +137 -13
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +35 -3
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/exports/internal.d.ts +1 -0
- package/dist/exports/internal.d.ts.map +1 -1
- package/dist/exports/internal.js +1 -0
- package/dist/exports/internal.js.map +1 -1
- package/dist/exports/shared.d.ts +3 -2
- package/dist/exports/shared.d.ts.map +1 -1
- package/dist/exports/shared.js +2 -1
- package/dist/exports/shared.js.map +1 -1
- package/dist/fields/baseFields/slug/countVersions.d.ts.map +1 -1
- package/dist/fields/baseFields/slug/countVersions.js +6 -8
- package/dist/fields/baseFields/slug/countVersions.js.map +1 -1
- package/dist/fields/baseFields/slug/generateSlug.d.ts +14 -7
- package/dist/fields/baseFields/slug/generateSlug.d.ts.map +1 -1
- package/dist/fields/baseFields/slug/generateSlug.js +53 -73
- package/dist/fields/baseFields/slug/generateSlug.js.map +1 -1
- package/dist/fields/baseFields/slug/types.d.ts +14 -0
- package/dist/fields/baseFields/slug/types.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/types.js +6 -0
- package/dist/fields/baseFields/slug/types.js.map +1 -0
- package/dist/fields/config/client.d.ts +1 -1
- package/dist/fields/config/client.d.ts.map +1 -1
- package/dist/fields/config/client.js +2 -1
- package/dist/fields/config/client.js.map +1 -1
- package/dist/fields/config/sanitize.d.ts.map +1 -1
- package/dist/fields/config/sanitize.js +39 -0
- package/dist/fields/config/sanitize.js.map +1 -1
- package/dist/fields/config/types.d.ts +44 -8
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/config/types.js.map +1 -1
- package/dist/fields/hooks/afterRead/promise.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/promise.js +11 -1
- package/dist/fields/hooks/afterRead/promise.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.js +10 -1
- package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
- package/dist/fields/setDefaultBeforeDuplicate.js +1 -0
- package/dist/fields/setDefaultBeforeDuplicate.js.map +1 -1
- package/dist/fields/sortableFieldTypes.d.ts.map +1 -1
- package/dist/fields/sortableFieldTypes.js +1 -0
- package/dist/fields/sortableFieldTypes.js.map +1 -1
- package/dist/fields/validations.d.ts +4 -1
- package/dist/fields/validations.d.ts.map +1 -1
- package/dist/fields/validations.js +7 -0
- package/dist/fields/validations.js.map +1 -1
- package/dist/globals/operations/local/countVersions.d.ts +3 -3
- package/dist/globals/operations/local/countVersions.d.ts.map +1 -1
- package/dist/globals/operations/local/countVersions.js.map +1 -1
- package/dist/globals/operations/local/findOne.d.ts +3 -3
- package/dist/globals/operations/local/findOne.d.ts.map +1 -1
- package/dist/globals/operations/local/findOne.js.map +1 -1
- package/dist/globals/operations/local/findVersionByID.d.ts +3 -3
- package/dist/globals/operations/local/findVersionByID.d.ts.map +1 -1
- package/dist/globals/operations/local/findVersionByID.js.map +1 -1
- package/dist/globals/operations/local/findVersions.d.ts +3 -3
- package/dist/globals/operations/local/findVersions.d.ts.map +1 -1
- package/dist/globals/operations/local/findVersions.js.map +1 -1
- package/dist/globals/operations/local/restoreVersion.d.ts +3 -3
- package/dist/globals/operations/local/restoreVersion.d.ts.map +1 -1
- package/dist/globals/operations/local/restoreVersion.js.map +1 -1
- package/dist/globals/operations/local/update.d.ts +3 -3
- package/dist/globals/operations/local/update.d.ts.map +1 -1
- package/dist/globals/operations/local/update.js.map +1 -1
- package/dist/index.bundled.d.ts +365 -300
- package/dist/index.d.ts +59 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/preferences/keys.d.ts +4 -0
- package/dist/preferences/keys.d.ts.map +1 -1
- package/dist/preferences/keys.js +4 -1
- package/dist/preferences/keys.js.map +1 -1
- package/dist/preferences/types.d.ts +15 -0
- package/dist/preferences/types.d.ts.map +1 -1
- package/dist/preferences/types.js +3 -1
- package/dist/preferences/types.js.map +1 -1
- package/dist/types/index.d.ts +8 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts.map +1 -1
- package/dist/uploads/fetchAPI-multipart/processMultipart.js +1 -14
- package/dist/uploads/fetchAPI-multipart/processMultipart.js.map +1 -1
- package/dist/uploads/matchMimeType.d.ts +8 -0
- package/dist/uploads/matchMimeType.d.ts.map +1 -0
- package/dist/uploads/matchMimeType.js +19 -0
- package/dist/uploads/matchMimeType.js.map +1 -0
- package/dist/uploads/matchMimeType.spec.js +66 -0
- package/dist/uploads/matchMimeType.spec.js.map +1 -0
- package/dist/uploads/types.d.ts +21 -0
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.js +6 -0
- package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
- package/dist/utilities/configToJSONSchema.d.ts +13 -4
- package/dist/utilities/configToJSONSchema.d.ts.map +1 -1
- package/dist/utilities/configToJSONSchema.js +139 -61
- package/dist/utilities/configToJSONSchema.js.map +1 -1
- package/dist/utilities/configToJSONSchema.spec.js +319 -0
- package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
- package/dist/utilities/createLocalReq.d.ts +2 -2
- package/dist/utilities/createLocalReq.d.ts.map +1 -1
- package/dist/utilities/createLocalReq.js.map +1 -1
- package/dist/utilities/getEntityPermissions/getEntityPermissions.d.ts.map +1 -1
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js +2 -0
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js.map +1 -1
- package/dist/utilities/getEntityPermissions/populateFieldPermissions.d.ts +7 -1
- package/dist/utilities/getEntityPermissions/populateFieldPermissions.d.ts.map +1 -1
- package/dist/utilities/getEntityPermissions/populateFieldPermissions.js +19 -2
- package/dist/utilities/getEntityPermissions/populateFieldPermissions.js.map +1 -1
- package/dist/utilities/isURLAllowed.d.ts.map +1 -1
- package/dist/utilities/isURLAllowed.js +9 -3
- package/dist/utilities/isURLAllowed.js.map +1 -1
- package/dist/utilities/isURLAllowed.spec.js +78 -0
- package/dist/utilities/isURLAllowed.spec.js.map +1 -0
- package/dist/utilities/telemetry/conf/envPaths.d.ts.map +1 -1
- package/dist/utilities/telemetry/conf/envPaths.js +40 -31
- package/dist/utilities/telemetry/conf/envPaths.js.map +1 -1
- package/dist/utilities/telemetry/events/adminInit.d.ts.map +1 -1
- package/dist/utilities/telemetry/events/adminInit.js +2 -3
- package/dist/utilities/telemetry/events/adminInit.js.map +1 -1
- package/dist/utilities/telemetry/events/serverInit.d.ts.map +1 -1
- package/dist/utilities/telemetry/events/serverInit.js +2 -3
- package/dist/utilities/telemetry/events/serverInit.js.map +1 -1
- package/dist/utilities/telemetry/index.d.ts +14 -3
- package/dist/utilities/telemetry/index.d.ts.map +1 -1
- package/dist/utilities/telemetry/index.js +6 -1
- package/dist/utilities/telemetry/index.js.map +1 -1
- package/dist/utilities/telemetry/index.spec.js +43 -0
- package/dist/utilities/telemetry/index.spec.js.map +1 -0
- package/dist/versions/schedule/job.d.ts.map +1 -1
- package/dist/versions/schedule/job.js +4 -1
- package/dist/versions/schedule/job.js.map +1 -1
- package/package.json +2 -2
- package/dist/fields/baseFields/slug/index.d.ts +0 -89
- package/dist/fields/baseFields/slug/index.d.ts.map +0 -1
- package/dist/fields/baseFields/slug/index.js +0 -81
- package/dist/fields/baseFields/slug/index.js.map +0 -1
- package/dist/utilities/isRSCEnabled.d.ts +0 -12
- package/dist/utilities/isRSCEnabled.d.ts.map +0 -1
- package/dist/utilities/isRSCEnabled.js +0 -14
- package/dist/utilities/isRSCEnabled.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/operations/login.ts"],"sourcesContent":["import type {\n AuthOperationsFromCollectionSlug,\n Collection,\n DataFromCollectionSlug,\n} from '../../collections/config/types.js'\nimport type { AuthCollectionSlug, TypedUser } from '../../index.js'\nimport type { PayloadRequest, Where } from '../../types/index.js'\n\nimport { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'\nimport { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'\nimport {\n AuthenticationError,\n LockedAuth,\n UnverifiedEmail,\n ValidationError,\n} from '../../errors/index.js'\nimport { afterRead } from '../../fields/hooks/afterRead/index.js'\nimport { commitTransaction, Forbidden, initTransaction } from '../../index.js'\nimport { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { sanitizeInternalFields } from '../../utilities/sanitizeInternalFields.js'\nimport { getFieldsToSign } from '../getFieldsToSign.js'\nimport { getLoginOptions } from '../getLoginOptions.js'\nimport { isUserLocked } from '../isUserLocked.js'\nimport { jwtSign } from '../jwt.js'\nimport { addSessionToUser, revokeSession } from '../sessions.js'\nimport { authenticateLocalStrategy } from '../strategies/local/authenticate.js'\nimport { incrementLoginAttempts } from '../strategies/local/incrementLoginAttempts.js'\nimport { resetLoginAttempts } from '../strategies/local/resetLoginAttempts.js'\n\nexport type LoginResult<TSlug extends AuthCollectionSlug> = {\n exp?: number\n token?: string\n user?: DataFromCollectionSlug<TSlug>\n}\n\nexport type Arguments<TSlug extends AuthCollectionSlug> = {\n collection: Collection\n data: AuthOperationsFromCollectionSlug<TSlug>['login']\n depth?: number\n overrideAccess?: boolean\n req: PayloadRequest\n showHiddenFields?: boolean\n}\n\ntype CheckLoginPermissionArgs<TSlug extends AuthCollectionSlug> = {\n loggingInWithUsername?: boolean\n req: PayloadRequest\n user: DataFromCollectionSlug<TSlug>\n}\n\n/**\n * Throws an error if the user is locked or does not exist.\n * This does not check the login attempts, only the lock status. Whoever increments login attempts\n * is responsible for locking the user properly, not whoever checks the login permission.\n */\nexport const checkLoginPermission = <TSlug extends AuthCollectionSlug>({\n loggingInWithUsername,\n req,\n user,\n}: CheckLoginPermissionArgs<TSlug>) => {\n if (!user) {\n throw new AuthenticationError(req.t, Boolean(loggingInWithUsername))\n }\n\n if (isUserLocked(new Date(user.lockUntil))) {\n throw new LockedAuth(req.t)\n }\n}\n\nexport const loginOperation = async <TSlug extends AuthCollectionSlug>(\n incomingArgs: Arguments<TSlug>,\n): Promise<LoginResult<TSlug>> => {\n let args = incomingArgs\n\n if (args.collection.config.auth.disableLocalStrategy) {\n throw new Forbidden(args.req.t)\n }\n\n // /////////////////////////////////////\n // beforeOperation - Collection\n // /////////////////////////////////////\n\n args = await buildBeforeOperation({\n args,\n collection: args.collection.config,\n operation: 'login',\n overrideAccess: args.overrideAccess!,\n })\n\n const {\n collection: { config: collectionConfig },\n data,\n depth,\n overrideAccess = false,\n req,\n req: {\n fallbackLocale,\n locale,\n payload,\n payload: { secret },\n },\n showHiddenFields,\n } = args\n\n // /////////////////////////////////////\n // Login\n // /////////////////////////////////////\n\n const { email: unsanitizedEmail, password } = data\n const loginWithUsername = collectionConfig.auth.loginWithUsername\n\n const sanitizedEmail =\n typeof unsanitizedEmail === 'string' ? unsanitizedEmail.toLowerCase().trim() : null\n const sanitizedUsername =\n 'username' in data && typeof data?.username === 'string'\n ? data.username.toLowerCase().trim()\n : null\n\n const { canLoginWithEmail, canLoginWithUsername } = getLoginOptions(loginWithUsername)\n\n // cannot login with email, did not provide username\n if (!canLoginWithEmail && !sanitizedUsername) {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [{ message: req.i18n.t('validation:required'), path: 'username' }],\n })\n }\n\n // cannot login with username, did not provide email\n if (!canLoginWithUsername && !sanitizedEmail) {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [{ message: req.i18n.t('validation:required'), path: 'email' }],\n })\n }\n\n // can login with either email or username, did not provide either\n if (!sanitizedUsername && !sanitizedEmail) {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [\n { message: req.i18n.t('validation:required'), path: 'email' },\n { message: req.i18n.t('validation:required'), path: 'username' },\n ],\n })\n }\n\n // did not provide password for login\n if (typeof password !== 'string' || password.trim() === '') {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [{ message: req.i18n.t('validation:required'), path: 'password' }],\n })\n }\n\n let whereConstraint: Where = {}\n const emailConstraint: Where = {\n email: {\n equals: sanitizedEmail,\n },\n }\n const usernameConstraint: Where = {\n username: {\n equals: sanitizedUsername,\n },\n }\n\n if (canLoginWithEmail && canLoginWithUsername && (sanitizedUsername || sanitizedEmail)) {\n if (sanitizedUsername) {\n whereConstraint = {\n or: [\n usernameConstraint,\n {\n email: {\n equals: sanitizedUsername,\n },\n },\n ],\n }\n } else {\n whereConstraint = {\n or: [\n emailConstraint,\n {\n username: {\n equals: sanitizedEmail,\n },\n },\n ],\n }\n }\n } else if (canLoginWithEmail && sanitizedEmail) {\n whereConstraint = emailConstraint\n } else if (canLoginWithUsername && sanitizedUsername) {\n whereConstraint = usernameConstraint\n }\n\n // Exclude trashed users\n whereConstraint = appendNonTrashedFilter({\n enableTrash: collectionConfig.trash,\n trash: false,\n where: whereConstraint,\n })\n\n let user = (await payload.db.findOne<TypedUser>({\n collection: collectionConfig.slug,\n req,\n where: whereConstraint,\n })) as TypedUser\n\n checkLoginPermission({\n loggingInWithUsername: Boolean(canLoginWithUsername && sanitizedUsername),\n req,\n user,\n })\n\n user.collection = collectionConfig.slug\n user._strategy = 'local-jwt'\n\n const authResult = await authenticateLocalStrategy({ doc: user, password })\n user = sanitizeInternalFields(user)\n\n const maxLoginAttemptsEnabled = args.collection.config.auth.maxLoginAttempts > 0\n\n if (!authResult) {\n if (maxLoginAttemptsEnabled) {\n await incrementLoginAttempts({\n collection: collectionConfig,\n payload: req.payload,\n user,\n })\n\n // Re-check login permissions and max attempts after incrementing attempts, in case parallel updates occurred\n checkLoginPermission({\n loggingInWithUsername: Boolean(canLoginWithUsername && sanitizedUsername),\n req,\n user,\n })\n }\n\n throw new AuthenticationError(req.t)\n }\n\n if (collectionConfig.auth.verify && user._verified === false) {\n throw new UnverifiedEmail({ t: req.t })\n }\n\n // Authentication successful - start transaction for remaining operations\n const shouldCommit = await initTransaction(args.req)\n let sid: string | undefined\n\n try {\n /*\n * Correct password accepted - re‑check that the account didn't\n * get locked by parallel bad attempts in the meantime.\n */\n if (maxLoginAttemptsEnabled) {\n const { lockUntil, loginAttempts } = (await payload.db.findOne<TypedUser>({\n collection: collectionConfig.slug,\n req,\n select: {\n lockUntil: true,\n loginAttempts: true,\n },\n where: { id: { equals: user.id } },\n }))!\n\n user.lockUntil = lockUntil\n user.loginAttempts = loginAttempts\n\n checkLoginPermission({\n req,\n user,\n })\n }\n\n const fieldsToSignArgs: Parameters<typeof getFieldsToSign>[0] = {\n collectionConfig,\n email: sanitizedEmail!,\n user,\n }\n\n const session = await addSessionToUser({\n collectionConfig,\n payload,\n req,\n user,\n })\n sid = session.sid\n\n if (sid) {\n fieldsToSignArgs.sid = sid\n }\n\n const fieldsToSign = getFieldsToSign(fieldsToSignArgs)\n\n if (maxLoginAttemptsEnabled) {\n await resetLoginAttempts({\n collection: collectionConfig,\n doc: user,\n payload: req.payload,\n req,\n })\n }\n\n // /////////////////////////////////////\n // beforeLogin - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeLogin?.length) {\n for (const hook of collectionConfig.hooks.beforeLogin) {\n user =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n user,\n })) || user\n }\n }\n\n const { exp, token } = await jwtSign({\n fieldsToSign,\n secret,\n tokenExpiration: collectionConfig.auth.tokenExpiration,\n })\n\n req.user = user\n\n // /////////////////////////////////////\n // afterLogin - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterLogin?.length) {\n for (const hook of collectionConfig.hooks.afterLogin) {\n user =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n token,\n user,\n })) || user\n }\n }\n\n // /////////////////////////////////////\n // afterRead - Fields\n // /////////////////////////////////////\n\n user = await afterRead({\n collection: collectionConfig,\n context: req.context,\n depth: depth!,\n doc: user,\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n draft: undefined,\n fallbackLocale: fallbackLocale!,\n global: null,\n locale: locale!,\n overrideAccess,\n req,\n showHiddenFields: showHiddenFields!,\n })\n\n // /////////////////////////////////////\n // afterRead - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterRead?.length) {\n for (const hook of collectionConfig.hooks.afterRead) {\n user =\n (await hook({\n collection: args.collection?.config,\n context: req.context,\n doc: user,\n overrideAccess,\n req,\n })) || user\n }\n }\n\n let result: LoginResult<TSlug> = {\n exp,\n token,\n user,\n }\n\n // /////////////////////////////////////\n // afterOperation - Collection\n // /////////////////////////////////////\n\n result = await buildAfterOperation({\n args,\n collection: args.collection?.config,\n operation: 'login',\n overrideAccess: args.overrideAccess!,\n result,\n })\n\n if (shouldCommit) {\n await commitTransaction(req)\n }\n\n // /////////////////////////////////////\n // Return results\n // /////////////////////////////////////\n\n return result\n } catch (error: unknown) {\n if (sid) {\n await revokeSession({\n collectionConfig,\n payload,\n req,\n sid,\n user,\n })\n }\n await killTransaction(args.req)\n throw error\n }\n}\n"],"names":["buildAfterOperation","buildBeforeOperation","AuthenticationError","LockedAuth","UnverifiedEmail","ValidationError","afterRead","commitTransaction","Forbidden","initTransaction","appendNonTrashedFilter","killTransaction","sanitizeInternalFields","getFieldsToSign","getLoginOptions","isUserLocked","jwtSign","addSessionToUser","revokeSession","authenticateLocalStrategy","incrementLoginAttempts","resetLoginAttempts","checkLoginPermission","loggingInWithUsername","req","user","t","Boolean","Date","lockUntil","loginOperation","incomingArgs","args","collection","config","auth","disableLocalStrategy","operation","overrideAccess","collectionConfig","data","depth","fallbackLocale","locale","payload","secret","showHiddenFields","email","unsanitizedEmail","password","loginWithUsername","sanitizedEmail","toLowerCase","trim","sanitizedUsername","username","canLoginWithEmail","canLoginWithUsername","slug","errors","message","i18n","path","whereConstraint","emailConstraint","equals","usernameConstraint","or","enableTrash","trash","where","db","findOne","_strategy","authResult","doc","maxLoginAttemptsEnabled","maxLoginAttempts","verify","_verified","shouldCommit","sid","loginAttempts","select","id","fieldsToSignArgs","session","fieldsToSign","hooks","beforeLogin","length","hook","context","exp","token","tokenExpiration","afterLogin","draft","undefined","global","result","error"],"mappings":"AAQA,SAASA,mBAAmB,QAAQ,gEAA+D;AACnG,SAASC,oBAAoB,QAAQ,iEAAgE;AACrG,SACEC,mBAAmB,EACnBC,UAAU,EACVC,eAAe,EACfC,eAAe,QACV,wBAAuB;AAC9B,SAASC,SAAS,QAAQ,wCAAuC;AACjE,SAASC,iBAAiB,EAAEC,SAAS,EAAEC,eAAe,QAAQ,iBAAgB;AAC9E,SAASC,sBAAsB,QAAQ,4CAA2C;AAClF,SAASC,eAAe,QAAQ,qCAAoC;AACpE,SAASC,sBAAsB,QAAQ,4CAA2C;AAClF,SAASC,eAAe,QAAQ,wBAAuB;AACvD,SAASC,eAAe,QAAQ,wBAAuB;AACvD,SAASC,YAAY,QAAQ,qBAAoB;AACjD,SAASC,OAAO,QAAQ,YAAW;AACnC,SAASC,gBAAgB,EAAEC,aAAa,QAAQ,iBAAgB;AAChE,SAASC,yBAAyB,QAAQ,sCAAqC;AAC/E,SAASC,sBAAsB,QAAQ,gDAA+C;AACtF,SAASC,kBAAkB,QAAQ,4CAA2C;AAuB9E;;;;CAIC,GACD,OAAO,MAAMC,uBAAuB,CAAmC,EACrEC,qBAAqB,EACrBC,GAAG,EACHC,IAAI,EAC4B;IAChC,IAAI,CAACA,MAAM;QACT,MAAM,IAAIvB,oBAAoBsB,IAAIE,CAAC,EAAEC,QAAQJ;IAC/C;IAEA,IAAIR,aAAa,IAAIa,KAAKH,KAAKI,SAAS,IAAI;QAC1C,MAAM,IAAI1B,WAAWqB,IAAIE,CAAC;IAC5B;AACF,EAAC;AAED,OAAO,MAAMI,iBAAiB,OAC5BC;IAEA,IAAIC,OAAOD;IAEX,IAAIC,KAAKC,UAAU,CAACC,MAAM,CAACC,IAAI,CAACC,oBAAoB,EAAE;QACpD,MAAM,IAAI5B,UAAUwB,KAAKR,GAAG,CAACE,CAAC;IAChC;IAEA,wCAAwC;IACxC,+BAA+B;IAC/B,wCAAwC;IAExCM,OAAO,MAAM/B,qBAAqB;QAChC+B;QACAC,YAAYD,KAAKC,UAAU,CAACC,MAAM;QAClCG,WAAW;QACXC,gBAAgBN,KAAKM,cAAc;IACrC;IAEA,MAAM,EACJL,YAAY,EAAEC,QAAQK,gBAAgB,EAAE,EACxCC,IAAI,EACJC,KAAK,EACLH,iBAAiB,KAAK,EACtBd,GAAG,EACHA,KAAK,EACHkB,cAAc,EACdC,MAAM,EACNC,OAAO,EACPA,SAAS,EAAEC,MAAM,EAAE,EACpB,EACDC,gBAAgB,EACjB,GAAGd;IAEJ,wCAAwC;IACxC,QAAQ;IACR,wCAAwC;IAExC,MAAM,EAAEe,OAAOC,gBAAgB,EAAEC,QAAQ,EAAE,GAAGT;IAC9C,MAAMU,oBAAoBX,iBAAiBJ,IAAI,CAACe,iBAAiB;IAEjE,MAAMC,iBACJ,OAAOH,qBAAqB,WAAWA,iBAAiBI,WAAW,GAAGC,IAAI,KAAK;IACjF,MAAMC,oBACJ,cAAcd,QAAQ,OAAOA,MAAMe,aAAa,WAC5Cf,KAAKe,QAAQ,CAACH,WAAW,GAAGC,IAAI,KAChC;IAEN,MAAM,EAAEG,iBAAiB,EAAEC,oBAAoB,EAAE,GAAG3C,gBAAgBoC;IAEpE,oDAAoD;IACpD,IAAI,CAACM,qBAAqB,CAACF,mBAAmB;QAC5C,MAAM,IAAIjD,gBAAgB;YACxB4B,YAAYM,iBAAiBmB,IAAI;YACjCC,QAAQ;gBAAC;oBAAEC,SAASpC,IAAIqC,IAAI,CAACnC,CAAC,CAAC;oBAAwBoC,MAAM;gBAAW;aAAE;QAC5E;IACF;IAEA,oDAAoD;IACpD,IAAI,CAACL,wBAAwB,CAACN,gBAAgB;QAC5C,MAAM,IAAI9C,gBAAgB;YACxB4B,YAAYM,iBAAiBmB,IAAI;YACjCC,QAAQ;gBAAC;oBAAEC,SAASpC,IAAIqC,IAAI,CAACnC,CAAC,CAAC;oBAAwBoC,MAAM;gBAAQ;aAAE;QACzE;IACF;IAEA,kEAAkE;IAClE,IAAI,CAACR,qBAAqB,CAACH,gBAAgB;QACzC,MAAM,IAAI9C,gBAAgB;YACxB4B,YAAYM,iBAAiBmB,IAAI;YACjCC,QAAQ;gBACN;oBAAEC,SAASpC,IAAIqC,IAAI,CAACnC,CAAC,CAAC;oBAAwBoC,MAAM;gBAAQ;gBAC5D;oBAAEF,SAASpC,IAAIqC,IAAI,CAACnC,CAAC,CAAC;oBAAwBoC,MAAM;gBAAW;aAChE;QACH;IACF;IAEA,qCAAqC;IACrC,IAAI,OAAOb,aAAa,YAAYA,SAASI,IAAI,OAAO,IAAI;QAC1D,MAAM,IAAIhD,gBAAgB;YACxB4B,YAAYM,iBAAiBmB,IAAI;YACjCC,QAAQ;gBAAC;oBAAEC,SAASpC,IAAIqC,IAAI,CAACnC,CAAC,CAAC;oBAAwBoC,MAAM;gBAAW;aAAE;QAC5E;IACF;IAEA,IAAIC,kBAAyB,CAAC;IAC9B,MAAMC,kBAAyB;QAC7BjB,OAAO;YACLkB,QAAQd;QACV;IACF;IACA,MAAMe,qBAA4B;QAChCX,UAAU;YACRU,QAAQX;QACV;IACF;IAEA,IAAIE,qBAAqBC,wBAAyBH,CAAAA,qBAAqBH,cAAa,GAAI;QACtF,IAAIG,mBAAmB;YACrBS,kBAAkB;gBAChBI,IAAI;oBACFD;oBACA;wBACEnB,OAAO;4BACLkB,QAAQX;wBACV;oBACF;iBACD;YACH;QACF,OAAO;YACLS,kBAAkB;gBAChBI,IAAI;oBACFH;oBACA;wBACET,UAAU;4BACRU,QAAQd;wBACV;oBACF;iBACD;YACH;QACF;IACF,OAAO,IAAIK,qBAAqBL,gBAAgB;QAC9CY,kBAAkBC;IACpB,OAAO,IAAIP,wBAAwBH,mBAAmB;QACpDS,kBAAkBG;IACpB;IAEA,wBAAwB;IACxBH,kBAAkBrD,uBAAuB;QACvC0D,aAAa7B,iBAAiB8B,KAAK;QACnCA,OAAO;QACPC,OAAOP;IACT;IAEA,IAAItC,OAAQ,MAAMmB,QAAQ2B,EAAE,CAACC,OAAO,CAAY;QAC9CvC,YAAYM,iBAAiBmB,IAAI;QACjClC;QACA8C,OAAOP;IACT;IAEAzC,qBAAqB;QACnBC,uBAAuBI,QAAQ8B,wBAAwBH;QACvD9B;QACAC;IACF;IAEAA,KAAKQ,UAAU,GAAGM,iBAAiBmB,IAAI;IACvCjC,KAAKgD,SAAS,GAAG;IAEjB,MAAMC,aAAa,MAAMvD,0BAA0B;QAAEwD,KAAKlD;QAAMwB;IAAS;IACzExB,OAAOb,uBAAuBa;IAE9B,MAAMmD,0BAA0B5C,KAAKC,UAAU,CAACC,MAAM,CAACC,IAAI,CAAC0C,gBAAgB,GAAG;IAE/E,IAAI,CAACH,YAAY;QACf,IAAIE,yBAAyB;YAC3B,MAAMxD,uBAAuB;gBAC3Ba,YAAYM;gBACZK,SAASpB,IAAIoB,OAAO;gBACpBnB;YACF;YAEA,6GAA6G;YAC7GH,qBAAqB;gBACnBC,uBAAuBI,QAAQ8B,wBAAwBH;gBACvD9B;gBACAC;YACF;QACF;QAEA,MAAM,IAAIvB,oBAAoBsB,IAAIE,CAAC;IACrC;IAEA,IAAIa,iBAAiBJ,IAAI,CAAC2C,MAAM,IAAIrD,KAAKsD,SAAS,KAAK,OAAO;QAC5D,MAAM,IAAI3E,gBAAgB;YAAEsB,GAAGF,IAAIE,CAAC;QAAC;IACvC;IAEA,yEAAyE;IACzE,MAAMsD,eAAe,MAAMvE,gBAAgBuB,KAAKR,GAAG;IACnD,IAAIyD;IAEJ,IAAI;QACF;;;KAGC,GACD,IAAIL,yBAAyB;YAC3B,MAAM,EAAE/C,SAAS,EAAEqD,aAAa,EAAE,GAAI,MAAMtC,QAAQ2B,EAAE,CAACC,OAAO,CAAY;gBACxEvC,YAAYM,iBAAiBmB,IAAI;gBACjClC;gBACA2D,QAAQ;oBACNtD,WAAW;oBACXqD,eAAe;gBACjB;gBACAZ,OAAO;oBAAEc,IAAI;wBAAEnB,QAAQxC,KAAK2D,EAAE;oBAAC;gBAAE;YACnC;YAEA3D,KAAKI,SAAS,GAAGA;YACjBJ,KAAKyD,aAAa,GAAGA;YAErB5D,qBAAqB;gBACnBE;gBACAC;YACF;QACF;QAEA,MAAM4D,mBAA0D;YAC9D9C;YACAQ,OAAOI;YACP1B;QACF;QAEA,MAAM6D,UAAU,MAAMrE,iBAAiB;YACrCsB;YACAK;YACApB;YACAC;QACF;QACAwD,MAAMK,QAAQL,GAAG;QAEjB,IAAIA,KAAK;YACPI,iBAAiBJ,GAAG,GAAGA;QACzB;QAEA,MAAMM,eAAe1E,gBAAgBwE;QAErC,IAAIT,yBAAyB;YAC3B,MAAMvD,mBAAmB;gBACvBY,YAAYM;gBACZoC,KAAKlD;gBACLmB,SAASpB,IAAIoB,OAAO;gBACpBpB;YACF;QACF;QAEA,wCAAwC;QACxC,2BAA2B;QAC3B,wCAAwC;QAExC,IAAIe,iBAAiBiD,KAAK,EAAEC,aAAaC,QAAQ;YAC/C,KAAK,MAAMC,QAAQpD,iBAAiBiD,KAAK,CAACC,WAAW,CAAE;gBACrDhE,OACE,AAAC,MAAMkE,KAAK;oBACV1D,YAAYD,KAAKC,UAAU,EAAEC;oBAC7B0D,SAAS5D,KAAKR,GAAG,CAACoE,OAAO;oBACzBpE,KAAKQ,KAAKR,GAAG;oBACbC;gBACF,MAAOA;YACX;QACF;QAEA,MAAM,EAAEoE,GAAG,EAAEC,KAAK,EAAE,GAAG,MAAM9E,QAAQ;YACnCuE;YACA1C;YACAkD,iBAAiBxD,iBAAiBJ,IAAI,CAAC4D,eAAe;QACxD;QAEAvE,IAAIC,IAAI,GAAGA;QAEX,wCAAwC;QACxC,0BAA0B;QAC1B,wCAAwC;QAExC,IAAIc,iBAAiBiD,KAAK,EAAEQ,YAAYN,QAAQ;YAC9C,KAAK,MAAMC,QAAQpD,iBAAiBiD,KAAK,CAACQ,UAAU,CAAE;gBACpDvE,OACE,AAAC,MAAMkE,KAAK;oBACV1D,YAAYD,KAAKC,UAAU,EAAEC;oBAC7B0D,SAAS5D,KAAKR,GAAG,CAACoE,OAAO;oBACzBpE,KAAKQ,KAAKR,GAAG;oBACbsE;oBACArE;gBACF,MAAOA;YACX;QACF;QAEA,wCAAwC;QACxC,qBAAqB;QACrB,wCAAwC;QAExCA,OAAO,MAAMnB,UAAU;YACrB2B,YAAYM;YACZqD,SAASpE,IAAIoE,OAAO;YACpBnD,OAAOA;YACPkC,KAAKlD;YACL,oFAAoF;YACpFwE,OAAOC;YACPxD,gBAAgBA;YAChByD,QAAQ;YACRxD,QAAQA;YACRL;YACAd;YACAsB,kBAAkBA;QACpB;QAEA,wCAAwC;QACxC,yBAAyB;QACzB,wCAAwC;QAExC,IAAIP,iBAAiBiD,KAAK,EAAElF,WAAWoF,QAAQ;YAC7C,KAAK,MAAMC,QAAQpD,iBAAiBiD,KAAK,CAAClF,SAAS,CAAE;gBACnDmB,OACE,AAAC,MAAMkE,KAAK;oBACV1D,YAAYD,KAAKC,UAAU,EAAEC;oBAC7B0D,SAASpE,IAAIoE,OAAO;oBACpBjB,KAAKlD;oBACLa;oBACAd;gBACF,MAAOC;YACX;QACF;QAEA,IAAI2E,SAA6B;YAC/BP;YACAC;YACArE;QACF;QAEA,wCAAwC;QACxC,8BAA8B;QAC9B,wCAAwC;QAExC2E,SAAS,MAAMpG,oBAAoB;YACjCgC;YACAC,YAAYD,KAAKC,UAAU,EAAEC;YAC7BG,WAAW;YACXC,gBAAgBN,KAAKM,cAAc;YACnC8D;QACF;QAEA,IAAIpB,cAAc;YAChB,MAAMzE,kBAAkBiB;QAC1B;QAEA,wCAAwC;QACxC,iBAAiB;QACjB,wCAAwC;QAExC,OAAO4E;IACT,EAAE,OAAOC,OAAgB;QACvB,IAAIpB,KAAK;YACP,MAAM/D,cAAc;gBAClBqB;gBACAK;gBACApB;gBACAyD;gBACAxD;YACF;QACF;QACA,MAAMd,gBAAgBqB,KAAKR,GAAG;QAC9B,MAAM6E;IACR;AACF,EAAC"}
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/operations/login.ts"],"sourcesContent":["import type {\n AuthOperationsFromCollectionSlug,\n Collection,\n DataFromCollectionSlug,\n} from '../../collections/config/types.js'\nimport type { AuthCollectionSlug, AuthenticatedUser, User } from '../../index.js'\nimport type { PayloadRequest, Where } from '../../types/index.js'\nimport type { AuthRuntimeFields } from '../types.js'\n\nimport { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'\nimport { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'\nimport {\n AuthenticationError,\n LockedAuth,\n UnverifiedEmail,\n ValidationError,\n} from '../../errors/index.js'\nimport { afterRead } from '../../fields/hooks/afterRead/index.js'\nimport { commitTransaction, Forbidden, initTransaction } from '../../index.js'\nimport { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { sanitizeInternalFields } from '../../utilities/sanitizeInternalFields.js'\nimport { getFieldsToSign } from '../getFieldsToSign.js'\nimport { getLoginOptions } from '../getLoginOptions.js'\nimport { isUserLocked } from '../isUserLocked.js'\nimport { jwtSign } from '../jwt.js'\nimport { addSessionToUser, revokeSession } from '../sessions.js'\nimport { authenticateLocalStrategy } from '../strategies/local/authenticate.js'\nimport { incrementLoginAttempts } from '../strategies/local/incrementLoginAttempts.js'\nimport { resetLoginAttempts } from '../strategies/local/resetLoginAttempts.js'\n\nexport type LoginResult<TSlug extends AuthCollectionSlug> = {\n exp?: number\n token?: string\n user?: AuthRuntimeFields & DataFromCollectionSlug<TSlug>\n}\n\nexport type Arguments<TSlug extends AuthCollectionSlug> = {\n collection: Collection\n data: AuthOperationsFromCollectionSlug<TSlug>['login']\n depth?: number\n overrideAccess?: boolean\n req: PayloadRequest\n showHiddenFields?: boolean\n}\n\ntype CheckLoginPermissionArgs<TSlug extends AuthCollectionSlug> = {\n loggingInWithUsername?: boolean\n req: PayloadRequest\n user: DataFromCollectionSlug<TSlug>\n}\n\n/**\n * Throws an error if the user is locked or does not exist.\n * This does not check the login attempts, only the lock status. Whoever increments login attempts\n * is responsible for locking the user properly, not whoever checks the login permission.\n */\nexport const checkLoginPermission = <TSlug extends AuthCollectionSlug>({\n loggingInWithUsername,\n req,\n user,\n}: CheckLoginPermissionArgs<TSlug>) => {\n if (!user) {\n throw new AuthenticationError(req.t, Boolean(loggingInWithUsername))\n }\n\n if (isUserLocked(new Date(user.lockUntil))) {\n throw new LockedAuth(req.t)\n }\n}\n\nexport const loginOperation = async <TSlug extends AuthCollectionSlug>(\n incomingArgs: Arguments<TSlug>,\n): Promise<LoginResult<TSlug>> => {\n let args = incomingArgs\n\n if (args.collection.config.auth.disableLocalStrategy) {\n throw new Forbidden(args.req.t)\n }\n\n // /////////////////////////////////////\n // beforeOperation - Collection\n // /////////////////////////////////////\n\n args = await buildBeforeOperation({\n args,\n collection: args.collection.config,\n operation: 'login',\n overrideAccess: args.overrideAccess!,\n })\n\n const {\n collection: { config: collectionConfig },\n data,\n depth,\n overrideAccess = false,\n req,\n req: {\n fallbackLocale,\n locale,\n payload,\n payload: { secret },\n },\n showHiddenFields,\n } = args\n\n // /////////////////////////////////////\n // Login\n // /////////////////////////////////////\n\n const { email: unsanitizedEmail, password } = data\n const loginWithUsername = collectionConfig.auth.loginWithUsername\n\n const sanitizedEmail =\n typeof unsanitizedEmail === 'string' ? unsanitizedEmail.toLowerCase().trim() : null\n const sanitizedUsername =\n 'username' in data && typeof data?.username === 'string'\n ? data.username.toLowerCase().trim()\n : null\n\n const { canLoginWithEmail, canLoginWithUsername } = getLoginOptions(loginWithUsername)\n\n // cannot login with email, did not provide username\n if (!canLoginWithEmail && !sanitizedUsername) {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [{ message: req.i18n.t('validation:required'), path: 'username' }],\n })\n }\n\n // cannot login with username, did not provide email\n if (!canLoginWithUsername && !sanitizedEmail) {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [{ message: req.i18n.t('validation:required'), path: 'email' }],\n })\n }\n\n // can login with either email or username, did not provide either\n if (!sanitizedUsername && !sanitizedEmail) {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [\n { message: req.i18n.t('validation:required'), path: 'email' },\n { message: req.i18n.t('validation:required'), path: 'username' },\n ],\n })\n }\n\n // did not provide password for login\n if (typeof password !== 'string' || password.trim() === '') {\n throw new ValidationError({\n collection: collectionConfig.slug,\n errors: [{ message: req.i18n.t('validation:required'), path: 'password' }],\n })\n }\n\n let whereConstraint: Where = {}\n const emailConstraint: Where = {\n email: {\n equals: sanitizedEmail,\n },\n }\n const usernameConstraint: Where = {\n username: {\n equals: sanitizedUsername,\n },\n }\n\n if (canLoginWithEmail && canLoginWithUsername && (sanitizedUsername || sanitizedEmail)) {\n if (sanitizedUsername) {\n whereConstraint = {\n or: [\n usernameConstraint,\n {\n email: {\n equals: sanitizedUsername,\n },\n },\n ],\n }\n } else {\n whereConstraint = {\n or: [\n emailConstraint,\n {\n username: {\n equals: sanitizedEmail,\n },\n },\n ],\n }\n }\n } else if (canLoginWithEmail && sanitizedEmail) {\n whereConstraint = emailConstraint\n } else if (canLoginWithUsername && sanitizedUsername) {\n whereConstraint = usernameConstraint\n }\n\n // Exclude trashed users\n whereConstraint = appendNonTrashedFilter({\n enableTrash: collectionConfig.trash,\n trash: false,\n where: whereConstraint,\n })\n\n let user = (await payload.db.findOne<User>({\n collection: collectionConfig.slug,\n req,\n where: whereConstraint,\n })) as AuthenticatedUser\n\n checkLoginPermission({\n loggingInWithUsername: Boolean(canLoginWithUsername && sanitizedUsername),\n req,\n user,\n })\n\n user.collection = collectionConfig.slug\n user._strategy = 'local-jwt'\n\n const authResult = await authenticateLocalStrategy({ doc: user, password })\n user = sanitizeInternalFields(user)\n\n const maxLoginAttemptsEnabled = args.collection.config.auth.maxLoginAttempts > 0\n\n if (!authResult) {\n if (maxLoginAttemptsEnabled) {\n await incrementLoginAttempts({\n collection: collectionConfig,\n payload: req.payload,\n user,\n })\n\n // Re-check login permissions and max attempts after incrementing attempts, in case parallel updates occurred\n checkLoginPermission({\n loggingInWithUsername: Boolean(canLoginWithUsername && sanitizedUsername),\n req,\n user,\n })\n }\n\n throw new AuthenticationError(req.t)\n }\n\n if (collectionConfig.auth.verify && user._verified === false) {\n throw new UnverifiedEmail({ t: req.t })\n }\n\n // Authentication successful - start transaction for remaining operations\n const shouldCommit = await initTransaction(args.req)\n let sid: string | undefined\n\n try {\n /*\n * Correct password accepted - re‑check that the account didn't\n * get locked by parallel bad attempts in the meantime.\n */\n if (maxLoginAttemptsEnabled) {\n const { lockUntil, loginAttempts } = (await payload.db.findOne<User>({\n collection: collectionConfig.slug,\n req,\n select: {\n lockUntil: true,\n loginAttempts: true,\n },\n where: { id: { equals: user.id } },\n }))!\n\n user.lockUntil = lockUntil\n user.loginAttempts = loginAttempts\n\n checkLoginPermission({\n req,\n user,\n })\n }\n\n const fieldsToSignArgs: Parameters<typeof getFieldsToSign>[0] = {\n collectionConfig,\n email: sanitizedEmail!,\n user,\n }\n\n const session = await addSessionToUser({\n collectionConfig,\n payload,\n req,\n user,\n })\n sid = session.sid\n\n if (sid) {\n fieldsToSignArgs.sid = sid\n }\n\n const fieldsToSign = getFieldsToSign(fieldsToSignArgs)\n\n if (maxLoginAttemptsEnabled) {\n await resetLoginAttempts({\n collection: collectionConfig,\n doc: user,\n payload: req.payload,\n req,\n })\n }\n\n // /////////////////////////////////////\n // beforeLogin - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeLogin?.length) {\n for (const hook of collectionConfig.hooks.beforeLogin) {\n user =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n user,\n })) || user\n }\n }\n\n const { exp, token } = await jwtSign({\n fieldsToSign,\n secret,\n tokenExpiration: collectionConfig.auth.tokenExpiration,\n })\n\n req.user = user\n\n // /////////////////////////////////////\n // afterLogin - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterLogin?.length) {\n for (const hook of collectionConfig.hooks.afterLogin) {\n user =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n token,\n user,\n })) || user\n }\n }\n\n // /////////////////////////////////////\n // afterRead - Fields\n // /////////////////////////////////////\n\n user = await afterRead({\n collection: collectionConfig,\n context: req.context,\n depth: depth!,\n doc: user,\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n draft: undefined,\n fallbackLocale: fallbackLocale!,\n global: null,\n locale: locale!,\n overrideAccess,\n req,\n showHiddenFields: showHiddenFields!,\n })\n\n // /////////////////////////////////////\n // afterRead - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterRead?.length) {\n for (const hook of collectionConfig.hooks.afterRead) {\n user =\n (await hook({\n collection: args.collection?.config,\n context: req.context,\n doc: user,\n overrideAccess,\n req,\n })) || user\n }\n }\n\n let result: LoginResult<TSlug> = {\n exp,\n token,\n user,\n }\n\n // /////////////////////////////////////\n // afterOperation - Collection\n // /////////////////////////////////////\n\n result = await buildAfterOperation({\n args,\n collection: args.collection?.config,\n operation: 'login',\n overrideAccess: args.overrideAccess!,\n result,\n })\n\n if (shouldCommit) {\n await commitTransaction(req)\n }\n\n // /////////////////////////////////////\n // Return results\n // /////////////////////////////////////\n\n return result\n } catch (error: unknown) {\n if (sid) {\n await revokeSession({\n collectionConfig,\n payload,\n req,\n sid,\n user,\n })\n }\n await killTransaction(args.req)\n throw error\n }\n}\n"],"names":["buildAfterOperation","buildBeforeOperation","AuthenticationError","LockedAuth","UnverifiedEmail","ValidationError","afterRead","commitTransaction","Forbidden","initTransaction","appendNonTrashedFilter","killTransaction","sanitizeInternalFields","getFieldsToSign","getLoginOptions","isUserLocked","jwtSign","addSessionToUser","revokeSession","authenticateLocalStrategy","incrementLoginAttempts","resetLoginAttempts","checkLoginPermission","loggingInWithUsername","req","user","t","Boolean","Date","lockUntil","loginOperation","incomingArgs","args","collection","config","auth","disableLocalStrategy","operation","overrideAccess","collectionConfig","data","depth","fallbackLocale","locale","payload","secret","showHiddenFields","email","unsanitizedEmail","password","loginWithUsername","sanitizedEmail","toLowerCase","trim","sanitizedUsername","username","canLoginWithEmail","canLoginWithUsername","slug","errors","message","i18n","path","whereConstraint","emailConstraint","equals","usernameConstraint","or","enableTrash","trash","where","db","findOne","_strategy","authResult","doc","maxLoginAttemptsEnabled","maxLoginAttempts","verify","_verified","shouldCommit","sid","loginAttempts","select","id","fieldsToSignArgs","session","fieldsToSign","hooks","beforeLogin","length","hook","context","exp","token","tokenExpiration","afterLogin","draft","undefined","global","result","error"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/operations/me.ts"],"sourcesContent":["import { decodeJwt } from 'jose'\n\nimport type { Collection } from '../../collections/config/types.js'\nimport type {
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/operations/me.ts"],"sourcesContent":["import { decodeJwt } from 'jose'\n\nimport type { Collection } from '../../collections/config/types.js'\nimport type { AuthenticatedUser } from '../../index.js'\nimport type { JoinQuery, PayloadRequest, PopulateType, SelectType } from '../../types/index.js'\nimport type { ClientUser } from '../types.js'\n\nexport type MeOperationResult = {\n collection?: string\n exp?: number\n /** @deprecated\n * use:\n * ```ts\n * user._strategy\n * ```\n */\n strategy?: string\n token?: string\n user?: ClientUser\n}\n\nexport type Arguments = {\n collection: Collection\n currentToken?: string\n depth?: number\n draft?: boolean\n joins?: JoinQuery\n populate?: PopulateType\n req: PayloadRequest\n select?: SelectType\n}\n\nexport const meOperation = async (args: Arguments): Promise<MeOperationResult> => {\n const { collection, currentToken, depth, draft, joins, populate, req, select } = args\n\n let result: MeOperationResult = {\n user: null!,\n }\n\n if (req.user) {\n if (req.user.collection !== collection.config.slug) {\n return {\n user: null!,\n }\n }\n\n const { pathname } = req\n const isGraphQL = pathname === `/api${req.payload.config.routes.graphQL}`\n\n const user = (await req.payload.findByID({\n id: req.user.id,\n collection: collection.config.slug,\n depth: isGraphQL ? 0 : (depth ?? collection.config.auth.depth),\n draft,\n joins,\n overrideAccess: false,\n populate,\n req,\n select,\n showHiddenFields: false,\n })) as AuthenticatedUser\n\n if (user) {\n user.collection = collection.config.slug\n user._strategy = req.user._strategy\n }\n\n // /////////////////////////////////////\n // me hook - Collection\n // /////////////////////////////////////\n\n for (const meHook of collection.config.hooks.me) {\n const hookResult = await meHook({ args, user })\n\n if (hookResult) {\n result.user = hookResult.user\n result.exp = hookResult.exp\n\n break\n }\n }\n\n result.collection = req.user.collection\n /** @deprecated\n * use:\n * ```ts\n * user._strategy\n * ```\n */\n result.strategy = req.user._strategy\n\n if (!result.user) {\n result.user = user\n\n if (currentToken) {\n const decoded = decodeJwt(currentToken)\n if (decoded) {\n result.exp = decoded.exp\n }\n if (!collection.config.auth.removeTokenFromResponses) {\n result.token = currentToken\n }\n }\n }\n }\n\n // /////////////////////////////////////\n // After Me - Collection\n // /////////////////////////////////////\n\n if (collection.config.hooks?.afterMe?.length) {\n for (const hook of collection.config.hooks.afterMe) {\n result =\n (await hook({\n collection: collection?.config,\n context: req.context,\n req,\n response: result,\n })) || result\n }\n }\n\n return result\n}\n"],"names":["decodeJwt","meOperation","args","collection","currentToken","depth","draft","joins","populate","req","select","result","user","config","slug","pathname","isGraphQL","payload","routes","graphQL","findByID","id","auth","overrideAccess","showHiddenFields","_strategy","meHook","hooks","me","hookResult","exp","strategy","decoded","removeTokenFromResponses","token","afterMe","length","hook","context","response"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAM;AAgChC,OAAO,MAAMC,cAAc,OAAOC;IAChC,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAEC,KAAK,EAAEC,KAAK,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,MAAM,EAAE,GAAGR;IAEjF,IAAIS,SAA4B;QAC9BC,MAAM;IACR;IAEA,IAAIH,IAAIG,IAAI,EAAE;QACZ,IAAIH,IAAIG,IAAI,CAACT,UAAU,KAAKA,WAAWU,MAAM,CAACC,IAAI,EAAE;YAClD,OAAO;gBACLF,MAAM;YACR;QACF;QAEA,MAAM,EAAEG,QAAQ,EAAE,GAAGN;QACrB,MAAMO,YAAYD,aAAa,CAAC,IAAI,EAAEN,IAAIQ,OAAO,CAACJ,MAAM,CAACK,MAAM,CAACC,OAAO,EAAE;QAEzE,MAAMP,OAAQ,MAAMH,IAAIQ,OAAO,CAACG,QAAQ,CAAC;YACvCC,IAAIZ,IAAIG,IAAI,CAACS,EAAE;YACflB,YAAYA,WAAWU,MAAM,CAACC,IAAI;YAClCT,OAAOW,YAAY,IAAKX,SAASF,WAAWU,MAAM,CAACS,IAAI,CAACjB,KAAK;YAC7DC;YACAC;YACAgB,gBAAgB;YAChBf;YACAC;YACAC;YACAc,kBAAkB;QACpB;QAEA,IAAIZ,MAAM;YACRA,KAAKT,UAAU,GAAGA,WAAWU,MAAM,CAACC,IAAI;YACxCF,KAAKa,SAAS,GAAGhB,IAAIG,IAAI,CAACa,SAAS;QACrC;QAEA,wCAAwC;QACxC,uBAAuB;QACvB,wCAAwC;QAExC,KAAK,MAAMC,UAAUvB,WAAWU,MAAM,CAACc,KAAK,CAACC,EAAE,CAAE;YAC/C,MAAMC,aAAa,MAAMH,OAAO;gBAAExB;gBAAMU;YAAK;YAE7C,IAAIiB,YAAY;gBACdlB,OAAOC,IAAI,GAAGiB,WAAWjB,IAAI;gBAC7BD,OAAOmB,GAAG,GAAGD,WAAWC,GAAG;gBAE3B;YACF;QACF;QAEAnB,OAAOR,UAAU,GAAGM,IAAIG,IAAI,CAACT,UAAU;QACvC;;;;;KAKC,GACDQ,OAAOoB,QAAQ,GAAGtB,IAAIG,IAAI,CAACa,SAAS;QAEpC,IAAI,CAACd,OAAOC,IAAI,EAAE;YAChBD,OAAOC,IAAI,GAAGA;YAEd,IAAIR,cAAc;gBAChB,MAAM4B,UAAUhC,UAAUI;gBAC1B,IAAI4B,SAAS;oBACXrB,OAAOmB,GAAG,GAAGE,QAAQF,GAAG;gBAC1B;gBACA,IAAI,CAAC3B,WAAWU,MAAM,CAACS,IAAI,CAACW,wBAAwB,EAAE;oBACpDtB,OAAOuB,KAAK,GAAG9B;gBACjB;YACF;QACF;IACF;IAEA,wCAAwC;IACxC,wBAAwB;IACxB,wCAAwC;IAExC,IAAID,WAAWU,MAAM,CAACc,KAAK,EAAEQ,SAASC,QAAQ;QAC5C,KAAK,MAAMC,QAAQlC,WAAWU,MAAM,CAACc,KAAK,CAACQ,OAAO,CAAE;YAClDxB,SACE,AAAC,MAAM0B,KAAK;gBACVlC,YAAYA,YAAYU;gBACxByB,SAAS7B,IAAI6B,OAAO;gBACpB7B;gBACA8B,UAAU5B;YACZ,MAAOA;QACX;IACF;IAEA,OAAOA;AACT,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/auth/operations/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/auth/operations/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAYpE,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,UAAU,CAAA;IACtB,GAAG,EAAE,cAAc,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAU,cAAc,SAAS,KAAG,OAAO,CAAC,MAAM,CAgL9E,CAAA"}
|
|
@@ -38,23 +38,29 @@ export const refreshOperation = async (incomingArgs)=>{
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
|
+
if (!user) {
|
|
42
|
+
throw new Forbidden(args.req.t);
|
|
43
|
+
}
|
|
41
44
|
const sid = args.req.user._sid;
|
|
42
45
|
if (collectionConfig.auth.useSessions && !collectionConfig.auth.disableLocalStrategy) {
|
|
43
46
|
if (!Array.isArray(user.sessions) || !sid) {
|
|
44
47
|
throw new Forbidden(args.req.t);
|
|
45
48
|
}
|
|
46
49
|
const existingSession = user.sessions.find(({ id })=>id === sid);
|
|
50
|
+
if (!existingSession) {
|
|
51
|
+
throw new Forbidden(args.req.t);
|
|
52
|
+
}
|
|
47
53
|
const now = new Date();
|
|
48
54
|
const tokenExpInMs = collectionConfig.auth.tokenExpiration * 1000;
|
|
49
55
|
existingSession.expiresAt = new Date(now.getTime() + tokenExpInMs);
|
|
50
|
-
// Prevent updatedAt from being updated when only refreshing a session
|
|
51
|
-
user.updatedAt = null;
|
|
52
56
|
await req.payload.db.updateOne({
|
|
53
57
|
id: user.id,
|
|
54
58
|
collection: collectionConfig.slug,
|
|
55
59
|
data: {
|
|
56
60
|
...user,
|
|
57
|
-
|
|
61
|
+
// Prevent updatedAt from being updated when only refreshing a session
|
|
62
|
+
sessions: removeExpiredSessions(user.sessions),
|
|
63
|
+
updatedAt: null
|
|
58
64
|
},
|
|
59
65
|
req,
|
|
60
66
|
returning: false
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/operations/refresh.ts"],"sourcesContent":["import type { Collection } from '../../collections/config/types.js'\nimport type { Document, PayloadRequest } from '../../types/index.js'\n\nimport { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'\nimport { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'\nimport { Forbidden } from '../../errors/index.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { getFieldsToSign } from '../getFieldsToSign.js'\nimport { jwtSign } from '../jwt.js'\nimport { removeExpiredSessions } from '../sessions.js'\n\nexport type Result = {\n exp: number\n refreshedToken: string\n setCookie?: boolean\n /** @deprecated\n * use:\n * ```ts\n * user._strategy\n * ```\n */\n strategy?: string\n user: Document\n}\n\nexport type Arguments = {\n collection: Collection\n req: PayloadRequest\n}\n\nexport const refreshOperation = async (incomingArgs: Arguments): Promise<Result> => {\n let args = incomingArgs\n\n try {\n const shouldCommit = await initTransaction(args.req)\n\n // /////////////////////////////////////\n // beforeOperation - Collection\n // /////////////////////////////////////\n\n args = await buildBeforeOperation({\n args,\n collection: args.collection.config,\n operation: 'refresh',\n overrideAccess: false,\n })\n\n // /////////////////////////////////////\n // Refresh\n // /////////////////////////////////////\n\n const {\n collection: { config: collectionConfig },\n req,\n req: {\n payload: { config, secret },\n },\n } = args\n\n if (!args.req.user) {\n throw new Forbidden(args.req.t)\n }\n\n const pathname = new URL(args.req.url!).pathname\n\n const isGraphQL = pathname === config.routes.graphQL\n\n let user = await req.payload.db.findOne<any>({\n collection: collectionConfig.slug,\n req,\n where: { id: { equals: args.req.user.id } },\n })\n\n const sid = args.req.user._sid\n\n if (collectionConfig.auth.useSessions && !collectionConfig.auth.disableLocalStrategy) {\n if (!Array.isArray(user.sessions) || !sid) {\n throw new Forbidden(args.req.t)\n }\n\n const existingSession = user.sessions.find(({ id }: { id: number }) => id === sid)\n\n const now = new Date()\n const tokenExpInMs = collectionConfig.auth.tokenExpiration * 1000\n existingSession.expiresAt = new Date(now.getTime() + tokenExpInMs)\n\n // Prevent updatedAt from being updated when only refreshing a session\n user.updatedAt = null\n\n await req.payload.db.updateOne({\n id: user.id,\n collection: collectionConfig.slug,\n data: {\n ...user,\n sessions: removeExpiredSessions(user.sessions),\n },\n req,\n returning: false,\n })\n }\n\n user = await req.payload.findByID({\n id: user.id,\n collection: collectionConfig.slug,\n depth: isGraphQL ? 0 : args.collection.config.auth.depth,\n req: args.req,\n })\n\n if (user) {\n user.collection = args.req.user.collection\n user._strategy = args.req.user._strategy\n }\n\n let result!: Result\n\n // /////////////////////////////////////\n // refresh hook - Collection\n // /////////////////////////////////////\n\n for (const refreshHook of args.collection.config.hooks.refresh) {\n const hookResult = await refreshHook({ args, user })\n\n if (hookResult) {\n result = hookResult\n break\n }\n }\n\n if (!result) {\n const fieldsToSign = getFieldsToSign({\n collectionConfig,\n email: user?.email as string,\n sid,\n user: args?.req?.user,\n })\n\n const { exp, token: refreshedToken } = await jwtSign({\n fieldsToSign,\n secret,\n tokenExpiration: collectionConfig.auth.tokenExpiration,\n })\n\n result = {\n exp,\n refreshedToken,\n setCookie: true,\n /** @deprecated\n * use:\n * ```ts\n * user._strategy\n * ```\n */\n strategy: args.req.user._strategy,\n user,\n }\n }\n\n // /////////////////////////////////////\n // After Refresh - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterRefresh?.length) {\n for (const hook of collectionConfig.hooks.afterRefresh) {\n result =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n exp: result.exp,\n req: args.req,\n token: result.refreshedToken,\n })) || result\n }\n }\n\n // /////////////////////////////////////\n // afterOperation - Collection\n // /////////////////////////////////////\n\n result = await buildAfterOperation({\n args,\n collection: args.collection?.config,\n operation: 'refresh',\n overrideAccess: false,\n result,\n })\n\n // /////////////////////////////////////\n // Return results\n // /////////////////////////////////////\n\n if (shouldCommit) {\n await commitTransaction(req)\n }\n\n return result\n } catch (error: unknown) {\n await killTransaction(args.req)\n throw error\n }\n}\n"],"names":["buildAfterOperation","buildBeforeOperation","Forbidden","commitTransaction","initTransaction","killTransaction","getFieldsToSign","jwtSign","removeExpiredSessions","refreshOperation","incomingArgs","args","shouldCommit","req","collection","config","operation","overrideAccess","collectionConfig","payload","secret","user","t","pathname","URL","url","isGraphQL","routes","graphQL","db","findOne","slug","where","id","equals","sid","_sid","auth","useSessions","disableLocalStrategy","Array","isArray","sessions","existingSession","find","now","Date","tokenExpInMs","tokenExpiration","expiresAt","getTime","updatedAt","updateOne","data","returning","findByID","depth","_strategy","result","refreshHook","hooks","refresh","hookResult","fieldsToSign","email","exp","token","refreshedToken","setCookie","strategy","afterRefresh","length","hook","context","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/operations/refresh.ts"],"sourcesContent":["import type { Collection } from '../../collections/config/types.js'\nimport type { AuthenticatedUser } from '../../index.js'\nimport type { Document, PayloadRequest } from '../../types/index.js'\n\nimport { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'\nimport { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'\nimport { Forbidden } from '../../errors/index.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { getFieldsToSign } from '../getFieldsToSign.js'\nimport { jwtSign } from '../jwt.js'\nimport { removeExpiredSessions } from '../sessions.js'\n\nexport type Result = {\n exp: number\n refreshedToken: string\n setCookie?: boolean\n /** @deprecated\n * use:\n * ```ts\n * user._strategy\n * ```\n */\n strategy?: string\n user: Document\n}\n\nexport type Arguments = {\n collection: Collection\n req: PayloadRequest\n}\n\nexport const refreshOperation = async (incomingArgs: Arguments): Promise<Result> => {\n let args = incomingArgs\n\n try {\n const shouldCommit = await initTransaction(args.req)\n\n // /////////////////////////////////////\n // beforeOperation - Collection\n // /////////////////////////////////////\n\n args = await buildBeforeOperation({\n args,\n collection: args.collection.config,\n operation: 'refresh',\n overrideAccess: false,\n })\n\n // /////////////////////////////////////\n // Refresh\n // /////////////////////////////////////\n\n const {\n collection: { config: collectionConfig },\n req,\n req: {\n payload: { config, secret },\n },\n } = args\n\n if (!args.req.user) {\n throw new Forbidden(args.req.t)\n }\n\n const pathname = new URL(args.req.url!).pathname\n\n const isGraphQL = pathname === config.routes.graphQL\n\n let user = await req.payload.db.findOne<AuthenticatedUser>({\n collection: collectionConfig.slug,\n req,\n where: { id: { equals: args.req.user.id } },\n })\n\n if (!user) {\n throw new Forbidden(args.req.t)\n }\n\n const sid = args.req.user._sid\n\n if (collectionConfig.auth.useSessions && !collectionConfig.auth.disableLocalStrategy) {\n if (!Array.isArray(user.sessions) || !sid) {\n throw new Forbidden(args.req.t)\n }\n\n const existingSession = user.sessions.find(({ id }) => id === sid)\n\n if (!existingSession) {\n throw new Forbidden(args.req.t)\n }\n\n const now = new Date()\n const tokenExpInMs = collectionConfig.auth.tokenExpiration * 1000\n existingSession.expiresAt = new Date(now.getTime() + tokenExpInMs)\n\n await req.payload.db.updateOne({\n id: user.id,\n collection: collectionConfig.slug,\n data: {\n ...user,\n // Prevent updatedAt from being updated when only refreshing a session\n sessions: removeExpiredSessions(user.sessions),\n updatedAt: null,\n },\n req,\n returning: false,\n })\n }\n\n user = (await req.payload.findByID({\n id: user.id,\n collection: collectionConfig.slug,\n depth: isGraphQL ? 0 : args.collection.config.auth.depth,\n req: args.req,\n })) as AuthenticatedUser\n\n if (user) {\n user.collection = args.req.user.collection\n user._strategy = args.req.user._strategy\n }\n\n let result!: Result\n\n // /////////////////////////////////////\n // refresh hook - Collection\n // /////////////////////////////////////\n\n for (const refreshHook of args.collection.config.hooks.refresh) {\n const hookResult = await refreshHook({ args, user })\n\n if (hookResult) {\n result = hookResult\n break\n }\n }\n\n if (!result) {\n const fieldsToSign = getFieldsToSign({\n collectionConfig,\n email: user?.email as string,\n sid,\n user: args?.req?.user,\n })\n\n const { exp, token: refreshedToken } = await jwtSign({\n fieldsToSign,\n secret,\n tokenExpiration: collectionConfig.auth.tokenExpiration,\n })\n\n result = {\n exp,\n refreshedToken,\n setCookie: true,\n /** @deprecated\n * use:\n * ```ts\n * user._strategy\n * ```\n */\n strategy: args.req.user._strategy,\n user,\n }\n }\n\n // /////////////////////////////////////\n // After Refresh - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterRefresh?.length) {\n for (const hook of collectionConfig.hooks.afterRefresh) {\n result =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n exp: result.exp,\n req: args.req,\n token: result.refreshedToken,\n })) || result\n }\n }\n\n // /////////////////////////////////////\n // afterOperation - Collection\n // /////////////////////////////////////\n\n result = await buildAfterOperation({\n args,\n collection: args.collection?.config,\n operation: 'refresh',\n overrideAccess: false,\n result,\n })\n\n // /////////////////////////////////////\n // Return results\n // /////////////////////////////////////\n\n if (shouldCommit) {\n await commitTransaction(req)\n }\n\n return result\n } catch (error: unknown) {\n await killTransaction(args.req)\n throw error\n }\n}\n"],"names":["buildAfterOperation","buildBeforeOperation","Forbidden","commitTransaction","initTransaction","killTransaction","getFieldsToSign","jwtSign","removeExpiredSessions","refreshOperation","incomingArgs","args","shouldCommit","req","collection","config","operation","overrideAccess","collectionConfig","payload","secret","user","t","pathname","URL","url","isGraphQL","routes","graphQL","db","findOne","slug","where","id","equals","sid","_sid","auth","useSessions","disableLocalStrategy","Array","isArray","sessions","existingSession","find","now","Date","tokenExpInMs","tokenExpiration","expiresAt","getTime","updateOne","data","updatedAt","returning","findByID","depth","_strategy","result","refreshHook","hooks","refresh","hookResult","fieldsToSign","email","exp","token","refreshedToken","setCookie","strategy","afterRefresh","length","hook","context","error"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resetPassword.d.ts","sourceRoot":"","sources":["../../../src/auth/operations/resetPassword.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,mCAAmC,CAAA;AAC3F,OAAO,KAAK,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"resetPassword.d.ts","sourceRoot":"","sources":["../../../src/auth/operations/resetPassword.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,mCAAmC,CAAA;AAC3F,OAAO,KAAK,EAAE,kBAAkB,EAAQ,MAAM,gBAAgB,CAAA;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAe1D,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,UAAU,CAAA;IACtB,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAA;QAChB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,GAAG,EAAE,cAAc,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAU,KAAK,SAAS,kBAAkB,EAC3E,MAAM,SAAS,KACd,OAAO,CAAC,MAAM,CA4NhB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/operations/resetPassword.ts"],"sourcesContent":["import { status as httpStatus } from 'http-status'\n\nimport type { Collection, DataFromCollectionSlug } from '../../collections/config/types.js'\nimport type { AuthCollectionSlug, TypedUser } from '../../index.js'\nimport type { PayloadRequest } from '../../types/index.js'\n\nimport { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'\nimport { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'\nimport { APIError, Forbidden } from '../../errors/index.js'\nimport { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { getFieldsToSign } from '../getFieldsToSign.js'\nimport { jwtSign } from '../jwt.js'\nimport { addSessionToUser, revokeSession } from '../sessions.js'\nimport { authenticateLocalStrategy } from '../strategies/local/authenticate.js'\nimport { generatePasswordSaltHash } from '../strategies/local/generatePasswordSaltHash.js'\n\nexport type Result = {\n token?: string\n user: Record<string, unknown>\n}\n\nexport type Arguments = {\n collection: Collection\n data: {\n password: string\n token: string\n }\n depth?: number\n overrideAccess?: boolean\n req: PayloadRequest\n}\n\nexport const resetPasswordOperation = async <TSlug extends AuthCollectionSlug>(\n args: Arguments,\n): Promise<Result> => {\n const {\n collection: { config: collectionConfig },\n data,\n depth,\n overrideAccess,\n req: {\n payload: { secret },\n payload,\n },\n req,\n } = args\n\n if (\n !Object.prototype.hasOwnProperty.call(data, 'token') ||\n !Object.prototype.hasOwnProperty.call(data, 'password')\n ) {\n throw new APIError('Missing required data.', httpStatus.BAD_REQUEST)\n }\n\n if (collectionConfig.auth.disableLocalStrategy) {\n throw new Forbidden(req.t)\n }\n\n let sid: string | undefined\n let user: null | TypedUser = null\n\n try {\n const shouldCommit = await initTransaction(req)\n\n args = await buildBeforeOperation({\n args,\n collection: args.collection.config,\n operation: 'resetPassword',\n overrideAccess,\n })\n\n // /////////////////////////////////////\n // Reset Password\n // /////////////////////////////////////\n\n const where = appendNonTrashedFilter({\n enableTrash: Boolean(collectionConfig.trash),\n trash: false,\n where: {\n resetPasswordExpiration: { greater_than: new Date().toISOString() },\n resetPasswordToken: { equals: data.token },\n },\n })\n\n user = await payload.db.findOne<TypedUser>({\n collection: collectionConfig.slug,\n req,\n where,\n })\n\n if (!user) {\n throw new APIError('Token is either invalid or has expired.', httpStatus.FORBIDDEN)\n }\n\n // TODO: replace this method\n const { hash, salt } = await generatePasswordSaltHash({\n collection: collectionConfig,\n password: data.password,\n req,\n })\n\n user.salt = salt\n user.hash = hash\n\n user.resetPasswordExpiration = new Date().toISOString()\n\n if (collectionConfig.auth.verify) {\n user._verified = Boolean(user._verified)\n }\n\n // /////////////////////////////////////\n // beforeValidate - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeValidate?.length) {\n for (const hook of collectionConfig.hooks.beforeValidate) {\n await hook({\n collection: args.collection?.config,\n context: req.context,\n data: user,\n operation: 'update',\n req,\n })\n }\n }\n\n // /////////////////////////////////////\n // Update new password\n // /////////////////////////////////////\n\n // Ensure updatedAt date is always updated\n user.updatedAt = new Date().toISOString()\n\n const doc = await payload.db.updateOne({\n id: user.id,\n collection: collectionConfig.slug,\n data: user,\n req,\n })\n\n await authenticateLocalStrategy({ doc, password: data.password })\n\n const fieldsToSignArgs: Parameters<typeof getFieldsToSign>[0] = {\n collectionConfig,\n email: user.email!,\n user,\n }\n\n const session = await addSessionToUser({\n collectionConfig,\n payload,\n req,\n user,\n })\n sid = session.sid\n\n if (sid) {\n fieldsToSignArgs.sid = sid\n }\n\n const fieldsToSign = getFieldsToSign(fieldsToSignArgs)\n\n // /////////////////////////////////////\n // beforeLogin - Collection\n // /////////////////////////////////////\n\n let userBeforeLogin = user\n\n if (collectionConfig.hooks?.beforeLogin?.length) {\n for (const hook of collectionConfig.hooks.beforeLogin) {\n userBeforeLogin =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n user: userBeforeLogin,\n })) || userBeforeLogin\n }\n }\n\n const { token } = await jwtSign({\n fieldsToSign,\n secret,\n tokenExpiration: collectionConfig.auth.tokenExpiration,\n })\n\n req.user = userBeforeLogin\n\n // /////////////////////////////////////\n // afterLogin - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterLogin?.length) {\n for (const hook of collectionConfig.hooks.afterLogin) {\n userBeforeLogin =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n token,\n user: userBeforeLogin,\n })) || userBeforeLogin\n }\n }\n\n const fullUser = await payload.findByID({\n id: user.id,\n collection: collectionConfig.slug,\n depth,\n overrideAccess,\n req,\n trash: false,\n })\n\n if (shouldCommit) {\n await commitTransaction(req)\n }\n\n if (fullUser) {\n fullUser.collection = collectionConfig.slug\n fullUser._strategy = 'local-jwt'\n }\n\n let result: { user: DataFromCollectionSlug<TSlug> } & Result = {\n token,\n user: fullUser,\n }\n\n // /////////////////////////////////////\n // afterOperation - Collection\n // /////////////////////////////////////\n\n result = await buildAfterOperation({\n args,\n collection: args.collection?.config,\n operation: 'resetPassword',\n overrideAccess,\n result,\n })\n\n return result\n } catch (error: unknown) {\n if (sid) {\n await revokeSession({\n collectionConfig,\n payload,\n req,\n sid,\n user,\n })\n }\n await killTransaction(req)\n throw error\n }\n}\n"],"names":["status","httpStatus","buildAfterOperation","buildBeforeOperation","APIError","Forbidden","appendNonTrashedFilter","commitTransaction","initTransaction","killTransaction","getFieldsToSign","jwtSign","addSessionToUser","revokeSession","authenticateLocalStrategy","generatePasswordSaltHash","resetPasswordOperation","args","collection","config","collectionConfig","data","depth","overrideAccess","req","payload","secret","Object","prototype","hasOwnProperty","call","BAD_REQUEST","auth","disableLocalStrategy","t","sid","user","shouldCommit","operation","where","enableTrash","Boolean","trash","resetPasswordExpiration","greater_than","Date","toISOString","resetPasswordToken","equals","token","db","findOne","slug","FORBIDDEN","hash","salt","password","verify","_verified","hooks","beforeValidate","length","hook","context","updatedAt","doc","updateOne","id","fieldsToSignArgs","email","session","fieldsToSign","userBeforeLogin","beforeLogin","tokenExpiration","afterLogin","fullUser","findByID","_strategy","result","error"],"mappings":"AAAA,SAASA,UAAUC,UAAU,QAAQ,cAAa;AAMlD,SAASC,mBAAmB,QAAQ,gEAA+D;AACnG,SAASC,oBAAoB,QAAQ,iEAAgE;AACrG,SAASC,QAAQ,EAAEC,SAAS,QAAQ,wBAAuB;AAC3D,SAASC,sBAAsB,QAAQ,4CAA2C;AAClF,SAASC,iBAAiB,QAAQ,uCAAsC;AACxE,SAASC,eAAe,QAAQ,qCAAoC;AACpE,SAASC,eAAe,QAAQ,qCAAoC;AACpE,SAASC,eAAe,QAAQ,wBAAuB;AACvD,SAASC,OAAO,QAAQ,YAAW;AACnC,SAASC,gBAAgB,EAAEC,aAAa,QAAQ,iBAAgB;AAChE,SAASC,yBAAyB,QAAQ,sCAAqC;AAC/E,SAASC,wBAAwB,QAAQ,kDAAiD;AAkB1F,OAAO,MAAMC,yBAAyB,OACpCC;IAEA,MAAM,EACJC,YAAY,EAAEC,QAAQC,gBAAgB,EAAE,EACxCC,IAAI,EACJC,KAAK,EACLC,cAAc,EACdC,KAAK,EACHC,SAAS,EAAEC,MAAM,EAAE,EACnBD,OAAO,EACR,EACDD,GAAG,EACJ,GAAGP;IAEJ,IACE,CAACU,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACT,MAAM,YAC5C,CAACM,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACT,MAAM,aAC5C;QACA,MAAM,IAAIjB,SAAS,0BAA0BH,WAAW8B,WAAW;IACrE;IAEA,IAAIX,iBAAiBY,IAAI,CAACC,oBAAoB,EAAE;QAC9C,MAAM,IAAI5B,UAAUmB,IAAIU,CAAC;IAC3B;IAEA,IAAIC;IACJ,IAAIC,OAAyB;IAE7B,IAAI;QACF,MAAMC,eAAe,MAAM7B,gBAAgBgB;QAE3CP,OAAO,MAAMd,qBAAqB;YAChCc;YACAC,YAAYD,KAAKC,UAAU,CAACC,MAAM;YAClCmB,WAAW;YACXf;QACF;QAEA,wCAAwC;QACxC,iBAAiB;QACjB,wCAAwC;QAExC,MAAMgB,QAAQjC,uBAAuB;YACnCkC,aAAaC,QAAQrB,iBAAiBsB,KAAK;YAC3CA,OAAO;YACPH,OAAO;gBACLI,yBAAyB;oBAAEC,cAAc,IAAIC,OAAOC,WAAW;gBAAG;gBAClEC,oBAAoB;oBAAEC,QAAQ3B,KAAK4B,KAAK;gBAAC;YAC3C;QACF;QAEAb,OAAO,MAAMX,QAAQyB,EAAE,CAACC,OAAO,CAAY;YACzCjC,YAAYE,iBAAiBgC,IAAI;YACjC5B;YACAe;QACF;QAEA,IAAI,CAACH,MAAM;YACT,MAAM,IAAIhC,SAAS,2CAA2CH,WAAWoD,SAAS;QACpF;QAEA,4BAA4B;QAC5B,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAE,GAAG,MAAMxC,yBAAyB;YACpDG,YAAYE;YACZoC,UAAUnC,KAAKmC,QAAQ;YACvBhC;QACF;QAEAY,KAAKmB,IAAI,GAAGA;QACZnB,KAAKkB,IAAI,GAAGA;QAEZlB,KAAKO,uBAAuB,GAAG,IAAIE,OAAOC,WAAW;QAErD,IAAI1B,iBAAiBY,IAAI,CAACyB,MAAM,EAAE;YAChCrB,KAAKsB,SAAS,GAAGjB,QAAQL,KAAKsB,SAAS;QACzC;QAEA,wCAAwC;QACxC,8BAA8B;QAC9B,wCAAwC;QAExC,IAAItC,iBAAiBuC,KAAK,EAAEC,gBAAgBC,QAAQ;YAClD,KAAK,MAAMC,QAAQ1C,iBAAiBuC,KAAK,CAACC,cAAc,CAAE;gBACxD,MAAME,KAAK;oBACT5C,YAAYD,KAAKC,UAAU,EAAEC;oBAC7B4C,SAASvC,IAAIuC,OAAO;oBACpB1C,MAAMe;oBACNE,WAAW;oBACXd;gBACF;YACF;QACF;QAEA,wCAAwC;QACxC,sBAAsB;QACtB,wCAAwC;QAExC,0CAA0C;QAC1CY,KAAK4B,SAAS,GAAG,IAAInB,OAAOC,WAAW;QAEvC,MAAMmB,MAAM,MAAMxC,QAAQyB,EAAE,CAACgB,SAAS,CAAC;YACrCC,IAAI/B,KAAK+B,EAAE;YACXjD,YAAYE,iBAAiBgC,IAAI;YACjC/B,MAAMe;YACNZ;QACF;QAEA,MAAMV,0BAA0B;YAAEmD;YAAKT,UAAUnC,KAAKmC,QAAQ;QAAC;QAE/D,MAAMY,mBAA0D;YAC9DhD;YACAiD,OAAOjC,KAAKiC,KAAK;YACjBjC;QACF;QAEA,MAAMkC,UAAU,MAAM1D,iBAAiB;YACrCQ;YACAK;YACAD;YACAY;QACF;QACAD,MAAMmC,QAAQnC,GAAG;QAEjB,IAAIA,KAAK;YACPiC,iBAAiBjC,GAAG,GAAGA;QACzB;QAEA,MAAMoC,eAAe7D,gBAAgB0D;QAErC,wCAAwC;QACxC,2BAA2B;QAC3B,wCAAwC;QAExC,IAAII,kBAAkBpC;QAEtB,IAAIhB,iBAAiBuC,KAAK,EAAEc,aAAaZ,QAAQ;YAC/C,KAAK,MAAMC,QAAQ1C,iBAAiBuC,KAAK,CAACc,WAAW,CAAE;gBACrDD,kBACE,AAAC,MAAMV,KAAK;oBACV5C,YAAYD,KAAKC,UAAU,EAAEC;oBAC7B4C,SAAS9C,KAAKO,GAAG,CAACuC,OAAO;oBACzBvC,KAAKP,KAAKO,GAAG;oBACbY,MAAMoC;gBACR,MAAOA;YACX;QACF;QAEA,MAAM,EAAEvB,KAAK,EAAE,GAAG,MAAMtC,QAAQ;YAC9B4D;YACA7C;YACAgD,iBAAiBtD,iBAAiBY,IAAI,CAAC0C,eAAe;QACxD;QAEAlD,IAAIY,IAAI,GAAGoC;QAEX,wCAAwC;QACxC,0BAA0B;QAC1B,wCAAwC;QAExC,IAAIpD,iBAAiBuC,KAAK,EAAEgB,YAAYd,QAAQ;YAC9C,KAAK,MAAMC,QAAQ1C,iBAAiBuC,KAAK,CAACgB,UAAU,CAAE;gBACpDH,kBACE,AAAC,MAAMV,KAAK;oBACV5C,YAAYD,KAAKC,UAAU,EAAEC;oBAC7B4C,SAAS9C,KAAKO,GAAG,CAACuC,OAAO;oBACzBvC,KAAKP,KAAKO,GAAG;oBACbyB;oBACAb,MAAMoC;gBACR,MAAOA;YACX;QACF;QAEA,MAAMI,WAAW,MAAMnD,QAAQoD,QAAQ,CAAC;YACtCV,IAAI/B,KAAK+B,EAAE;YACXjD,YAAYE,iBAAiBgC,IAAI;YACjC9B;YACAC;YACAC;YACAkB,OAAO;QACT;QAEA,IAAIL,cAAc;YAChB,MAAM9B,kBAAkBiB;QAC1B;QAEA,IAAIoD,UAAU;YACZA,SAAS1D,UAAU,GAAGE,iBAAiBgC,IAAI;YAC3CwB,SAASE,SAAS,GAAG;QACvB;QAEA,IAAIC,SAA2D;YAC7D9B;YACAb,MAAMwC;QACR;QAEA,wCAAwC;QACxC,8BAA8B;QAC9B,wCAAwC;QAExCG,SAAS,MAAM7E,oBAAoB;YACjCe;YACAC,YAAYD,KAAKC,UAAU,EAAEC;YAC7BmB,WAAW;YACXf;YACAwD;QACF;QAEA,OAAOA;IACT,EAAE,OAAOC,OAAgB;QACvB,IAAI7C,KAAK;YACP,MAAMtB,cAAc;gBAClBO;gBACAK;gBACAD;gBACAW;gBACAC;YACF;QACF;QACA,MAAM3B,gBAAgBe;QACtB,MAAMwD;IACR;AACF,EAAC"}
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/operations/resetPassword.ts"],"sourcesContent":["import { status as httpStatus } from 'http-status'\n\nimport type { Collection, DataFromCollectionSlug } from '../../collections/config/types.js'\nimport type { AuthCollectionSlug, User } from '../../index.js'\nimport type { PayloadRequest } from '../../types/index.js'\n\nimport { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'\nimport { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'\nimport { APIError, Forbidden } from '../../errors/index.js'\nimport { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { getFieldsToSign } from '../getFieldsToSign.js'\nimport { jwtSign } from '../jwt.js'\nimport { addSessionToUser, revokeSession } from '../sessions.js'\nimport { authenticateLocalStrategy } from '../strategies/local/authenticate.js'\nimport { generatePasswordSaltHash } from '../strategies/local/generatePasswordSaltHash.js'\n\nexport type Result = {\n token?: string\n user: Record<string, unknown>\n}\n\nexport type Arguments = {\n collection: Collection\n data: {\n password: string\n token: string\n }\n depth?: number\n overrideAccess?: boolean\n req: PayloadRequest\n}\n\nexport const resetPasswordOperation = async <TSlug extends AuthCollectionSlug>(\n args: Arguments,\n): Promise<Result> => {\n const {\n collection: { config: collectionConfig },\n data,\n depth,\n overrideAccess,\n req: {\n payload: { secret },\n payload,\n },\n req,\n } = args\n\n if (\n !Object.prototype.hasOwnProperty.call(data, 'token') ||\n !Object.prototype.hasOwnProperty.call(data, 'password')\n ) {\n throw new APIError('Missing required data.', httpStatus.BAD_REQUEST)\n }\n\n if (collectionConfig.auth.disableLocalStrategy) {\n throw new Forbidden(req.t)\n }\n\n let sid: string | undefined\n let user: null | User = null\n\n try {\n const shouldCommit = await initTransaction(req)\n\n args = await buildBeforeOperation({\n args,\n collection: args.collection.config,\n operation: 'resetPassword',\n overrideAccess,\n })\n\n // /////////////////////////////////////\n // Reset Password\n // /////////////////////////////////////\n\n const where = appendNonTrashedFilter({\n enableTrash: Boolean(collectionConfig.trash),\n trash: false,\n where: {\n resetPasswordExpiration: { greater_than: new Date().toISOString() },\n resetPasswordToken: { equals: data.token },\n },\n })\n\n user = await payload.db.findOne<User>({\n collection: collectionConfig.slug,\n req,\n where,\n })\n\n if (!user) {\n throw new APIError('Token is either invalid or has expired.', httpStatus.FORBIDDEN)\n }\n\n // TODO: replace this method\n const { hash, salt } = await generatePasswordSaltHash({\n collection: collectionConfig,\n password: data.password,\n req,\n })\n\n user.salt = salt\n user.hash = hash\n\n user.resetPasswordExpiration = new Date().toISOString()\n\n if (collectionConfig.auth.verify) {\n user._verified = Boolean(user._verified)\n }\n\n // /////////////////////////////////////\n // beforeValidate - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeValidate?.length) {\n for (const hook of collectionConfig.hooks.beforeValidate) {\n await hook({\n collection: args.collection?.config,\n context: req.context,\n data: user,\n operation: 'update',\n req,\n })\n }\n }\n\n // /////////////////////////////////////\n // Update new password\n // /////////////////////////////////////\n\n // Ensure updatedAt date is always updated\n user.updatedAt = new Date().toISOString()\n\n const doc = await payload.db.updateOne({\n id: user.id,\n collection: collectionConfig.slug,\n data: user,\n req,\n })\n\n await authenticateLocalStrategy({ doc, password: data.password })\n\n const fieldsToSignArgs: Parameters<typeof getFieldsToSign>[0] = {\n collectionConfig,\n email: user.email!,\n user,\n }\n\n const session = await addSessionToUser({\n collectionConfig,\n payload,\n req,\n user,\n })\n sid = session.sid\n\n if (sid) {\n fieldsToSignArgs.sid = sid\n }\n\n const fieldsToSign = getFieldsToSign(fieldsToSignArgs)\n\n // /////////////////////////////////////\n // beforeLogin - Collection\n // /////////////////////////////////////\n\n let userBeforeLogin = user\n\n if (collectionConfig.hooks?.beforeLogin?.length) {\n for (const hook of collectionConfig.hooks.beforeLogin) {\n userBeforeLogin =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n user: userBeforeLogin,\n })) || userBeforeLogin\n }\n }\n\n const { token } = await jwtSign({\n fieldsToSign,\n secret,\n tokenExpiration: collectionConfig.auth.tokenExpiration,\n })\n\n req.user = userBeforeLogin\n\n // /////////////////////////////////////\n // afterLogin - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterLogin?.length) {\n for (const hook of collectionConfig.hooks.afterLogin) {\n userBeforeLogin =\n (await hook({\n collection: args.collection?.config,\n context: args.req.context,\n req: args.req,\n token,\n user: userBeforeLogin,\n })) || userBeforeLogin\n }\n }\n\n const fullUser = await payload.findByID({\n id: user.id,\n collection: collectionConfig.slug,\n depth,\n overrideAccess,\n req,\n trash: false,\n })\n\n if (shouldCommit) {\n await commitTransaction(req)\n }\n\n if (fullUser) {\n fullUser.collection = collectionConfig.slug\n fullUser._strategy = 'local-jwt'\n }\n\n let result: { user: DataFromCollectionSlug<TSlug> } & Result = {\n token,\n user: fullUser,\n }\n\n // /////////////////////////////////////\n // afterOperation - Collection\n // /////////////////////////////////////\n\n result = await buildAfterOperation({\n args,\n collection: args.collection?.config,\n operation: 'resetPassword',\n overrideAccess,\n result,\n })\n\n return result\n } catch (error: unknown) {\n if (sid) {\n await revokeSession({\n collectionConfig,\n payload,\n req,\n sid,\n user,\n })\n }\n await killTransaction(req)\n throw error\n }\n}\n"],"names":["status","httpStatus","buildAfterOperation","buildBeforeOperation","APIError","Forbidden","appendNonTrashedFilter","commitTransaction","initTransaction","killTransaction","getFieldsToSign","jwtSign","addSessionToUser","revokeSession","authenticateLocalStrategy","generatePasswordSaltHash","resetPasswordOperation","args","collection","config","collectionConfig","data","depth","overrideAccess","req","payload","secret","Object","prototype","hasOwnProperty","call","BAD_REQUEST","auth","disableLocalStrategy","t","sid","user","shouldCommit","operation","where","enableTrash","Boolean","trash","resetPasswordExpiration","greater_than","Date","toISOString","resetPasswordToken","equals","token","db","findOne","slug","FORBIDDEN","hash","salt","password","verify","_verified","hooks","beforeValidate","length","hook","context","updatedAt","doc","updateOne","id","fieldsToSignArgs","email","session","fieldsToSign","userBeforeLogin","beforeLogin","tokenExpiration","afterLogin","fullUser","findByID","_strategy","result","error"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Collection } from '../collections/config/types.js';
|
|
2
2
|
import type { SanitizedConfig } from '../config/types.js';
|
|
3
3
|
import type { InitializedEmailAdapter } from '../email/types.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { User } from '../index.js';
|
|
5
5
|
import type { PayloadRequest } from '../types/index.js';
|
|
6
6
|
type Args = {
|
|
7
7
|
collection: Collection;
|
|
@@ -10,7 +10,7 @@ type Args = {
|
|
|
10
10
|
email: InitializedEmailAdapter;
|
|
11
11
|
req: PayloadRequest;
|
|
12
12
|
token: string;
|
|
13
|
-
user:
|
|
13
|
+
user: User;
|
|
14
14
|
};
|
|
15
15
|
export declare function sendVerificationEmail(args: Args): Promise<void>;
|
|
16
16
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sendVerificationEmail.d.ts","sourceRoot":"","sources":["../../src/auth/sendVerificationEmail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"sendVerificationEmail.d.ts","sourceRoot":"","sources":["../../src/auth/sendVerificationEmail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAMvD,KAAK,IAAI,GAAG;IACV,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,eAAe,CAAA;IACvB,YAAY,EAAE,OAAO,CAAA;IACrB,KAAK,EAAE,uBAAuB,CAAA;IAC9B,GAAG,EAAE,cAAc,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,IAAI,CAAA;CACX,CAAA;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDrE"}
|
|
@@ -3,7 +3,7 @@ import { getRequestOrigin } from '../utilities/getRequestOrigin.js';
|
|
|
3
3
|
export async function sendVerificationEmail(args) {
|
|
4
4
|
// Verify token from e-mail
|
|
5
5
|
const { collection: { config: collectionConfig }, config, disableEmail, email, req, token, user } = args;
|
|
6
|
-
if (!disableEmail) {
|
|
6
|
+
if (!disableEmail && user.email) {
|
|
7
7
|
const serverURL = getRequestOrigin({
|
|
8
8
|
config,
|
|
9
9
|
req
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/sendVerificationEmail.ts"],"sourcesContent":["import type { Collection } from '../collections/config/types.js'\nimport type { SanitizedConfig } from '../config/types.js'\nimport type { InitializedEmailAdapter } from '../email/types.js'\nimport type {
|
|
1
|
+
{"version":3,"sources":["../../src/auth/sendVerificationEmail.ts"],"sourcesContent":["import type { Collection } from '../collections/config/types.js'\nimport type { SanitizedConfig } from '../config/types.js'\nimport type { InitializedEmailAdapter } from '../email/types.js'\nimport type { User } from '../index.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { VerifyConfig } from './types.js'\n\nimport { formatAdminURL } from '../utilities/formatAdminURL.js'\nimport { getRequestOrigin } from '../utilities/getRequestOrigin.js'\n\ntype Args = {\n collection: Collection\n config: SanitizedConfig\n disableEmail: boolean\n email: InitializedEmailAdapter\n req: PayloadRequest\n token: string\n user: User\n}\n\nexport async function sendVerificationEmail(args: Args): Promise<void> {\n // Verify token from e-mail\n const {\n collection: { config: collectionConfig },\n config,\n disableEmail,\n email,\n req,\n token,\n user,\n } = args\n\n if (!disableEmail && user.email) {\n const serverURL = getRequestOrigin({ config, req })\n\n const verificationURL = formatAdminURL({\n adminRoute: config.routes.admin,\n path: `/${collectionConfig.slug}/verify/${token}`,\n serverURL,\n })\n\n let html = `${req.t('authentication:newAccountCreated', {\n serverURL: config.serverURL,\n verificationURL,\n })}`\n\n const verify = collectionConfig.auth.verify as VerifyConfig\n\n // Allow config to override email content\n if (typeof verify.generateEmailHTML === 'function') {\n html = await verify.generateEmailHTML({\n req,\n token,\n user,\n })\n }\n\n let subject = req.t('authentication:verifyYourEmail')\n\n // Allow config to override email subject\n if (typeof verify.generateEmailSubject === 'function') {\n subject = await verify.generateEmailSubject({\n req,\n token,\n user,\n })\n }\n\n await email.sendEmail({\n from: `\"${email.defaultFromName}\" <${email.defaultFromAddress}>`,\n html,\n subject,\n to: user.email,\n })\n }\n}\n"],"names":["formatAdminURL","getRequestOrigin","sendVerificationEmail","args","collection","config","collectionConfig","disableEmail","email","req","token","user","serverURL","verificationURL","adminRoute","routes","admin","path","slug","html","t","verify","auth","generateEmailHTML","subject","generateEmailSubject","sendEmail","from","defaultFromName","defaultFromAddress","to"],"mappings":"AAOA,SAASA,cAAc,QAAQ,iCAAgC;AAC/D,SAASC,gBAAgB,QAAQ,mCAAkC;AAYnE,OAAO,eAAeC,sBAAsBC,IAAU;IACpD,2BAA2B;IAC3B,MAAM,EACJC,YAAY,EAAEC,QAAQC,gBAAgB,EAAE,EACxCD,MAAM,EACNE,YAAY,EACZC,KAAK,EACLC,GAAG,EACHC,KAAK,EACLC,IAAI,EACL,GAAGR;IAEJ,IAAI,CAACI,gBAAgBI,KAAKH,KAAK,EAAE;QAC/B,MAAMI,YAAYX,iBAAiB;YAAEI;YAAQI;QAAI;QAEjD,MAAMI,kBAAkBb,eAAe;YACrCc,YAAYT,OAAOU,MAAM,CAACC,KAAK;YAC/BC,MAAM,CAAC,CAAC,EAAEX,iBAAiBY,IAAI,CAAC,QAAQ,EAAER,OAAO;YACjDE;QACF;QAEA,IAAIO,OAAO,GAAGV,IAAIW,CAAC,CAAC,oCAAoC;YACtDR,WAAWP,OAAOO,SAAS;YAC3BC;QACF,IAAI;QAEJ,MAAMQ,SAASf,iBAAiBgB,IAAI,CAACD,MAAM;QAE3C,yCAAyC;QACzC,IAAI,OAAOA,OAAOE,iBAAiB,KAAK,YAAY;YAClDJ,OAAO,MAAME,OAAOE,iBAAiB,CAAC;gBACpCd;gBACAC;gBACAC;YACF;QACF;QAEA,IAAIa,UAAUf,IAAIW,CAAC,CAAC;QAEpB,yCAAyC;QACzC,IAAI,OAAOC,OAAOI,oBAAoB,KAAK,YAAY;YACrDD,UAAU,MAAMH,OAAOI,oBAAoB,CAAC;gBAC1ChB;gBACAC;gBACAC;YACF;QACF;QAEA,MAAMH,MAAMkB,SAAS,CAAC;YACpBC,MAAM,CAAC,CAAC,EAAEnB,MAAMoB,eAAe,CAAC,GAAG,EAAEpB,MAAMqB,kBAAkB,CAAC,CAAC,CAAC;YAChEV;YACAK;YACAM,IAAInB,KAAKH,KAAK;QAChB;IACF;AACF"}
|
package/dist/auth/sessions.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { SanitizedCollectionConfig
|
|
2
|
-
import type {
|
|
1
|
+
import type { SanitizedCollectionConfig } from '../collections/config/types.js';
|
|
2
|
+
import type { AuthenticatedUser, User, UserSession } from '../index.js';
|
|
3
3
|
import type { Payload, PayloadRequest } from '../types/index.js';
|
|
4
|
-
import type { UntypedUser, UserSession } from './types.js';
|
|
5
4
|
/**
|
|
6
5
|
* Removes expired sessions from an array of sessions
|
|
7
6
|
*/
|
|
@@ -14,7 +13,7 @@ export declare const addSessionToUser: ({ collectionConfig, payload, req, user,
|
|
|
14
13
|
collectionConfig: SanitizedCollectionConfig;
|
|
15
14
|
payload: Payload;
|
|
16
15
|
req: PayloadRequest;
|
|
17
|
-
user:
|
|
16
|
+
user: AuthenticatedUser;
|
|
18
17
|
}) => Promise<{
|
|
19
18
|
sid?: string;
|
|
20
19
|
}>;
|
|
@@ -23,6 +22,6 @@ export declare const revokeSession: ({ collectionConfig, payload, req, sid, user
|
|
|
23
22
|
payload: Payload;
|
|
24
23
|
req: PayloadRequest;
|
|
25
24
|
sid: string;
|
|
26
|
-
user: null |
|
|
25
|
+
user: null | User;
|
|
27
26
|
}) => Promise<void>;
|
|
28
27
|
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/auth/sessions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/auth/sessions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,WAAW,EAAE,KAAG,WAAW,EAO1E,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAU,2CAKpC;IACD,gBAAgB,EAAE,yBAAyB,CAAA;IAC3C,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,cAAc,CAAA;IACnB,IAAI,EAAE,iBAAiB,CAAA;CACxB,KAAG,OAAO,CAAC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAqC3B,CAAA;AAED,eAAO,MAAM,aAAa,GAAU,gDAMjC;IACD,gBAAgB,EAAE,yBAAyB,CAAA;IAC3C,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,cAAc,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;CAClB,KAAG,OAAO,CAAC,IAAI,CAWf,CAAA"}
|
package/dist/auth/sessions.js
CHANGED
|
@@ -32,12 +32,14 @@ import { v4 as uuid } from 'uuid';
|
|
|
32
32
|
user.sessions = removeExpiredSessions(user.sessions);
|
|
33
33
|
user.sessions.push(session);
|
|
34
34
|
}
|
|
35
|
-
// Prevent updatedAt from being updated when only adding a session
|
|
36
|
-
user.updatedAt = null;
|
|
37
35
|
await payload.db.updateOne({
|
|
38
36
|
id: user.id,
|
|
39
37
|
collection: collectionConfig.slug,
|
|
40
|
-
data:
|
|
38
|
+
data: {
|
|
39
|
+
...user,
|
|
40
|
+
// Prevent updatedAt from being updated when only adding a session
|
|
41
|
+
updatedAt: null
|
|
42
|
+
},
|
|
41
43
|
req,
|
|
42
44
|
returning: false
|
|
43
45
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/sessions.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid'\n\nimport type { SanitizedCollectionConfig
|
|
1
|
+
{"version":3,"sources":["../../src/auth/sessions.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid'\n\nimport type { SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { AuthenticatedUser, User, UserSession } from '../index.js'\nimport type { Payload, PayloadRequest } from '../types/index.js'\n\n/**\n * Removes expired sessions from an array of sessions\n */\nexport const removeExpiredSessions = (sessions: UserSession[]): UserSession[] => {\n const now = new Date()\n\n return sessions.filter(({ expiresAt }) => {\n const expiry = expiresAt instanceof Date ? expiresAt : new Date(expiresAt)\n return expiry > now\n })\n}\n\n/**\n * Adds a session to the user and removes expired sessions\n * @returns The session ID (sid) if sessions are used\n */\nexport const addSessionToUser = async ({\n collectionConfig,\n payload,\n req,\n user,\n}: {\n collectionConfig: SanitizedCollectionConfig\n payload: Payload\n req: PayloadRequest\n user: AuthenticatedUser\n}): Promise<{ sid?: string }> => {\n let sid: string | undefined\n if (collectionConfig.auth.useSessions) {\n // Add session to user\n sid = uuid()\n const now = new Date()\n const tokenExpInMs = collectionConfig.auth.tokenExpiration * 1000\n const expiresAt = new Date(now.getTime() + tokenExpInMs)\n\n const session = { id: sid, createdAt: now, expiresAt }\n\n if (!user.sessions?.length) {\n user.sessions = [session]\n } else {\n user.sessions = removeExpiredSessions(user.sessions)\n user.sessions.push(session)\n }\n\n await payload.db.updateOne({\n id: user.id,\n collection: collectionConfig.slug,\n data: {\n ...user,\n // Prevent updatedAt from being updated when only adding a session\n updatedAt: null,\n },\n req,\n returning: false,\n })\n\n user.collection = collectionConfig.slug\n user._strategy = 'local-jwt'\n }\n\n return {\n sid,\n }\n}\n\nexport const revokeSession = async ({\n collectionConfig,\n payload,\n req,\n sid,\n user,\n}: {\n collectionConfig: SanitizedCollectionConfig\n payload: Payload\n req: PayloadRequest\n sid: string\n user: null | User\n}): Promise<void> => {\n if (collectionConfig.auth.useSessions && user && user.sessions?.length) {\n user.sessions = user.sessions.filter((session) => session.id !== sid)\n await payload.db.updateOne({\n id: user.id,\n collection: collectionConfig.slug,\n data: user,\n req,\n returning: false,\n })\n }\n}\n"],"names":["v4","uuid","removeExpiredSessions","sessions","now","Date","filter","expiresAt","expiry","addSessionToUser","collectionConfig","payload","req","user","sid","auth","useSessions","tokenExpInMs","tokenExpiration","getTime","session","id","createdAt","length","push","db","updateOne","collection","slug","data","updatedAt","returning","_strategy","revokeSession"],"mappings":"AAAA,SAASA,MAAMC,IAAI,QAAQ,OAAM;AAMjC;;CAEC,GACD,OAAO,MAAMC,wBAAwB,CAACC;IACpC,MAAMC,MAAM,IAAIC;IAEhB,OAAOF,SAASG,MAAM,CAAC,CAAC,EAAEC,SAAS,EAAE;QACnC,MAAMC,SAASD,qBAAqBF,OAAOE,YAAY,IAAIF,KAAKE;QAChE,OAAOC,SAASJ;IAClB;AACF,EAAC;AAED;;;CAGC,GACD,OAAO,MAAMK,mBAAmB,OAAO,EACrCC,gBAAgB,EAChBC,OAAO,EACPC,GAAG,EACHC,IAAI,EAML;IACC,IAAIC;IACJ,IAAIJ,iBAAiBK,IAAI,CAACC,WAAW,EAAE;QACrC,sBAAsB;QACtBF,MAAMb;QACN,MAAMG,MAAM,IAAIC;QAChB,MAAMY,eAAeP,iBAAiBK,IAAI,CAACG,eAAe,GAAG;QAC7D,MAAMX,YAAY,IAAIF,KAAKD,IAAIe,OAAO,KAAKF;QAE3C,MAAMG,UAAU;YAAEC,IAAIP;YAAKQ,WAAWlB;YAAKG;QAAU;QAErD,IAAI,CAACM,KAAKV,QAAQ,EAAEoB,QAAQ;YAC1BV,KAAKV,QAAQ,GAAG;gBAACiB;aAAQ;QAC3B,OAAO;YACLP,KAAKV,QAAQ,GAAGD,sBAAsBW,KAAKV,QAAQ;YACnDU,KAAKV,QAAQ,CAACqB,IAAI,CAACJ;QACrB;QAEA,MAAMT,QAAQc,EAAE,CAACC,SAAS,CAAC;YACzBL,IAAIR,KAAKQ,EAAE;YACXM,YAAYjB,iBAAiBkB,IAAI;YACjCC,MAAM;gBACJ,GAAGhB,IAAI;gBACP,kEAAkE;gBAClEiB,WAAW;YACb;YACAlB;YACAmB,WAAW;QACb;QAEAlB,KAAKc,UAAU,GAAGjB,iBAAiBkB,IAAI;QACvCf,KAAKmB,SAAS,GAAG;IACnB;IAEA,OAAO;QACLlB;IACF;AACF,EAAC;AAED,OAAO,MAAMmB,gBAAgB,OAAO,EAClCvB,gBAAgB,EAChBC,OAAO,EACPC,GAAG,EACHE,GAAG,EACHD,IAAI,EAOL;IACC,IAAIH,iBAAiBK,IAAI,CAACC,WAAW,IAAIH,QAAQA,KAAKV,QAAQ,EAAEoB,QAAQ;QACtEV,KAAKV,QAAQ,GAAGU,KAAKV,QAAQ,CAACG,MAAM,CAAC,CAACc,UAAYA,QAAQC,EAAE,KAAKP;QACjE,MAAMH,QAAQc,EAAE,CAACC,SAAS,CAAC;YACzBL,IAAIR,KAAKQ,EAAE;YACXM,YAAYjB,iBAAiBkB,IAAI;YACjCC,MAAMhB;YACND;YACAmB,WAAW;QACb;IACF;AACF,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/strategies/apiKey.ts"],"sourcesContent":["import crypto from 'crypto'\n\nimport type { SanitizedCollectionConfig } from '../../collections/config/types.js'\nimport type {
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/strategies/apiKey.ts"],"sourcesContent":["import crypto from 'crypto'\n\nimport type { SanitizedCollectionConfig } from '../../collections/config/types.js'\nimport type { User } from '../../index.js'\nimport type { Where } from '../../types/index.js'\nimport type { AuthStrategyFunction } from '../index.js'\n\nexport const APIKeyAuthentication =\n (collectionConfig: SanitizedCollectionConfig): AuthStrategyFunction =>\n async ({ headers, isGraphQL = false, payload }) => {\n const authHeader = headers.get('Authorization')\n\n if (authHeader?.startsWith(`${collectionConfig.slug} API-Key `)) {\n const apiKey = authHeader.replace(`${collectionConfig.slug} API-Key `, '')\n\n const sha256APIKeyIndex = crypto\n .createHmac('sha256', payload.secret)\n .update(apiKey)\n .digest('hex')\n\n try {\n const where: Where = {}\n if (collectionConfig.auth?.verify) {\n where.and = [\n {\n apiKeyIndex: {\n equals: sha256APIKeyIndex,\n },\n },\n {\n _verified: {\n not_equals: false,\n },\n },\n ]\n } else {\n where.apiKeyIndex = { equals: sha256APIKeyIndex }\n }\n\n const userQuery = await payload.find({\n collection: collectionConfig.slug,\n depth: isGraphQL ? 0 : collectionConfig.auth.depth,\n limit: 1,\n overrideAccess: true,\n pagination: false,\n where,\n })\n\n if (userQuery.docs && userQuery.docs.length > 0) {\n const user = userQuery.docs[0]\n user!.collection = collectionConfig.slug\n user!._strategy = 'api-key'\n\n return {\n user: user as User,\n }\n }\n } catch (ignore) {\n return { user: null }\n }\n }\n\n return { user: null }\n }\n"],"names":["crypto","APIKeyAuthentication","collectionConfig","headers","isGraphQL","payload","authHeader","get","startsWith","slug","apiKey","replace","sha256APIKeyIndex","createHmac","secret","update","digest","where","auth","verify","and","apiKeyIndex","equals","_verified","not_equals","userQuery","find","collection","depth","limit","overrideAccess","pagination","docs","length","user","_strategy","ignore"],"mappings":"AAAA,OAAOA,YAAY,SAAQ;AAO3B,OAAO,MAAMC,uBACX,CAACC,mBACD,OAAO,EAAEC,OAAO,EAAEC,YAAY,KAAK,EAAEC,OAAO,EAAE;QAC5C,MAAMC,aAAaH,QAAQI,GAAG,CAAC;QAE/B,IAAID,YAAYE,WAAW,GAAGN,iBAAiBO,IAAI,CAAC,SAAS,CAAC,GAAG;YAC/D,MAAMC,SAASJ,WAAWK,OAAO,CAAC,GAAGT,iBAAiBO,IAAI,CAAC,SAAS,CAAC,EAAE;YAEvE,MAAMG,oBAAoBZ,OACvBa,UAAU,CAAC,UAAUR,QAAQS,MAAM,EACnCC,MAAM,CAACL,QACPM,MAAM,CAAC;YAEV,IAAI;gBACF,MAAMC,QAAe,CAAC;gBACtB,IAAIf,iBAAiBgB,IAAI,EAAEC,QAAQ;oBACjCF,MAAMG,GAAG,GAAG;wBACV;4BACEC,aAAa;gCACXC,QAAQV;4BACV;wBACF;wBACA;4BACEW,WAAW;gCACTC,YAAY;4BACd;wBACF;qBACD;gBACH,OAAO;oBACLP,MAAMI,WAAW,GAAG;wBAAEC,QAAQV;oBAAkB;gBAClD;gBAEA,MAAMa,YAAY,MAAMpB,QAAQqB,IAAI,CAAC;oBACnCC,YAAYzB,iBAAiBO,IAAI;oBACjCmB,OAAOxB,YAAY,IAAIF,iBAAiBgB,IAAI,CAACU,KAAK;oBAClDC,OAAO;oBACPC,gBAAgB;oBAChBC,YAAY;oBACZd;gBACF;gBAEA,IAAIQ,UAAUO,IAAI,IAAIP,UAAUO,IAAI,CAACC,MAAM,GAAG,GAAG;oBAC/C,MAAMC,OAAOT,UAAUO,IAAI,CAAC,EAAE;oBAC9BE,KAAMP,UAAU,GAAGzB,iBAAiBO,IAAI;oBACxCyB,KAAMC,SAAS,GAAG;oBAElB,OAAO;wBACLD,MAAMA;oBACR;gBACF;YACF,EAAE,OAAOE,QAAQ;gBACf,OAAO;oBAAEF,MAAM;gBAAK;YACtB;QACF;QAEA,OAAO;YAAEA,MAAM;QAAK;IACtB,EAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { SanitizedCollectionConfig } from '../../../collections/config/types.js';
|
|
2
|
-
import { type Payload, type
|
|
2
|
+
import { type Payload, type User } from '../../../index.js';
|
|
3
3
|
type Args = {
|
|
4
4
|
collection: SanitizedCollectionConfig;
|
|
5
5
|
payload: Payload;
|
|
6
|
-
user:
|
|
6
|
+
user: User;
|
|
7
7
|
};
|
|
8
8
|
export declare const incrementLoginAttempts: ({ collection, payload, user, }: Args) => Promise<void>;
|
|
9
9
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incrementLoginAttempts.d.ts","sourceRoot":"","sources":["../../../../src/auth/strategies/local/incrementLoginAttempts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAA;AAErF,OAAO,EAAmB,KAAK,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"incrementLoginAttempts.d.ts","sourceRoot":"","sources":["../../../../src/auth/strategies/local/incrementLoginAttempts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAA;AAErF,OAAO,EAAmB,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAG5E,KAAK,IAAI,GAAG;IACV,UAAU,EAAE,yBAAyB,CAAA;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,IAAI,CAAA;CACX,CAAA;AAID,eAAO,MAAM,sBAAsB,GAAU,gCAI1C,IAAI,KAAG,OAAO,CAAC,IAAI,CAuIrB,CAAA"}
|
|
@@ -92,7 +92,7 @@ export const incrementLoginAttempts = async ({ collection, payload, user })=>{
|
|
|
92
92
|
if (currentUser?.sessions?.length) {
|
|
93
93
|
// Does not hurt also removing expired sessions
|
|
94
94
|
currentUser.sessions = currentUser.sessions.filter((session)=>{
|
|
95
|
-
const sessionCreatedAt = new Date(session.createdAt);
|
|
95
|
+
const sessionCreatedAt = new Date(session.createdAt ?? 0);
|
|
96
96
|
const twentySecondsAgo = new Date(currentTime - 20000);
|
|
97
97
|
// Remove sessions created within the last 20 seconds
|
|
98
98
|
return sessionCreatedAt <= twentySecondsAgo;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/auth/strategies/local/incrementLoginAttempts.ts"],"sourcesContent":["import type { SanitizedCollectionConfig } from '../../../collections/config/types.js'\n\nimport { type JsonObject, type Payload, type
|
|
1
|
+
{"version":3,"sources":["../../../../src/auth/strategies/local/incrementLoginAttempts.ts"],"sourcesContent":["import type { SanitizedCollectionConfig } from '../../../collections/config/types.js'\n\nimport { type JsonObject, type Payload, type User } from '../../../index.js'\nimport { isUserLocked } from '../../isUserLocked.js'\n\ntype Args = {\n collection: SanitizedCollectionConfig\n payload: Payload\n user: User\n}\n\n// Note: this function does not use req in its updates, as we want those to be visible in parallel requests that are on a different\n// transaction. At the same time, we want updates from parallel requests to be visible here.\nexport const incrementLoginAttempts = async ({\n collection,\n payload,\n user,\n}: Args): Promise<void> => {\n const {\n auth: { lockTime, maxLoginAttempts },\n } = collection\n\n const currentTime = Date.now()\n\n let updatedLockUntil: null | string = null\n let updatedLoginAttempts: null | number = null\n\n if (user.lockUntil && !isUserLocked(new Date(user.lockUntil))) {\n // Expired lock, restart count at 1\n const updatedUser = await payload.db.updateOne({\n id: user.id,\n collection: collection.slug,\n data: {\n lockUntil: null,\n loginAttempts: 1,\n },\n select: {\n lockUntil: true,\n loginAttempts: true,\n },\n })\n updatedLockUntil = updatedUser.lockUntil\n updatedLoginAttempts = updatedUser.loginAttempts\n user.lockUntil = updatedLockUntil\n } else {\n const data: JsonObject = {\n loginAttempts: {\n $inc: 1,\n },\n }\n\n const willReachMaxAttempts =\n typeof user.loginAttempts === 'number' && user.loginAttempts + 1 >= maxLoginAttempts\n // Lock the account if at max attempts and not already locked\n if (willReachMaxAttempts) {\n const lockUntil = new Date(currentTime + lockTime).toISOString()\n data.lockUntil = lockUntil\n }\n\n const updatedUser = await payload.db.updateOne({\n id: user.id,\n collection: collection.slug,\n data,\n select: {\n lockUntil: true,\n loginAttempts: true,\n },\n })\n\n updatedLockUntil = updatedUser.lockUntil\n updatedLoginAttempts = updatedUser.loginAttempts\n }\n\n if (updatedLoginAttempts === null) {\n throw new Error('Failed to update login attempts or lockUntil for user')\n }\n\n // Check updated latest lockUntil and loginAttempts in case there were parallel updates\n const reachedMaxAttemptsForCurrentUser =\n typeof updatedLoginAttempts === 'number' && updatedLoginAttempts - 1 >= maxLoginAttempts\n\n const reachedMaxAttemptsForNextUser =\n typeof updatedLoginAttempts === 'number' && updatedLoginAttempts >= maxLoginAttempts\n\n if (reachedMaxAttemptsForCurrentUser) {\n user.lockUntil = updatedLockUntil\n }\n user.loginAttempts = updatedLoginAttempts - 1 // -1, as the updated increment is applied for the *next* login attempt, not the current one\n\n if (\n reachedMaxAttemptsForNextUser &&\n (!updatedLockUntil || !isUserLocked(new Date(updatedLockUntil)))\n ) {\n // If lockUntil reached max login attempts due to multiple parallel attempts but user was not locked yet,\n const newLockUntil = new Date(currentTime + lockTime).toISOString()\n\n await payload.db.updateOne({\n id: user.id,\n collection: collection.slug,\n data: {\n lockUntil: newLockUntil,\n },\n returning: false,\n })\n\n if (reachedMaxAttemptsForCurrentUser) {\n user.lockUntil = newLockUntil\n }\n\n if (collection.auth.useSessions) {\n // Remove all active sessions that have been created in a 20 second window. This protects\n // against brute force attacks - example: 99 incorrect, 1 correct parallel login attempts.\n // The correct login attempt will be finished first, as it's faster due to not having to perform\n // an additional db update here.\n // However, this request (the incorrect login attempt request) can kill the successful login attempt here.\n\n // Fetch user sessions separately (do not do this in the updateOne select in order to preserve the returning: true db call optimization)\n const currentUser = await payload.db.findOne<User>({\n collection: collection.slug,\n select: {\n sessions: true,\n },\n where: {\n id: {\n equals: user.id,\n },\n },\n })\n if (currentUser?.sessions?.length) {\n // Does not hurt also removing expired sessions\n currentUser.sessions = currentUser.sessions.filter((session) => {\n const sessionCreatedAt = new Date(session.createdAt ?? 0)\n const twentySecondsAgo = new Date(currentTime - 20000)\n\n // Remove sessions created within the last 20 seconds\n return sessionCreatedAt <= twentySecondsAgo\n })\n\n user.sessions = currentUser.sessions\n\n // Ensure updatedAt date is always updated\n user.updatedAt = new Date().toISOString()\n\n await payload.db.updateOne({\n id: user.id,\n collection: collection.slug,\n data: user,\n returning: false,\n })\n }\n }\n }\n}\n"],"names":["isUserLocked","incrementLoginAttempts","collection","payload","user","auth","lockTime","maxLoginAttempts","currentTime","Date","now","updatedLockUntil","updatedLoginAttempts","lockUntil","updatedUser","db","updateOne","id","slug","data","loginAttempts","select","$inc","willReachMaxAttempts","toISOString","Error","reachedMaxAttemptsForCurrentUser","reachedMaxAttemptsForNextUser","newLockUntil","returning","useSessions","currentUser","findOne","sessions","where","equals","length","filter","session","sessionCreatedAt","createdAt","twentySecondsAgo","updatedAt"],"mappings":"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"}
|