1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
import bcrypt from "bcrypt";
import { Request, Response } from "express";
import jwt from "jsonwebtoken";
import { QueryResult } from "pg";
import db from "../database/postgres.js";
import { ErrorResponse } from "../types/error.js";
import type { LoginRequest } from "../types/request.js";
import type {
AuthorizedUser,
DatabaseUser,
LoginResponse,
} from "../types/user.js";
async function loginUser(req: Request, res: Response) {
const { email, password } = req.body as LoginRequest;
if (!email || !password) {
return res.status(400).json({
message: "E-mail and password are required.",
});
}
try {
// Get data for user with login email address
const queryResult: QueryResult<DatabaseUser> = await db.query(
"SELECT id, email, password_hash, created_at FROM users WHERE email = $1;",
[email]
);
const user = queryResult.rows[0];
if (!user) {
return res.status(401).json({ message: "Login data invalid." });
}
// Check if password is correct
const isValidPassword = await bcrypt.compare(
password,
user.password_hash
);
if (!isValidPassword) {
return res.status(401).json({
message: "The password is incorrect.",
});
}
const userData: AuthorizedUser = {
id: user.id,
email: user.email,
createdAt: user.created_at,
};
// Create token for authentication
const token = jwt.sign(userData, process.env.JWT_SECRET!);
const loginResponse: LoginResponse = {
message: "Successful login.",
user: userData,
token,
};
return res.status(200).json(loginResponse);
} catch (error) {
console.error("Error on login attempt: ", error);
const errorResponse: ErrorResponse = {
message: "Internal server error on login attempt.",
error,
};
return res.status(500).json(errorResponse);
}
}
export default loginUser;
|