UNPKG

payload

Version:

Node, React, Headless CMS and Application Framework built on Next.js

112 lines (111 loc) 4.12 kB
import { status as httpStatus } from 'http-status'; import { APIError, Forbidden } from '../../errors/index.js'; import { commitTransaction } from '../../utilities/commitTransaction.js'; import { initTransaction } from '../../utilities/initTransaction.js'; import { killTransaction } from '../../utilities/killTransaction.js'; import { getFieldsToSign } from '../getFieldsToSign.js'; import { jwtSign } from '../jwt.js'; import { authenticateLocalStrategy } from '../strategies/local/authenticate.js'; import { generatePasswordSaltHash } from '../strategies/local/generatePasswordSaltHash.js'; export const resetPasswordOperation = async (args)=>{ const { collection: { config: collectionConfig }, data, depth, overrideAccess, req: { payload: { secret }, payload }, req } = args; if (!Object.prototype.hasOwnProperty.call(data, 'token') || !Object.prototype.hasOwnProperty.call(data, 'password')) { throw new APIError('Missing required data.', httpStatus.BAD_REQUEST); } if (collectionConfig.auth.disableLocalStrategy) { throw new Forbidden(req.t); } try { const shouldCommit = await initTransaction(req); // ///////////////////////////////////// // Reset Password // ///////////////////////////////////// const user = await payload.db.findOne({ collection: collectionConfig.slug, req, where: { resetPasswordExpiration: { greater_than: new Date().toISOString() }, resetPasswordToken: { equals: data.token } } }); if (!user) { throw new APIError('Token is either invalid or has expired.', httpStatus.FORBIDDEN); } // TODO: replace this method const { hash, salt } = await generatePasswordSaltHash({ collection: collectionConfig, password: data.password, req }); user.salt = salt; user.hash = hash; user.resetPasswordExpiration = new Date().toISOString(); if (collectionConfig.auth.verify) { user._verified = Boolean(user._verified); } // ///////////////////////////////////// // beforeValidate - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.beforeValidate?.length) { for (const hook of collectionConfig.hooks.beforeValidate){ await hook({ collection: args.collection?.config, context: req.context, data: user, operation: 'update', req }); } } // ///////////////////////////////////// // Update new password // ///////////////////////////////////// const doc = await payload.db.updateOne({ id: user.id, collection: collectionConfig.slug, data: user, req }); await authenticateLocalStrategy({ doc, password: data.password }); const fieldsToSign = getFieldsToSign({ collectionConfig, email: user.email, user }); const { token } = await jwtSign({ fieldsToSign, secret, tokenExpiration: collectionConfig.auth.tokenExpiration }); const fullUser = await payload.findByID({ id: user.id, collection: collectionConfig.slug, depth, overrideAccess, req }); if (shouldCommit) { await commitTransaction(req); } if (fullUser) { fullUser.collection = collectionConfig.slug; fullUser._strategy = 'local-jwt'; } const result = { token, user: fullUser }; return result; } catch (error) { await killTransaction(req); throw error; } }; //# sourceMappingURL=resetPassword.js.map