diff options
| author | Jan Tuomi <jan.tuomi@eficode.com> | 2020-02-05 19:25:36 +0200 |
|---|---|---|
| committer | Jan Tuomi <jan.tuomi@eficode.com> | 2020-02-05 19:25:36 +0200 |
| commit | 71d9490d0988c97b8b023a70e0b61c65f32ad3b9 (patch) | |
| tree | df6f3db2c1f3c3ef9339843431a79197b465a74c /backend/src/routes.js | |
| parent | 48a60c896d86de9bf76806ca60da35ef9f77259e (diff) | |
Implement permissions
Diffstat (limited to 'backend/src/routes.js')
| -rw-r--r-- | backend/src/routes.js | 141 |
1 files changed, 15 insertions, 126 deletions
diff --git a/backend/src/routes.js b/backend/src/routes.js index b0f3660..9d6775e 100644 --- a/backend/src/routes.js +++ b/backend/src/routes.js @@ -1,69 +1,15 @@ const express = require('express'); -const sha512 = require('js-sha512'); -const shortid = require('shortid'); -const base64 = require('base-64'); const db = require('./db'); +const { permissionMiddleware } = require('./authz'); +const PERMISSIONS = require('./permissions'); -const buildSessionCookie = ({ username, sessionToken, isLogout, remember }) => { - if (!isLogout) { - const joinedToken = `${username}&${sessionToken}`; - const encodedToken = base64.encode(joinedToken); - if (remember) { - return `sessionCookie=${encodedToken}; Domain=localhost; HttpOnly; SameSite=strict;`; - } else { - return `sessionCookie=${encodedToken}; Domain=localhost; HttpOnly; SameSite=strict; Max-Age=86400;`; - } - } else { - return `sessionCookie=deleted; Domain=localhost; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; SameSite=strict;`; - } -}; +const { authMiddleware, registerRoute, loginRoute, logoutRoute } = require('./authn'); const normalRouter = express.Router(); const authedRouter = express.Router(); -authedRouter.use(async (req, res, next) => { - const cookies = req.cookies; - const encodedCookie = cookies.sessionCookie; - - if (!encodedCookie) { - res.status(403); - return res.json({ - message: 'Log in first!', - }); - } - const sessionCookie = base64.decode(encodedCookie); - - const [ username, sessionToken ] = sessionCookie.split('&'); - - const user = await db('users').where({ username }).first(); - if (!user) { - res.status(400); - res.set('Set-Cookie', buildSessionCookie({ isLogout: true })); - return res.json({ - message: 'Invalid session token.', - sessionCookie, - }); - } - - const salt = user.salt; - - const sessionTokenHash = sha512(salt + sessionToken); - const token = await db('tokens').where({ type: 'session', value: sessionTokenHash }); - if (!token) { - res.status(400); - res.set('Set-Cookie', buildSessionCookie({ isLogout: true })); - return res.json({ - message: 'Invalid session token.', - sessionCookie, - }); - } - - req.sessionTokenHash = sessionTokenHash; - req.user = user; - - next(); -}); +authedRouter.use(authMiddleware); normalRouter.get('/', (req, res) => { res.json({ @@ -71,74 +17,10 @@ normalRouter.get('/', (req, res) => { }); }); -normalRouter.post('/register', async (req, res) => { - const { username, password } = req.body; - if (!username || !password) { - res.status(400); - return res.json({ - error: 'Username or password missing.', - }); - } - - const existingUser = await db('users').where({ username }).first(); - if (existingUser) { - res.status(400); - return res.json({ - error: 'Username already taken.', - }); - } - - const salt = shortid.generate(); - const pwHash = sha512(salt + password); - - 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 }); - - res.set('Set-Cookie', buildSessionCookie({ username, sessionToken, remember: false, isLogout: false })); - return res.json({ - username, - }); -}); - -normalRouter.post('/login', async (req, res) => { - const { username, password, remember } = req.body; - if (!username || !password) { - res.status(400); - return res.json({ - error: 'Username or password missing.', - }); - } - - const user = await db('users').where({ username }).first(); - - if (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, remember, isLogout: false })); - - return res.json({ - username, - }); - } - - res.status(403); - res.json({ - error: 'Wrong username or password', - }); -}); - -authedRouter.post('/logout', async (req, res) => { - await db('tokens').where({ type: 'session', user_id: req.user.id, value: req.sessionTokenHash }).delete(); - res.status(204); - res.set('Set-Cookie', buildSessionCookie({ isLogout: true })); - res.send(); -}); +/* Authentication flow */ +normalRouter.post('/register', registerRoute); +normalRouter.post('/login', loginRoute); +authedRouter.post('/logout', logoutRoute); authedRouter.get('/user', (req, res) => { const user = req.user; @@ -148,4 +30,11 @@ authedRouter.get('/user', (req, res) => { }); }); +authedRouter.get('/users', permissionMiddleware(PERMISSIONS.READ_USERS), async (req, res) => { + const users = await db('users').select('id', 'username', 'created_at'); + return res.json({ + users, + }); +}); + module.exports = { authedRouter, normalRouter }; |
