Skip to content
This repository was archived by the owner on Apr 19, 2023. It is now read-only.

Commit bd33c98

Browse files
✨ Add support for auth/login
1 parent 4d5d150 commit bd33c98

File tree

7 files changed

+54
-10
lines changed

7 files changed

+54
-10
lines changed

src/helpers/jwt.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ export const generateToken = (
99
) =>
1010
new Promise((resolve, reject) => {
1111
sign(
12-
payload,
12+
// Payload is expected to be a plain object
13+
JSON.parse(JSON.stringify(payload)),
1314
JWT_SECRET,
1415
{
1516
expiresIn,

src/helpers/middleware.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const errorHandler = (
99
res: Response,
1010
next: NextFunction
1111
) => {
12-
console.log(error);
12+
console.log(error.toString());
1313
const response = safeError(error.toString().replace("Error: ", ""));
1414
res.status(response.status);
1515
res.json({ error: response.code, message: response.message });

src/helpers/mysql.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { BackupCode } from "../interfaces/tables/backup-codes";
1111
import { Email } from "../interfaces/tables/emails";
1212
import { Membership } from "../interfaces/tables/memberships";
1313
import { Organization } from "../interfaces/tables/organization";
14+
import { Event } from "../interfaces/tables/events";
1415

1516
export const pool = createPool({
1617
host: DB_HOST,

src/interfaces/enum.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ export enum ErrorCode {
3131
MISSING_PASSWORD = "422/missing-password",
3232
MISSING_FIELD = "422/missing-field",
3333
USER_NOT_FOUND = "404/user-not-found",
34-
INVALID_LOGIN = "301/invalid-login",
34+
INVALID_LOGIN = "401/invalid-login",
3535
DEFAULT = "500/server-error"
3636
}

src/rest/auth.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { KeyValue, Locals } from "../interfaces/general";
1313
import { createEvent } from "../crud/event";
1414
import { EventType, ErrorCode, UserRole } from "../interfaces/enum";
15-
import { compare } from "bcrypt";
15+
import { compare, hash } from "bcrypt";
1616
import { deleteSensitiveInfoUser } from "../helpers/utils";
1717
import { createMembership } from "../crud/membership";
1818

@@ -83,7 +83,8 @@ export const sendPasswordReset = async (email: string, locals: Locals) => {
8383
await createEvent(
8484
{
8585
userId: user.id,
86-
type: EventType.AUTH_PASSWORD_RESET_REQUESTED
86+
type: EventType.AUTH_PASSWORD_RESET_REQUESTED,
87+
data: { token }
8788
},
8889
locals
8990
);
@@ -103,3 +104,21 @@ export const verifyEmail = async (token: string, locals: Locals) => {
103104
);
104105
return await updateEmail(emailId, { isVerified: true });
105106
};
107+
108+
export const updatePassword = async (
109+
token: string,
110+
password: string,
111+
locals: Locals
112+
) => {
113+
const userId = (<KeyValue>await verifyToken(token, "password-reset")).id;
114+
const hashedPassword = await hash(password || "", 8);
115+
await updateUser(userId, { password: hashedPassword });
116+
await createEvent(
117+
{
118+
userId,
119+
type: EventType.AUTH_PASSWORD_CHANGED
120+
},
121+
locals
122+
);
123+
return;
124+
};

src/routes/auth.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Request, Response } from "express";
22
import { ErrorCode } from "../interfaces/enum";
3-
import { sendPasswordReset, login } from "../rest/auth";
3+
import { sendPasswordReset, login, updatePassword } from "../rest/auth";
44
import { verifyToken } from "../helpers/jwt";
55

66
export const routeAuthVerifyToken = async (req: Request, res: Response) => {
@@ -28,9 +28,24 @@ export const routeAuthLogin = async (req: Request, res: Response) => {
2828
}
2929
};
3030

31-
export const routeAuthResetPassword = async (req: Request, res: Response) => {
31+
export const routeAuthResetPasswordRequest = async (
32+
req: Request,
33+
res: Response
34+
) => {
3235
const email = req.body && req.body.email;
3336
if (!email) throw new Error(ErrorCode.MISSING_FIELD);
3437
res.json({ queued: true });
3538
return await sendPasswordReset(email, res.locals);
3639
};
40+
41+
export const routeAuthResetPasswordRecover = async (
42+
req: Request,
43+
res: Response
44+
) => {
45+
const token =
46+
req.body.token || (req.get("Authorization") || "").replace("Bearer ", "");
47+
const password = req.body.password;
48+
if (!token || !password) throw new Error(ErrorCode.MISSING_FIELD);
49+
await updatePassword(token, password, res.locals);
50+
res.json({ success: true });
51+
};

src/routes/index.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { routeEmailVerify } from "./emails";
55
import { routeOrganizationCreate } from "./organizations";
66
import { authHandler } from "../helpers/middleware";
77
import {
8-
routeAuthResetPassword,
98
routeAuthVerifyToken,
10-
routeAuthLogin
9+
routeAuthLogin,
10+
routeAuthResetPasswordRequest,
11+
routeAuthResetPasswordRecover
1112
} from "./auth";
1213

1314
export const router = (app: Application) => {
@@ -24,7 +25,14 @@ export const router = (app: Application) => {
2425
const routesAuth = (app: Application) => {
2526
app.post("/auth/login", asyncHandler(routeAuthLogin));
2627
app.post("/auth/verify-token", asyncHandler(routeAuthVerifyToken));
27-
app.post("/auth/reset-password", asyncHandler(routeAuthResetPassword));
28+
app.post(
29+
"/auth/reset-password/request",
30+
asyncHandler(routeAuthResetPasswordRequest)
31+
);
32+
app.post(
33+
"/auth/reset-password/recover",
34+
asyncHandler(routeAuthResetPasswordRecover)
35+
);
2836
};
2937

3038
const routesUser = (app: Application) => {

0 commit comments

Comments
 (0)