|
|
@@ -1,155 +0,0 @@
|
|
|
-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
|
|
|
- })
|
|
|
-}
|