Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…awa-api into action-items
  • Loading branch information
meetulr committed Feb 18, 2024
2 parents c7ea0f4 + a083377 commit cb126c3
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 152 deletions.
28 changes: 14 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 2 additions & 32 deletions src/resolvers/Mutation/forgotPassword.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import bcrypt from "bcryptjs";
import { jwtDecode } from "jwt-decode";
import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { INVALID_OTP } from "../../constants";
import { User } from "../../models";
import {
ACCESS_TOKEN_SECRET,
INVALID_OTP,
USER_NOT_FOUND_ERROR,
} from "../../constants";
import jwt from "jsonwebtoken";

import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
/**
* This function enables a user to restore password.
* @param _parent - parent of current request
Expand All @@ -26,14 +20,7 @@ export const forgotPassword: MutationResolvers["forgotPassword"] = async (
) => {
const { userOtp, newPassword, otpToken } = args.data;

try {
await jwt.verify(otpToken, ACCESS_TOKEN_SECRET as string);
} catch (error) {
throw new Error(INVALID_OTP);
}

// Extracts email and otp out of otpToken.

const { email, otp } = jwtDecode<{
email: string;
otp: string;
Expand All @@ -47,23 +34,6 @@ export const forgotPassword: MutationResolvers["forgotPassword"] = async (
throw new Error(INVALID_OTP);
}

const user = await User.findOne({ email }).lean();

if (!user) {
throw new Error(USER_NOT_FOUND_ERROR.MESSAGE);
}
const oldHashedPassword: string = user.password;

//Checks whether the old password is same as the new one
const isSameAsOldPassword = await bcrypt.compare(
newPassword,
oldHashedPassword
);

if (isSameAsOldPassword == true) {
throw new Error("New password cannot be same as old password");
}

const hashedPassword = await bcrypt.hash(newPassword, 12);

// Updates password field for user's document with email === email.
Expand Down
110 changes: 4 additions & 106 deletions tests/resolvers/Mutation/forgotPassword.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-explicit-any */
import "dotenv/config";
import type { MutationForgotPasswordArgs } from "../../../src/types/generatedGraphQLTypes";
import { connect, disconnect } from "../../helpers/db";
import type mongoose from "mongoose";
import { forgotPassword as forgotPasswordResolver } from "../../../src/resolvers/Mutation/forgotPassword";
import {
INVALID_OTP,
ACCESS_TOKEN_SECRET,
USER_NOT_FOUND_ERROR,
} from "../../../src/constants";
import { INVALID_OTP } from "../../../src/constants";
import jwt from "jsonwebtoken";
import bcrypt from "bcryptjs";
import { beforeAll, afterAll, describe, it, expect } from "vitest";
Expand Down Expand Up @@ -37,7 +31,7 @@ describe("resolvers -> Mutation -> forgotPassword", () => {
email: testUser?.email ?? "",
otp: "otp",
},
ACCESS_TOKEN_SECRET as string,
process.env.NODE_ENV!,
{
expiresIn: 99999999,
},
Expand All @@ -57,101 +51,6 @@ describe("resolvers -> Mutation -> forgotPassword", () => {
}
});

//added ths test
it(`throws Error if newPassword is the same as the old password`, async () => {
const otp = "correctOtp";

const hashedOtp = await bcrypt.hash(otp, 1);

const otpToken = jwt.sign(
{
email: testUser?.email ?? "",
otp: hashedOtp,
},
ACCESS_TOKEN_SECRET as string,
{
expiresIn: 99999999,
}
);

const args: MutationForgotPasswordArgs = {
data: {
newPassword: testUser?.password ?? "", // Using optional chaining and nullish coalescing
otpToken,
userOtp: otp,
},
};

try {
await forgotPasswordResolver?.({}, args, {});
} catch (error: any) {
expect(error.message).toEqual(
"New password cannot be same as old password"
);
}
});
it("throws an error when the email is changed in the token", async () => {
const otp = "correctOtp";

const hashedOtp = await bcrypt.hash(otp, 1);

// Sign the token
const otpToken = jwt.sign(
{
email: testUser?.email ?? "",
otp: hashedOtp,
},
process.env.NODE_ENV ?? "",
{
expiresIn: 99999999,
}
);

const args: MutationForgotPasswordArgs = {
data: {
newPassword: testUser?.password ?? "", // Using optional chaining and nullish coalescing
otpToken,
userOtp: otp,
},
};

try {
await forgotPasswordResolver?.({}, args, {});
} catch (error: any) {
expect(error.message).toEqual(INVALID_OTP);
}
});
it(`throws an error when the user is not found`, async () => {
const otp = "correctOtp";

const hashedOtp = await bcrypt.hash(otp, 1);

// Sign the token with an email that doesn't exist
const otpToken = jwt.sign(
{
email: "nonexistent@example.com", // An email that doesn't exist
otp: hashedOtp,
},
ACCESS_TOKEN_SECRET as string,
{
expiresIn: 99999999,
}
);

const args: MutationForgotPasswordArgs = {
data: {
newPassword: "newPassword",
otpToken,
userOtp: otp,
},
};

try {
await forgotPasswordResolver?.({}, args, {});
} catch (error: any) {
expect(error.message).toEqual(USER_NOT_FOUND_ERROR.MESSAGE);
}
});
it(`changes the password if args.otp is correct`, async () => {
const otp = "otp";

Expand All @@ -162,7 +61,7 @@ describe("resolvers -> Mutation -> forgotPassword", () => {
email: testUser?.email ?? "",
otp: hashedOtp,
},
ACCESS_TOKEN_SECRET as string,
process.env.NODE_ENV ?? "",
{
expiresIn: 99999999,
},
Expand All @@ -180,14 +79,13 @@ describe("resolvers -> Mutation -> forgotPassword", () => {

expect(forgotPasswordPayload).toEqual(true);

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const updatedTestUser = await User!
.findOne({
_id: testUser?._id ?? "",
})
.select(["password"])
.lean();

expect(updatedTestUser?.password).not.toEqual(testUser?.password);
expect(updatedTestUser?.password).not.toEqual(testUser!.password);
});
});

0 comments on commit cb126c3

Please sign in to comment.