diff options
Diffstat (limited to 'backend/src')
| -rw-r--r-- | backend/src/authn.js | 60 | ||||
| -rw-r--r-- | backend/src/email.js | 20 | ||||
| -rw-r--r-- | backend/src/routes.js | 3 |
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) => { |
