Skip to content

Commit

Permalink
Merge pull request #57 from uwblueprint/LoginError
Browse files Browse the repository at this point in the history
Login error
  • Loading branch information
carolynzhang18 authored Aug 14, 2024
2 parents 7ee24c2 + 4a4fa6f commit 39fcb20
Show file tree
Hide file tree
Showing 12 changed files with 673 additions and 574 deletions.
35 changes: 33 additions & 2 deletions backend/rest/authRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import IAuthService from "../services/interfaces/authService";
import IEmailService from "../services/interfaces/emailService";
import IUserService from "../services/interfaces/userService";
import { getErrorMessage } from "../utilities/errorUtils";
import { AuthErrorCodes } from "../types/authTypes";

const authRouter: Router = Router();
const userService: IUserService = new UserService();
Expand All @@ -35,20 +36,50 @@ const cookieOptions: CookieOptions = {

/* Returns access token and user info in response body and sets refreshToken as an httpOnly cookie */
authRouter.post("/login", loginRequestValidator, async (req, res) => {
const requestedRole = req.body.attemptedRole;
let correctRole = null;
try {
const authDTO = await authService.generateToken(
req.body.email,
req.body.password,
);

const { refreshToken, ...rest } = authDTO;
const { accessToken, refreshToken, ...rest } = authDTO;
correctRole = rest.role;

if (correctRole !== requestedRole) {
throw new Error(AuthErrorCodes.WRONG_USER_TYPE);
}

const isVerified = await authService.isAuthorizedByEmail(
accessToken,
req.body.email,
);

if (!isVerified) {
throw new Error(AuthErrorCodes.UNVERIFIED_EMAIL);
}

res
.cookie("refreshToken", refreshToken, cookieOptions)
.status(200)
.json(rest);
} catch (error: unknown) {
res.status(500).json({ error: getErrorMessage(error) });
const message = getErrorMessage(error);
if (
req.body.attemptedRole !== "Learner" &&
(message === AuthErrorCodes.EMAIL_NOT_FOUND ||
message === AuthErrorCodes.INCORRECT_PASSWORD)
) {
res.status(500).json({ error: AuthErrorCodes.INVALID_LOGIN_CREDENTIALS });
} else if (message === AuthErrorCodes.WRONG_USER_TYPE) {
res.status(500).json({
error: message,
errorData: [requestedRole, correctRole],
});
} else {
res.status(500).json({ error: message });
}
}
});

Expand Down
2 changes: 1 addition & 1 deletion backend/services/implementations/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ class AuthService implements IAuthService {
/* eslint-disable class-methods-use-this */
async generateToken(email: string, password: string): Promise<AuthDTO> {
try {
const user = await this.userService.getUserByEmail(email);
const token = await FirebaseRestClient.signInWithPassword(
email,
password,
);
const user = await this.userService.getUserByEmail(email);
return { ...token, ...user };
} catch (error) {
Logger.error(`Failed to generate token for user with email ${email}`);
Expand Down
3 changes: 2 additions & 1 deletion backend/services/implementations/userService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
UpdateUserDTO,
UserDTO,
} from "../../types/userTypes";
import { AuthErrorCodes } from "../../types/authTypes";
import { getErrorMessage } from "../../utilities/errorUtils";
import logger from "../../utilities/logger";

Expand Down Expand Up @@ -59,7 +60,7 @@ class UserService implements IUserService {
}
} catch (error: unknown) {
Logger.error(`Failed to get user. Reason = ${getErrorMessage(error)}`);
throw new Error("EMAIL_NOT_FOUND");
throw new Error(AuthErrorCodes.EMAIL_NOT_FOUND);
}

return {
Expand Down
8 changes: 8 additions & 0 deletions backend/types/authTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ export type NodemailerConfig = {
refreshToken: string;
};
};

export enum AuthErrorCodes {
INVALID_LOGIN_CREDENTIALS = "INVALID_LOGIN_CREDENTIALS",
UNVERIFIED_EMAIL = "UNVERIFIED_EMAIL",
WRONG_USER_TYPE = "WRONG_USER_TYPE",
EMAIL_NOT_FOUND = "EMAIL_NOT_FOUND",
INCORRECT_PASSWORD = "INCORRECT_PASSWORD",
}
13 changes: 9 additions & 4 deletions backend/utilities/firebaseRestClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fetch, { Response } from "node-fetch";

import { Token } from "../types/authTypes";
import { AuthErrorCodes, Token } from "../types/authTypes";
import logger from "./logger";

const Logger = logger(__filename);
Expand Down Expand Up @@ -62,15 +62,20 @@ const FirebaseRestClient = {
await response.json();

if (!response.ok) {
const firebaseErrorMessage = (responseJson as RequestError).error.message;

const errorMessage = [
"Failed to sign-in via Firebase REST API, status code =",
`${response.status},`,
"error message =",
(responseJson as RequestError).error.message,
firebaseErrorMessage,
];
Logger.error(errorMessage.join(" "));

throw new Error("Failed to sign-in via Firebase REST API");
if (firebaseErrorMessage === "INVALID_LOGIN_CREDENTIALS") {
throw new Error(AuthErrorCodes.INCORRECT_PASSWORD);
} else {
throw new Error("Failed to sign-in via Firebase REST API");
}
}

return {
Expand Down
Loading

0 comments on commit 39fcb20

Please sign in to comment.