start user tests, improved user error messages
This commit is contained in:
@@ -127,11 +127,6 @@ class UserController {
|
||||
};
|
||||
|
||||
createUser = async (req: RequestType, res: Response, next: NextFunction) => {
|
||||
if (env.createAcctBlocked) {
|
||||
res.status(401).send();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const currentUUID = req.headers.uuid as string;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export const createAccountValidationRules = [
|
||||
.withMessage("Email is required")
|
||||
.isString()
|
||||
.withMessage("Email must be a string")
|
||||
.isLength({ min: 1, max: 256 })
|
||||
.isEmail()
|
||||
.withMessage("Email is invalid"),
|
||||
body("password")
|
||||
|
||||
@@ -6,6 +6,7 @@ import NotFoundError from "../../utils/NotFoundError";
|
||||
import InternalServerError from "../../utils/InternalServerError";
|
||||
import ForbiddenError from "../../utils/ForbiddenError";
|
||||
import NotValidDataError from "../../utils/NotValidDataError";
|
||||
import ConflictError from "../../utils/ConflictError";
|
||||
|
||||
export const middlewareValidationFunction = (
|
||||
req: Request,
|
||||
@@ -32,7 +33,8 @@ export const middlewareErrorHandler = (
|
||||
error instanceof ForbiddenError ||
|
||||
error instanceof NotFoundError ||
|
||||
error instanceof InternalServerError ||
|
||||
error instanceof NotValidDataError
|
||||
error instanceof NotValidDataError ||
|
||||
error instanceof ConflictError
|
||||
) {
|
||||
return res.status(error.code).send(error.message);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import crypto from "crypto";
|
||||
import bcrypt from "bcrypt";
|
||||
import jwt from "jsonwebtoken";
|
||||
import env from "../enviroment/env";
|
||||
import NotAuthorizedError from "../utils/NotAuthorizedError";
|
||||
|
||||
const userSchema = new mongoose.Schema(
|
||||
{
|
||||
@@ -131,13 +132,13 @@ userSchema.statics.findByCreds = async (email: string, password: string) => {
|
||||
const user = await User.findOne({ email });
|
||||
|
||||
if (!user) {
|
||||
throw new Error("User not found");
|
||||
throw new NotAuthorizedError("User not found");
|
||||
}
|
||||
|
||||
const isMatch = await bcrypt.compare(password, user.password);
|
||||
|
||||
if (!isMatch) {
|
||||
throw new Error("Incorrect password");
|
||||
throw new NotAuthorizedError("Incorrect password");
|
||||
}
|
||||
|
||||
return user;
|
||||
|
||||
@@ -9,6 +9,7 @@ import jwt from "jsonwebtoken";
|
||||
import sendVerificationEmail from "../../utils/sendVerificationEmail";
|
||||
import sendPasswordResetEmail from "../../utils/sendPasswordResetEmail";
|
||||
import ForbiddenError from "../../utils/ForbiddenError";
|
||||
import ConflictError from "../../utils/ConflictError";
|
||||
|
||||
type UserDataType = {
|
||||
email: string;
|
||||
@@ -85,6 +86,16 @@ class UserService {
|
||||
};
|
||||
|
||||
create = async (userData: any, uuid: string | undefined) => {
|
||||
if (env.createAcctBlocked) {
|
||||
throw new ForbiddenError("Account Creation Blocked");
|
||||
}
|
||||
|
||||
const userExistsLookedUp = await User.findOne({ email: userData.email });
|
||||
|
||||
if (userExistsLookedUp) {
|
||||
throw new ConflictError("Email Already Exists");
|
||||
}
|
||||
|
||||
const user = new User({
|
||||
email: userData.email,
|
||||
password: userData.password,
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
class ConflictError extends Error {
|
||||
code: number;
|
||||
|
||||
constructor(args: any) {
|
||||
super(args);
|
||||
|
||||
this.code = 409;
|
||||
}
|
||||
}
|
||||
|
||||
export default ConflictError;
|
||||
@@ -13,6 +13,7 @@ import AlertIcon from "../../icons/AlertIcon";
|
||||
import Spinner from "../Spinner/Spinner";
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
import Swal from "sweetalert2";
|
||||
import { AxiosError } from "axios";
|
||||
|
||||
const LoginPage = () => {
|
||||
const [email, setEmail] = useState("");
|
||||
@@ -55,9 +56,13 @@ const LoginPage = () => {
|
||||
navigate("/home");
|
||||
setLoadingLogin(false);
|
||||
} catch (e) {
|
||||
if (e instanceof AxiosError && e.response?.status === 401) {
|
||||
setError("Incorrect email or password");
|
||||
} else {
|
||||
setError("Login Error");
|
||||
}
|
||||
console.log("Login Error", e);
|
||||
setLoadingLogin(false);
|
||||
setError("Login Failed");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,9 +80,13 @@ const LoginPage = () => {
|
||||
navigate("/home");
|
||||
setLoadingLogin(false);
|
||||
} catch (e) {
|
||||
if (e instanceof AxiosError && e.response?.status === 409) {
|
||||
setError("Email Already Exists");
|
||||
} else {
|
||||
setError("Create Account Error");
|
||||
}
|
||||
console.log("Create Account Error", e);
|
||||
setLoadingLogin(false);
|
||||
setError("Create Account Failed");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
const request = require("supertest");
|
||||
const app = require("../utils/express-app");
|
||||
const mongoose = require("mongoose");
|
||||
const { MongoMemoryServer } = require("mongodb-memory-server");
|
||||
const getEnvVariables = require("../../dist-backend/enviroment/get-env-variables");
|
||||
const getKey = require("../../dist-backend/key/get-key").default;
|
||||
getEnvVariables();
|
||||
const env = require("../../dist-backend/enviroment/env");
|
||||
const { envFileFix } = require("../utils/db-setup");
|
||||
const { ObjectId } = require("mongodb");
|
||||
|
||||
let mongoServer;
|
||||
let authToken;
|
||||
let authToken2;
|
||||
let file;
|
||||
let file2;
|
||||
let user;
|
||||
let user2;
|
||||
|
||||
describe("File Controller", () => {
|
||||
beforeAll(async () => {
|
||||
envFileFix(env);
|
||||
await getKey();
|
||||
mongoServer = await MongoMemoryServer.create();
|
||||
await mongoose.connect(mongoServer.getUri(), { useNewUrlParser: true });
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await mongoose.model("fs.files").deleteMany({});
|
||||
await mongoose.model("Folder").deleteMany({});
|
||||
await mongoose.model("User").deleteMany({});
|
||||
|
||||
user = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "test@test.com",
|
||||
password: "test1234",
|
||||
})
|
||||
.set("uuid", 12314123123);
|
||||
|
||||
user2 = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "test@test2.com",
|
||||
password: "test1234",
|
||||
})
|
||||
.set("uuid", 12314123124);
|
||||
|
||||
authToken = user.headers["set-cookie"]
|
||||
.map((cookie) => cookie.split(";")[0])
|
||||
.join("; ");
|
||||
|
||||
authToken2 = user2.headers["set-cookie"]
|
||||
.map((cookie) => cookie.split(";")[0])
|
||||
.join("; ");
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await mongoose.disconnect();
|
||||
await mongoServer.stop();
|
||||
});
|
||||
|
||||
describe("User info: GET /user-service/user", () => {
|
||||
test("Should return user info", async () => {
|
||||
const userResponse = await request(app)
|
||||
.get(`/user-service/user`)
|
||||
.set("Cookie", authToken);
|
||||
|
||||
expect(userResponse.status).toBe(200);
|
||||
expect(userResponse.body.email).toBe(user.body.user.email);
|
||||
});
|
||||
test("Should return 401 if not authorized", async () => {
|
||||
const userResponse = await request(app)
|
||||
.get(`/user-service/user`)
|
||||
.set("Cookie", "access-token=test");
|
||||
|
||||
expect(userResponse.status).toBe(401);
|
||||
});
|
||||
});
|
||||
describe("User login: POST /user-service/login", () => {
|
||||
test("Should login user", async () => {
|
||||
const userResponse = await request(app).post("/user-service/login").send({
|
||||
email: user.body.user.email,
|
||||
password: "test1234",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(200);
|
||||
expect(userResponse.body.user.email).toBe(user.body.user.email);
|
||||
});
|
||||
test("Should return 401 if incorrect password", async () => {
|
||||
const userResponse = await request(app).post("/user-service/login").send({
|
||||
email: user.body.user.email,
|
||||
password: "test12345",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(401);
|
||||
});
|
||||
test("Should return 401 if incorrect email", async () => {
|
||||
const userResponse = await request(app).post("/user-service/login").send({
|
||||
email: "notexist@test.com",
|
||||
password: "test1234",
|
||||
});
|
||||
expect(userResponse.status).toBe(401);
|
||||
});
|
||||
});
|
||||
describe("Create User: POST /user-service/create", () => {
|
||||
test("Should create user", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "newuser@test.com",
|
||||
password: "test1234",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(201);
|
||||
|
||||
const userDbCheck = await mongoose.model("User").findOne({
|
||||
_id: userResponse.body.user._id,
|
||||
});
|
||||
|
||||
expect(userDbCheck.email).toBe(userResponse.body.user.email);
|
||||
});
|
||||
test("Should return 400 if no email", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
password: "test1234",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(400);
|
||||
});
|
||||
test("Should return 400 if no password", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "newuser@test.com",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(400);
|
||||
});
|
||||
test("Should return 400 if email length is less than 1", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "",
|
||||
password: "test1234",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(400);
|
||||
});
|
||||
test("Should return 400 if email length is greater than 256", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "a" * 257,
|
||||
password: "test1234",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(400);
|
||||
});
|
||||
test("Should return 400 if password length is less than 6", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "newuser@test.com",
|
||||
password: "",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(400);
|
||||
});
|
||||
test("Should return 400 if password length is greater than 256", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "newuser@test.com",
|
||||
password: "a" * 257,
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(400);
|
||||
});
|
||||
test("Should return 409 if email already exists", async () => {
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "test@test.com",
|
||||
password: "test1234",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(409);
|
||||
});
|
||||
test("Should return 403 if create account is blocked", async () => {
|
||||
env.createAcctBlocked = true;
|
||||
|
||||
const userResponse = await request(app)
|
||||
.post("/user-service/create")
|
||||
.send({
|
||||
email: "newemail@test.com",
|
||||
password: "test1234",
|
||||
});
|
||||
|
||||
expect(userResponse.status).toBe(403);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user