Skip to content

Commit 08d4330

Browse files
committed
Merge remote-tracking branch 'origin/main'
# Conflicts: # app.js
2 parents adaf67b + 5cbb143 commit 08d4330

6 files changed

Lines changed: 141 additions & 15 deletions

File tree

app.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const dbAdapter = require('./services/dbAdapter');
1212
const auth = require('./routes/auth');
1313
const users = require('./routes/users');
1414
const ban = require('./routes/ban');
15+
const verification = require('./routes/verification');
16+
const otp = require('./routes/otp');
1517

1618
const app = express();
1719

@@ -25,6 +27,8 @@ app.use(cors());
2527
app.use('/api/auth', auth);
2628
app.use('/api/users', users);
2729
app.use('/api/ban', ban);
30+
app.use('/api/verification', verification);
31+
app.use('/api/otp', otp);
2832

2933
//read config
3034
debugStartup('Application Name: '+config.get('name'));

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"morgan": "^1.10.0",
2828
"nodemailer": "^6.9.7",
2929
"pg": "^8.11.3",
30+
"speakeasy": "^2.0.0",
3031
"utf8": "^3.0.0"
3132
}
3233
}

routes/auth.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ router.post('/', async (req, res) => {
1818

1919
let user = await dbAdapter.getUserByEmail(req.body.email);
2020

21+
if (!user) {
22+
debugRoute("POST /api/auth - 400 - User not found");
23+
return res.status(400).send('Invalid email or password.');
24+
}
25+
2126
const validPassword = await bcrypt.compare(req.body.password, user.password);
2227
if (!validPassword) {
2328
debugRoute("POST /api/auth - 400 - Invalid password");
@@ -31,7 +36,7 @@ router.post('/', async (req, res) => {
3136

3237
debugRoute("POST /api/auth - 200 - User logged in");
3338

34-
res.status(200).send({token:generateAuthToken(user.id,user.admin,false,(user.totp_secret != null && user.totp_confirmed))});
39+
res.status(200).send({token:generateAuthToken(user.id,user.admin,false,(user.totp_secret !== undefined && user.totp_confirmed))});
3540
})
3641

3742
function validate(req) {

routes/otp.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
const express = require('express');
2+
const router = express.Router();
3+
const debugRoute = require('debug')('app:route');
4+
const speakeasy = require('speakeasy');
5+
//Models
6+
const {generateAuthToken} = require('../models/User');
7+
//Middleware
8+
const auth = require('../middleware/auth');
9+
10+
router.get('/generate', auth, async (req, res) => {
11+
//TODO get user from database
12+
let user = {};
13+
14+
if (!user) {
15+
debugRoute("GET /api/otp/generate - 404 - User not found");
16+
return res.status(404).send('User not found.');
17+
}
18+
19+
if (user.otp_enabled && user.otp_verified) {
20+
debugRoute("GET /api/otp/generate - 400 - OTP already enabled");
21+
return res.status(400).send('OTP already enabled.');
22+
}
23+
24+
user.totp_confirmed = false;
25+
let secret = speakeasy.generateSecret().base32;
26+
user.totp_secret = secret;
27+
28+
//TODO save user
29+
30+
debugRoute("GET /api/otp/generate - 200 - OTP generated");
31+
32+
res.send(secret);
33+
});
34+
35+
router.post('/verify', auth, async (req, res) => {
36+
if (!req.body.token) {
37+
debugRoute("POST /api/otp/verify - 400 - Token required");
38+
return res.status(400).send("Token required");
39+
}
40+
41+
//TODO get user from database and change me
42+
let user = {totp_secret: "someting"};
43+
44+
if (!user) {
45+
debugRoute("POST /api/otp/verify - 404 - User not found");
46+
return res.status(404).send('User not found.');
47+
}
48+
49+
if (user.totp_secret === undefined) {
50+
debugRoute("POST /api/otp/verify - 400 - OTP not enabled");
51+
return res.status(400).send('OTP not enabled.');
52+
}
53+
54+
let verified = speakeasy.totp.verify({
55+
secret: user.otp_secret,
56+
encoding: 'base32',
57+
token: req.body.token,
58+
window: 1
59+
});
60+
//TODO change me
61+
verified = true;
62+
63+
if (!verified) {
64+
debugRoute("POST /api/otp/verify - 400 - Invalid token");
65+
return res.status(400).send('Invalid token.');
66+
}
67+
68+
if (!user.totp_confirmed) {
69+
user.totp_confirmed = true;
70+
user.lastSecurityUpdate = Date.now();
71+
//TODO save User
72+
}
73+
74+
debugRoute("POST /api/otp/verify - 200 - OTP verified");
75+
76+
res.send(generateAuthToken(user.id, user.admin,true,true));
77+
});
78+
79+
router.post('/disable', auth, async (req, res) => {
80+
//TODO get user from database
81+
82+
let user = {};
83+
if (!user) {
84+
debugRoute("POST /api/otp/disable - 404 - User not found");
85+
return res.status(404).send('User not found.');
86+
}
87+
88+
//TODO change me
89+
user.totp_confirmed = true;
90+
if (!user.totp_confirmed) {
91+
debugRoute("POST /api/otp/disable - 400 - OTP not enabled");
92+
return res.status(400).send('OTP not enabled.');
93+
}
94+
95+
user.totp_secret = undefined;
96+
user.totp_confirmed = false;
97+
user.lastSecurityUpdate = Date.now();
98+
99+
//save user
100+
101+
debugRoute("POST /api/otp/disable - 200 - OTP disabled");
102+
103+
res.send(generateAuthToken(false,false));
104+
});
105+
106+
module.exports = router;

routes/verification.js

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const debugRoute = require('debug')('app:route');
44
const {sendVerificationEmail} = require("../services/mailer");
55
const Joi = require("joi");
66
//Models
7-
const {generateVerificationCode} = require('../models/user');
7+
const {generateVerificationCode} = require('../models/User');
88

99
router.post('/resend/:email', async (req, res) => {
1010
if (Joi.string().email().validate(req.params.email).error) {
@@ -20,12 +20,12 @@ router.post('/resend/:email', async (req, res) => {
2020
return res.status(404).send('User not found.');
2121
}
2222

23-
if (user.verificationCodeSent > Date.now() - 300000) {
23+
if (user.last_email_send > Date.now() - 300000) {
2424
debugRoute("POST /api/verification/resend/:email - 400 - Verification code already sent");
2525
return res.status(400).send('Verification code already sent.');
2626
}
2727

28-
if (user.active) {
28+
if (user.email_confirmed) {
2929
debugRoute("POST /api/verification/verify/:code - 400 - User already verified");
3030
return res.status(400).send('User already verified.');
3131
}
@@ -42,11 +42,6 @@ router.post('/resend/:email', async (req, res) => {
4242
});
4343

4444
router.post('/verify/:code', async (req, res) => {
45-
if (!global.connected) {
46-
debugRoute("POST /api/verification/verify/:code - 500 - DB not connected");
47-
return res.status(500).send("Database not connected");
48-
}
49-
5045
if (!req.params.code) {
5146
debugRoute("POST /api/verification/verify/:code - 400 - Code required");
5247
return res.status(400).send("Code required");
@@ -57,11 +52,8 @@ router.post('/verify/:code', async (req, res) => {
5752
return res.status(400).send("Invalid code");
5853
}
5954

60-
let user = await User.findOne({verificationCode: req.params.code});
61-
if (!user) {
62-
debugRoute("POST /api/verification/verify/:code - 400 - Invalid code");
63-
return res.status(400).send("Invalid code");
64-
}
55+
//TODO find user in database
56+
let user = {}
6557

6658
if (user.verificationCodeSent < Date.now() - 259200000) {
6759
debugRoute("POST /api/verification/verify/:code - 400 - Verification code expired");
@@ -71,7 +63,8 @@ router.post('/verify/:code', async (req, res) => {
7163
user.active = true;
7264
user.verificationCode = undefined;
7365
user.verificationCodeSent = undefined;
74-
user.save();
66+
67+
//TODO save user
7568

7669
debugRoute("POST /api/verification/verify/:code - 200 - User verified");
7770

0 commit comments

Comments
 (0)