summaryrefslogtreecommitdiffstats
path: root/backend/src
diff options
context:
space:
mode:
Diffstat (limited to 'backend/src')
-rw-r--r--backend/src/authn.js60
-rw-r--r--backend/src/email.js20
-rw-r--r--backend/src/routes.js3
3 files changed, 75 insertions, 8 deletions
diff --git a/backend/src/authn.js b/backend/src/authn.js
index 1980aed..52ba862 100644
--- a/backend/src/authn.js
+++ b/backend/src/authn.js
@@ -64,7 +64,7 @@ const authMiddleware = async (req, res, next) => {
};
const registerRoute = async (req, res) => {
- const { username, password } = req.body;
+ const { username, password, email } = req.body;
if (!username || !password) {
res.status(400);
return res.json({
@@ -110,16 +110,21 @@ const registerRoute = async (req, res) => {
const sessionToken = shortid.generate();
const sessionTokenHash = sha512(salt + sessionToken);
- const user = (await db('users').insert({ username, password: pwHash, salt }).returning('*'))[0];
- await db('tokens').insert({ user_id: user.id, type: 'session', value: sessionTokenHash });
+ const insertedUsers = await db('users').insert({ username, password: pwHash, email, salt }).returning('*');
+ const user = insertedUsers[0];
+
+ const activationToken = shortid.generate();
+ await db('tokens').insert({ user_id: user.id, type: 'activation', value: activationToken });
- res.set('Set-Cookie', buildSessionCookie({ username, sessionToken, remember: false, isLogout: false }));
+ // await db('tokens').insert({ user_id: user.id, type: 'session', value: sessionTokenHash });
+ // res.set('Set-Cookie', buildSessionCookie({ username, sessionToken, remember: false, isLogout: false }));
await consoleBackend.send({
recipients: [ username ],
subject: `Welcome to the service, ${username}!`,
- body: `Welcome.\n\nLog in at http://localhost:3000.\n\nBR,\nTeam`,
+ body: `Welcome.\n\nActivate your account at http://localhost:3000/activate/${activationToken}.\n\nBR,\nTeam`,
});
+
return res.json({
username,
});
@@ -135,10 +140,17 @@ const loginRoute = async (req, res) => {
}
const user = await db('users').where({ username }).first();
+ if (!user) {
+ res.status(400);
+ res.json({
+ error: 'Wrong username or password',
+ });
+ }
+
const salt = user.salt;
const pwHash = sha512(salt + password);
- if (!user || pwHash !== user.password) {
+ if (pwHash !== user.password) {
res.status(400);
res.json({
error: 'Wrong username or password',
@@ -150,7 +162,7 @@ const loginRoute = async (req, res) => {
await db('tokens').insert({ user_id: user.id, type: 'session', value: sessionTokenHash });
- res.set('Set-Cookie', buildSessionCookie({ username, sessionToken, remember, isLogout: false }));
+ res.set('Set-Cookie', buildSessionCookie({ username, sessionToken, isLogout: false }));
return res.json({
username,
@@ -164,10 +176,44 @@ const logoutRoute = async (req, res) => {
res.send();
};
+const activateRoute = async (req, res) => {
+ const { activationToken } = req.body;
+ if (!activationToken) {
+ res.status(400);
+ return res.json({
+ error: 'Missing or invalid activation token.',
+ });
+ }
+
+ const tokenObj = await db('tokens').where({ type: 'activation', value: activationToken }).first();
+ if (!tokenObj) {
+ res.status(400);
+ return res.json({
+ error: 'Missing or invalid activation token.',
+ });
+ }
+
+ const updatedUsers = await db('users').where({ id: tokenObj.user_id }).update({ activated: true }).returning('*');
+ const user = updatedUsers[0];
+ await db('tokens').where({ type: 'activation', value: activationToken }).delete();
+
+ const { username } = user;
+ const sessionToken = shortid.generate();
+ const sessionTokenHash = sha512(user.salt + sessionToken);
+
+ await db('tokens').insert({ user_id: user.id, type: 'session', value: sessionTokenHash });
+
+ res.set('Set-Cookie', buildSessionCookie({ username, sessionToken, isLogout: false }));
+ return res.json({
+ username,
+ });
+};
+
module.exports = {
buildSessionCookie,
authMiddleware,
registerRoute,
loginRoute,
logoutRoute,
+ activateRoute,
};
diff --git a/backend/src/email.js b/backend/src/email.js
new file mode 100644
index 0000000..b41bae5
--- /dev/null
+++ b/backend/src/email.js
@@ -0,0 +1,20 @@
+const consoleBackend = {
+ send: ({ recipients, subject, body, cc, bcc }) => {
+ if (!recipients) throw new Exception('Recipients missing');
+ if (!subject) throw new Exception('Subject missing');
+
+ console.log('Email sent to console.');
+ console.log('=== To:', recipients.join(', '));
+ if (cc) console.log('=== CC:', cc.join(', '));
+ if (bcc) console.log('=== BCC:', bcc.join(', '));
+ console.log('=== Subject:', subject);
+ console.log();
+ console.log('=== Body:');
+ console.log(body);
+ console.log('===');
+ },
+};
+
+module.exports = {
+ consoleBackend,
+};
diff --git a/backend/src/routes.js b/backend/src/routes.js
index 9d6775e..9424f75 100644
--- a/backend/src/routes.js
+++ b/backend/src/routes.js
@@ -4,7 +4,7 @@ const db = require('./db');
const { permissionMiddleware } = require('./authz');
const PERMISSIONS = require('./permissions');
-const { authMiddleware, registerRoute, loginRoute, logoutRoute } = require('./authn');
+const { authMiddleware, registerRoute, loginRoute, logoutRoute, activateRoute } = require('./authn');
const normalRouter = express.Router();
const authedRouter = express.Router();
@@ -20,6 +20,7 @@ normalRouter.get('/', (req, res) => {
/* Authentication flow */
normalRouter.post('/register', registerRoute);
normalRouter.post('/login', loginRoute);
+normalRouter.post('/activate', activateRoute);
authedRouter.post('/logout', logoutRoute);
authedRouter.get('/user', (req, res) => {