Skip to content

Commit

Permalink
[#4] authenticate middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
b051 committed Mar 21, 2017
1 parent dc644d7 commit 9b40dc8
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
36 changes: 36 additions & 0 deletions src/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//@flow

import Boom from 'boom'
import _jwt from 'jsonwebtoken'
import Promise from 'bluebird'
import Person from '../person/model'

const jwt = Promise.promisifyAll(_jwt)
const secret = process.env.AUTH_SECRET
const Bearer = /^Bearer (\S*)$/

export default async (ctx: any, next: Function) => {
if (!secret) {
throw Boom.unauthorized('Invalid secret')
}
if (!ctx.header || !ctx.header.authorization) {
throw Boom.unauthorized('No authentication token found')
}
const m = Bearer.exec(ctx.header.authorization)
if (!m || !m[1]) {
throw Boom.unauthorized('Bad Authorization header format. Format is "Authorization: Bearer <token>"')
}
const token = m[1]
try {
const user = await jwt.verifyAsync(token, secret)
const person = await Person.findById(user.id)
if (!person) {
throw Boom.unauthorized('Invalid token')
}
ctx.state = ctx.state || {}
ctx.state.person = person
} catch(err) {
throw Boom.unauthorized('Invalid token')
}
await next()
}
1 change: 1 addition & 0 deletions src/middleware/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//@flow

export {default as errors} from './errors'
export {default as auth} from './auth'
8 changes: 5 additions & 3 deletions src/person/router.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
//@flow

import Router from 'koa-router'
import Boom from 'boom'
import Person from './model'
import { auth } from '../middleware'

const router = new Router({
prefix: '/people'
})

router.get('/', async ctx => {
const message = 'hello'
ctx.body = { message }
router.get('/me', auth, async ctx => {
const { person } = ctx.state
ctx.body = { person: person.toSafeJSON() }
})

router.post('/login', async ctx => {
Expand Down
26 changes: 19 additions & 7 deletions test/person/person.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import Person from '../../src/person/model'

describe("router - people", () => {

it('should return a message', async () => {
const res = await app.get('/people')
expect(res.status).to.equal(200)
expect(res.body).to.have.key('message')
expect(res.body.message).to.equal('hello')
})

describe('/login', () => {
it('should throw on missing infomation', async () => {
const res = await app.post('/people/login')
Expand Down Expand Up @@ -45,6 +39,24 @@ describe("router - people", () => {
expect(res.body.person.salt).to.not.exist
expect(res.body.person.hash).to.not.exist
})
})

describe('/me', () => {
it('should throw if no token provided', async () => {
const res = await app.get('/people/me')
expect(res.status).to.equal(401)
expect(res.body.message).to.equal('No authentication token found')
})

it('should return my userinfo', async () => {
const person = await Person.findById(1)
const token = person.generateToken()
const res = await app.get('/people/me').set('Authorization', `Bearer ${token}`)
expect(res.status).to.equal(200)
expect(res.body.person.id).to.equal(1)
expect(res.body.person.password).to.not.exist
expect(res.body.person.salt).to.not.exist
expect(res.body.person.hash).to.not.exist
})
})
})

0 comments on commit 9b40dc8

Please sign in to comment.