BETTERZON-79: Adding API endpoint for logging in (#36)

This commit is contained in:
Patrick 2021-05-03 15:14:22 +02:00 committed by GitHub
parent e9d03b9cbb
commit a42c7da9a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 100 additions and 4 deletions

View File

@ -26,7 +26,7 @@ usersRouter.post('/register', async (req: Request, res: Response) => {
const username: string = req.body.username; const username: string = req.body.username;
const password: string = req.body.password; const password: string = req.body.password;
const email: string = req.body.email; const email: string = req.body.email;
const ip: string = req.connection.remoteAddress?? ''; const ip: string = req.connection.remoteAddress ?? '';
if (!username || !password || !email) { if (!username || !password || !email) {
// Missing // Missing
@ -52,3 +52,32 @@ usersRouter.post('/register', async (req: Request, res: Response) => {
res.status(404).send(e.message); res.status(404).send(e.message);
} }
}); });
// POST users/login
usersRouter.post('/login', async (req: Request, res: Response) => {
try {
const username: string = req.body.username;
const password: string = req.body.password;
const ip: string = req.connection.remoteAddress ?? '';
if (!username || !password) {
// Missing
res.status(400).send(JSON.stringify({message: 'Missing parameters'}));
return;
}
// Update the user entry and create a session
const session: Session = await UserService.login(username, password, ip);
if(!session.session_id) {
// Error logging in, probably wrong username / password
res.status(401).send(JSON.stringify({messages: ["Wrong username and / or password"], codes: [1, 4]}));
return;
}
// Send the session details back to the user
res.status(201).send(session);
} catch (e) {
res.status(404).send(e.message);
}
});

View File

@ -34,7 +34,7 @@ export const createUser = async (username: string, password: string, email: stri
let conn; let conn;
try { try {
// Hash password and generate + hash session key // Hash password and generate + hash session key
const pwHash = bcrypt.hashSync('123', 10); const pwHash = bcrypt.hashSync(password, 10);
const sessionKey = Guid.create().toString(); const sessionKey = Guid.create().toString();
const sessionKeyHash = bcrypt.hashSync(sessionKey, 10); const sessionKeyHash = bcrypt.hashSync(sessionKey, 10);
@ -57,7 +57,74 @@ export const createUser = async (username: string, password: string, email: stri
const sessionIdRes = await conn.query(sessionQuery, [userId, sessionKeyHash, ip]); const sessionIdRes = await conn.query(sessionQuery, [userId, sessionKeyHash, ip]);
await conn.commit(); await conn.commit();
// Get session id of the created user // Get session id of the created session
let sessionId: number = -1;
for (const row in sessionIdRes) {
if (row !== 'meta' && sessionIdRes[row].session_id != null) {
sessionId = sessionIdRes[row].session_id;
}
}
return {
session_id: sessionId,
session_key: sessionKey,
session_key_hash: '',
last_IP: ip
};
} catch (err) {
throw err;
} finally {
if (conn) {
conn.end();
}
}
return {} as Session;
};
/**
* Checks if the given credentials are valid and creates a new session if they are.
* Returns the session information in case of a successful login
*/
export const login = async (username: string, password: string, ip: string): Promise<Session> => {
let conn;
try {
// Get saved password hash
conn = await pool.getConnection();
const query = "SELECT user_id, bcrypt_password_hash FROM users WHERE username = ?"
const userRows = await conn.query(query, username);
let savedHash = '';
let userId = -1;
for (const row in userRows) {
if (row !== 'meta' && userRows[row].user_id != null) {
savedHash = userRows[row].bcrypt_password_hash;
userId = userRows[row].user_id;
}
}
// Check for correct password
if(!bcrypt.compareSync(password, savedHash)) {
// Wrong password, return invalid
return {} as Session;
}
// Password is valid, continue
// Generate + hash session key
const sessionKey = Guid.create().toString();
const sessionKeyHash = bcrypt.hashSync(sessionKey, 10);
// Update user entry in SQL
const userQuery = 'UPDATE users SET last_login_date = NOW()';
const userIdRes = await conn.query(userQuery);
await conn.commit();
// Create session
const sessionQuery = 'INSERT INTO sessions (user_id, session_key_hash, createdDate, lastLogin, validUntil, validDays, last_IP) VALUES (?,?,NOW(),NOW(),DATE_ADD(NOW(), INTERVAL 30 DAY),30,?) RETURNING session_id';
const sessionIdRes = await conn.query(sessionQuery, [userId, sessionKeyHash, ip]);
await conn.commit();
// Get session id of the created session
let sessionId: number = -1; let sessionId: number = -1;
for (const row in sessionIdRes) { for (const row in sessionIdRes) {
if (row !== 'meta' && sessionIdRes[row].session_id != null) { if (row !== 'meta' && sessionIdRes[row].session_id != null) {
@ -89,7 +156,7 @@ export const createUser = async (username: string, password: string, email: stri
export interface Status { export interface Status {
hasProblems: boolean; hasProblems: boolean;
messages: string[]; messages: string[];
codes: number[]; // 0 = all good, 1 = wrong username, 2 = wrong email, 3 = server error codes: number[]; // 0 = all good, 1 = wrong username, 2 = wrong email, 3 = server error, 4 = wrong password
} }
/** /**