register + login + mdp hash

This commit is contained in:
gprunet
2026-01-10 16:27:15 +01:00
parent f00152523f
commit a1c08ab9dc
7 changed files with 192 additions and 70 deletions
View File
+81
View File
@@ -0,0 +1,81 @@
require('dotenv').config();
const { Pool } = require('pg');
const pool = new Pool
({
user: process.env.POSTGRES_USER,
host: process.env.POSTGRES_HOST,
database: process.env.POSTGRES_DB,
password: process.env.POSTGRES_PASSWORD,
port: 5432,
});
async function waitForDb(retries = 10, delay = 2000)
{
for (let i = 0; i < retries; i++)
{
try
{
await pool.query('SELECT 1');
console.log('Database is ready!');
return ;
}
catch (err)
{
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error('Could not connect to database after multiple attempts');
}
async function createTables()
{
try
{
await pool.query(`
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS messages(
id SERIAL PRIMARY KEY,
sender_id INT REFERENCES users(id),
received_id INT REFERENCES users(id),
content TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS friendship (
id_user1 INT NOT NULL,
id_user2 INT NOT NULL,
status VARCHAR(20) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
CHECK (id_user1 < id_user2),
PRIMARY KEY (id_user1, id_user2),
FOREIGN KEY (id_user1) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (id_user2) REFERENCES users(id) ON DELETE CASCADE
);
`);
console.log('Tables created!');
}
catch (err)
{
console.error('Error creating tables:', err);
}
}
async function query(text, params)
{
return (pool.query(text, params));
}
module.exports =
{
waitForDb,
createTables,
query
};
+2
View File
@@ -7,6 +7,8 @@ COPY package*.json ./
RUN npm install
RUN npm install dotenv
RUN npm install pg
RUN npm install bcrypt
RUN npm install jsonwebtoken
COPY . .
+6 -70
View File
@@ -1,81 +1,17 @@
require('dotenv').config();
const { Pool } = require('pg');
const pool = new Pool
({
user: process.env.POSTGRES_USER,
host: process.env.POSTGRES_HOST,
database: process.env.POSTGRES_DB,
password: process.env.POSTGRES_PASSWORD,
port: 5432,
});
async function waitForDb(retries = 10, delay = 2000)
{
for (let i = 0; i < retries; i++)
{
try
{
await pool.query('SELECT 1');
console.log('Database is ready!');
return ;
}
catch (err)
{
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error('Could not connect to database after multiple attempts');
}
async function createTables()
{
try
{
await pool.query(`
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS messages(
id SERIAL PRIMARY KEY,
sender_id INT REFERENCES users(id),
received_id INT REFERENCES users(id),
content TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS friendship (
id_user1 INT NOT NULL,
id_user2 INT NOT NULL,
status VARCHAR(20) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
CHECK (id_user1 < id_user2),
PRIMARY KEY (id_user1, id_user2),
FOREIGN KEY (id_user1) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (id_user2) REFERENCES users(id) ON DELETE CASCADE
);
`);
console.log('Tables created!');
}
catch (err)
{
console.error('Error creating tables:', err);
}
}
const express = require('express');
const authRouter = require('./routes/auth');
const {waitForDb, createTables} = require('./db');
const app = express();
app.use(express.json());
async function startServer()
{
await waitForDb();
await createTables();
app.use('/api/auth', authRouter);
app.get('/api/', (req, res) => res.send('Backend running'));
app.listen(3001, () =>
+21
View File
@@ -0,0 +1,21 @@
const jwt = require('jsonwebtoken');
module.exports = function authMiddleware(req, res, next)
{
const header = req.headers.authorization;
if (!header)
return (res.status(401).json({error: 'Missing token'}));
const token = header.split(' ')[1];
try
{
const payload = jwt.verify(token, process.env.JWT_SECRET);
req.user = payload;
next();
}
catch
{
res.status(401).json({error: 'Invalid token'});
}
};
+22
View File
@@ -0,0 +1,22 @@
const express = require('express');
const router = express.Router();
const authService = require('../services/auth');
router.post('/register', async(req, res) =>
{
const {username, password} = req.body;
if (!username || !password)
return (res.status(400).json({error: 'Missing fields'}));
const result = await authService.register(username, password);
res.status(result.status).json(result.data);
});
router.post('/login', async(req, res) =>
{
const {username, password} = req.body;
const result = await authService.login(username, password);
res.status(result.status).json(result.data);
});
module.exports = router;
+60
View File
@@ -0,0 +1,60 @@
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const {query} = require('../db');
async function login(username, password)
{
try
{
const result = await query
(
`SELECT id, password_hash FROM users WHERE username = $1`,
[username]
);
if (result.rows.length === 0)
return ({status: 401, data: {error: 'Invalid credentials'}});
const user = result.rows[0];
const match = await bcrypt.compare(password, user.password_hash);
if (!match)
return ({status: 401, data: {error: 'Invalid credentials'}});
const token = jwt.sign
(
{userId: user.id},
process.env.JWT_SECRET,
{expiresIn: '1h'}
);
return ({status: 200, data: {token}});
}
catch (err)
{
console.error(err);
return ({status: 500, data: {error: 'Server error'}});
}
};
async function register(username, password)
{
try
{
const password_hash = await bcrypt.hash(password, 10);
await query
(
`INSERT INTO users (username, password_hash) VALUES ($1, $2)`,
[username, password_hash]
);
return ({status: 201, data: {message: 'User created'}});
}
catch (err)
{
if (err.code === '23505')
return ({status: 409, data: {error: 'Username already exists'}});
console.error(err);
return ({status: 500, data: {error: 'Server error'}});
}
};
module.exports = {register, login};