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

Commit 4d5d150

Browse files
✨ Add login
1 parent 9b661c6 commit 4d5d150

File tree

5 files changed

+60
-13
lines changed

5 files changed

+60
-13
lines changed

src/helpers/mail.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const mail = async (
4242
return await sendMail({
4343
from: SES_EMAIL,
4444
to: to.toString(),
45-
subject: i18n.en.emails[template],
45+
subject: i18n.en.emails[template] || "",
4646
message,
4747
altText
4848
});

src/interfaces/enum.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export enum EventType {
1414
AUTH_LOGIN_BACKUP_CODE = "auth.login_backupCode",
1515
AUTH_LOGIN_GOOGLE = "auth.login_google",
1616
AUTH_PASSWORD_CHANGED = "auth.password_changed",
17+
AUTH_PASSWORD_RESET_REQUESTED = "auth.passwordReset",
1718
ORGANIZATION_CREATED = "organization.created",
1819
ORGANIZATION_UPDATED = "organization.updated",
1920
ORGANIZATION_DELETED = "organization.deleted",

src/rest/auth.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import { User } from "../interfaces/tables/user";
22
import { createUser, updateUser, getUserByEmail, getUser } from "../crud/user";
33
import { InsertResult } from "../interfaces/mysql";
4-
import {
5-
createEmail,
6-
updateEmail,
7-
getEmail,
8-
getUserPrimaryEmail
9-
} from "../crud/email";
4+
import { createEmail, updateEmail, getEmail } from "../crud/email";
105
import { mail } from "../helpers/mail";
116
import {
127
emailVerificationToken,
@@ -21,11 +16,22 @@ import { compare } from "bcrypt";
2116
import { deleteSensitiveInfoUser } from "../helpers/utils";
2217
import { createMembership } from "../crud/membership";
2318

24-
export const login = async (email: string, password: string) => {
19+
export const login = async (
20+
email: string,
21+
password: string,
22+
locals: Locals
23+
) => {
2524
const user = await getUserByEmail(email, true);
2625
if (!user.password) throw new Error(ErrorCode.MISSING_PASSWORD);
2726
const correctPassword = await compare(password, user.password);
2827
if (correctPassword) {
28+
await createEvent(
29+
{
30+
userId: user.id,
31+
type: EventType.AUTH_LOGIN
32+
},
33+
locals
34+
);
2935
return await loginToken(deleteSensitiveInfoUser(user));
3036
}
3137
throw new Error(ErrorCode.INVALID_LOGIN);
@@ -69,11 +75,19 @@ export const sendEmailVerification = async (
6975
return;
7076
};
7177

72-
export const sendPasswordReset = async (email: string) => {
78+
export const sendPasswordReset = async (email: string, locals: Locals) => {
7379
const user = await getUserByEmail(email);
7480
if (!user.id) throw new Error(ErrorCode.USER_NOT_FOUND);
7581
const token = await passwordResetToken(user.id);
76-
return await mail(email, "password-reset", { name: user.name, token });
82+
await mail(email, "password-reset", { name: user.name, token });
83+
await createEvent(
84+
{
85+
userId: user.id,
86+
type: EventType.AUTH_PASSWORD_RESET_REQUESTED
87+
},
88+
locals
89+
);
90+
return;
7791
};
7892

7993
export const verifyEmail = async (token: string, locals: Locals) => {

src/routes/auth.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,36 @@
11
import { Request, Response } from "express";
22
import { ErrorCode } from "../interfaces/enum";
3-
import { sendPasswordReset } from "../rest/auth";
3+
import { sendPasswordReset, login } from "../rest/auth";
4+
import { verifyToken } from "../helpers/jwt";
5+
6+
export const routeAuthVerifyToken = async (req: Request, res: Response) => {
7+
const token =
8+
req.body.token || (req.get("Authorization") || "").replace("Bearer ", "");
9+
const subject = req.body.subject;
10+
if (!token || !subject) throw new Error(ErrorCode.MISSING_FIELD);
11+
try {
12+
const data = await verifyToken(token, subject);
13+
res.json({ verified: true, data });
14+
} catch (error) {
15+
throw new Error(ErrorCode.INVALID_TOKEN);
16+
}
17+
};
18+
19+
export const routeAuthLogin = async (req: Request, res: Response) => {
20+
const email = req.body.email;
21+
const password = req.body.password;
22+
if (!email || !password) throw new Error(ErrorCode.MISSING_FIELD);
23+
try {
24+
const token = await login(email, password, res.locals);
25+
res.json({ token });
26+
} catch (error) {
27+
throw new Error(ErrorCode.INVALID_LOGIN);
28+
}
29+
};
430

531
export const routeAuthResetPassword = async (req: Request, res: Response) => {
632
const email = req.body && req.body.email;
733
if (!email) throw new Error(ErrorCode.MISSING_FIELD);
834
res.json({ queued: true });
9-
return await sendPasswordReset(email);
35+
return await sendPasswordReset(email, res.locals);
1036
};

src/routes/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { routeUserMe, routeUserPut } from "./users";
44
import { routeEmailVerify } from "./emails";
55
import { routeOrganizationCreate } from "./organizations";
66
import { authHandler } from "../helpers/middleware";
7-
import { routeAuthResetPassword } from "./auth";
7+
import {
8+
routeAuthResetPassword,
9+
routeAuthVerifyToken,
10+
routeAuthLogin
11+
} from "./auth";
812

913
export const router = (app: Application) => {
1014
app.get("/", (req, res) => res.json({ hello: "world" }));
@@ -18,6 +22,8 @@ export const router = (app: Application) => {
1822
};
1923

2024
const routesAuth = (app: Application) => {
25+
app.post("/auth/login", asyncHandler(routeAuthLogin));
26+
app.post("/auth/verify-token", asyncHandler(routeAuthVerifyToken));
2127
app.post("/auth/reset-password", asyncHandler(routeAuthResetPassword));
2228
};
2329

0 commit comments

Comments
 (0)