payload
Version:
Node, React, Headless CMS and Application Framework built on Next.js
112 lines (111 loc) • 4.12 kB
JavaScript
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