refactor: messaging
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
export class LoginRequest{
|
export class LoginRequest{
|
||||||
constructor(
|
constructor(
|
||||||
username: string,
|
public username: string,
|
||||||
password: string
|
public password: string
|
||||||
){}
|
){}
|
||||||
}
|
}
|
||||||
export class LoginResponse{
|
export class LoginResponse{
|
||||||
|
|||||||
5
server/src/messages/Message.ts
Normal file
5
server/src/messages/Message.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export class GenericMessage{
|
||||||
|
constructor(
|
||||||
|
public message: string
|
||||||
|
){}
|
||||||
|
}
|
||||||
@@ -9,6 +9,5 @@ export class SendRequest{
|
|||||||
export class SendResponse{
|
export class SendResponse{
|
||||||
constructor(
|
constructor(
|
||||||
public balance: number,
|
public balance: number,
|
||||||
public message: string
|
|
||||||
){}
|
){}
|
||||||
}
|
}
|
||||||
@@ -2,34 +2,33 @@ import express from 'express';
|
|||||||
import { logger } from '../util/logging';
|
import { logger } from '../util/logging';
|
||||||
import User from '../model/user';
|
import User from '../model/user';
|
||||||
import { getJWT, requireAuth } from '../util/auth';
|
import { getJWT, requireAuth } from '../util/auth';
|
||||||
import { LoginRequest } from '@message/Login';
|
import { LoginRequest } from '../messages/Login';
|
||||||
import { SendRequest, SendResponse } from '@message/Send';
|
import { GenericMessage as Msg } from '../messages/Message';
|
||||||
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.post('/login', async (req, res) => {
|
router.post('/login', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { username, password } = req.body;
|
const data : LoginRequest = req.body;
|
||||||
const user = await User.findOne({where: { userID: username}});
|
const user = await User.findOne({where: { userID: data.username}});
|
||||||
if (!user) return res.status(401).json({ message: 'Invalid credentials' });
|
if (!user) return res.status(401).json(new Msg('Invalid credentials'));
|
||||||
const isMatch = (password == user.password);
|
const isMatch = (data.password == user.password);
|
||||||
//TODO hash passwords
|
//TODO hash passwords
|
||||||
//const isMatch = await bcrypt.compare(password, user.passwordHash);
|
//const isMatch = await bcrypt.compare(password, user.passwordHash);
|
||||||
if (!isMatch) return res.status(401).json({ message: 'Invalid credentials' });
|
if (!isMatch) return res.status(401).json(new Msg('Invalid credentials'));
|
||||||
|
|
||||||
// successfully authenticated
|
// successfully authenticated
|
||||||
let jwt = await getJWT(user);
|
let jwt = await getJWT(user);
|
||||||
res.cookie('jwt', jwt, {
|
res.cookie('jwt', jwt, {
|
||||||
httpOnly: true, // Prevent XSS
|
httpOnly: true, // Prevent XSS
|
||||||
secure: process.env.NODE_ENV === 'production',// HTTPS only
|
secure: process.env.NODE_ENV === 'production', // HTTPS only
|
||||||
sameSite: 'strict', // CSRF protection
|
sameSite: 'strict', // CSRF protection
|
||||||
maxAge: 86400000, // 1 day
|
maxAge: 86400000, // 1 day
|
||||||
});
|
});
|
||||||
res.json({ message: 'Logged in successfully' });
|
res.json(new Msg('Logged in successfully'));
|
||||||
}catch (err) {
|
}catch (err) {
|
||||||
logger.error('Failed to authenticate:', err);
|
logger.error('Failed to authenticate:', err);
|
||||||
res.status(500).json({ message: 'Failed to authenticate' });
|
res.status(500).json(new Msg('Failed to authenticate'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import User from '../model/user';
|
|||||||
import { db } from '../util/db';
|
import { db } from '../util/db';
|
||||||
import Transaction from '../model/transaction';
|
import Transaction from '../model/transaction';
|
||||||
import { SendRequest, SendResponse} from '../messages/Send';
|
import { SendRequest, SendResponse} from '../messages/Send';
|
||||||
|
import { GenericMessage as Err} from '../messages/Message';
|
||||||
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@@ -15,15 +16,14 @@ router.post('/', requireAuth, async (req, res) => {
|
|||||||
const data : SendRequest = req.body;
|
const data : SendRequest = req.body;
|
||||||
const recipient = await User.findOne({where: {userID: data.recipientID}})
|
const recipient = await User.findOne({where: {userID: data.recipientID}})
|
||||||
if ( Number(data.amount) <= 0) {
|
if ( Number(data.amount) <= 0) {
|
||||||
// TODO return SendResponse here and everywhere else in this file
|
return res.status(400).json(new Err('Invalid transfer amount'));
|
||||||
return res.status(400).json({ error: 'Invalid transfer amount' });
|
|
||||||
}
|
}
|
||||||
if (!recipient) {
|
if (!recipient) {
|
||||||
return res.status(404).json({ error: 'Recipient not found' });
|
return res.status(404).json(new Err('Recipient not found' ));
|
||||||
}
|
}
|
||||||
if (Number(sender.balance) < Number(data.amount)){
|
if (Number(sender.balance) < Number(data.amount)){
|
||||||
logger.error(`Insufficient balance: ${sender.balance} < ${data.amount}`)
|
logger.debug(`Insufficient balance: ${sender.balance} < ${data.amount}`)
|
||||||
return res.status(402).json({error: 'Insufficient balance'})
|
return res.status(402).json(new Err('Insufficient balance'))
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.transaction(async (t) =>{
|
await db.transaction(async (t) =>{
|
||||||
@@ -36,10 +36,10 @@ router.post('/', requireAuth, async (req, res) => {
|
|||||||
reference: data.reference
|
reference: data.reference
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
return res.status(200).json({balance: sender.balance, amount: data.amount});
|
return res.status(200).json(new SendResponse(sender.balance))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Failed to commit transaction:', err);
|
logger.error('Failed to commit transaction:', err);
|
||||||
return res.status(500).json({ error: 'Failed to commit transaction' });
|
return res.status(500).json(new Err('Failed to commit transaction' ));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user