| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- import express from 'express';
- import jwt from 'jsonwebtoken';
- import argon2 from 'argon2';
- import Mailer from "./mail.js"
- import * as crypto from "node:crypto";
- export const auth = express.Router();
- const mailer = new Mailer().init()
- let mfaCodes = []
- auth.get('/user', async (req, res) => {
- const UserDB = req.app.locals.db;
- const token = req.cookies.token;
- if (!token) {
- return res.status(401).json({error: 'No token'});
- }
- let decoded;
- try {
- decoded = jwt.verify(token, process.env.JWT_SECRET);
- } catch {
- res.clearCookie('token', {
- httpOnly: true,
- secure: false,
- sameSite: 'lax',
- path: '/'
- });
- return res.status(401).json({error: 'Invalid token'});
- }
- const row = await UserDB.find('users', {_id: decoded.id});
- if (!row) {
- res.clearCookie('token', {
- httpOnly: true,
- secure: false,
- sameSite: 'lax',
- path: '/'
- });
- return res.status(401).json({error: 'Invalid token'});
- }
- const {password, ...safeRow} = row;
- res.json(safeRow);
- });
- auth.get('/login/:data', async (req, res) => {
- const UserDB = req.app.locals.db;
- if (!req.params.data) {
- return res.status(401).send('Invalid token');
- }
- try {
- const data = JSON.parse(atob(req.params.data));
- const row = await UserDB.find('users', {_id: data.id});
- if (!row) {
- return res.status(401).send('Invalid token');
- }
- console.log(mfaCodes)
- const mfaRow = mfaCodes.find(obj => String(obj.id) === String(data.id));
- if (!mfaRow) {
- return res.status(401).send('Invalid token');
- }
- if (mfaRow.token !== data.token) {
- return res.status(401).send('Invalid token');
- }
- const token = jwt.sign(
- {id: row._id, username: row.username},
- process.env.JWT_SECRET,
- {expiresIn: '1h'}
- );
- res.cookie('token', token, {
- httpOnly: true,
- secure: false,
- sameSite: 'lax',
- maxAge: 60 * 60 * 1000,
- path: '/'
- });
- const index = mfaCodes.findIndex(obj => String(obj.id) === String(data.id));
- if (index !== -1) {
- mfaCodes.splice(index, 1);
- }
- res.redirect('http://localhost:5173/');
- } catch (e) {
- console.log(e);
- res.status(401).send('Invalid token');
- }
- });
- auth.post('/login', async (req, res) => {
- let UserDB = req.app.locals.db;
- const {username, password} = req.body;
- if (!username || !password) {
- return res.status(400).json({error: 'Missing credentials'});
- }
- const row = await UserDB.find('users', {username});
- if (!row) return res.status(401).json({error: 'User doesnt exist'});
- if (!await argon2.verify(row.password, password)) return res.status(401).json({error: 'Invalid password'});
- let mfgen = crypto.randomBytes(64).toString('hex');
- const mfaToken = {id: row._id, token: mfgen}
- mfaCodes.push(mfaToken)
- console.log(mfaCodes)
- await mailer.send(row.email, "2FA Login Link", `Hey, ${row.username}!\n\nYour login link is: http://localhost:3000/api/auth/login/${btoa(JSON.stringify(mfaToken))}`)
- res.json({success: true, user: {username}});
- });
- auth.post('/register', async (req, res) => {
- let UserDB = req.app.locals.db;
- const {email, password} = req.body;
- const username = email.split("@")[0]
- //await mailer.send(email, "signup request", "this worked?")
- if (await UserDB.find('users', {username: username})) return res.status(400).json({error: 'User already exists'});
- const hash = await hashPass(password)
- UserDB.add('users', {username: username, email: email, password: hash})
- res.json({success: true, user: {username}});
- })
- async function hashPass(input) {
- return await argon2.hash(input, {
- type: argon2.argon2id,
- salt: Buffer.from(process.env.SALT, 'utf8'),
- timeCost: 2,
- memoryCost: 19456,
- parallelism: 1
- })
- }
|