Add auth and blacklist APIs
This commit is contained in:
39
server/__tests__/AuthAPI-test.js
Normal file
39
server/__tests__/AuthAPI-test.js
Normal file
@ -0,0 +1,39 @@
|
||||
const AuthAPI = require('../AuthAPI')
|
||||
|
||||
describe('Auth API', () => {
|
||||
beforeEach(done => {
|
||||
AuthAPI.removeAllRevokedTokens().then(() => done(), done)
|
||||
})
|
||||
|
||||
it('creates tokens with the right scopes', done => {
|
||||
const scopes = {
|
||||
blacklist: {
|
||||
add: true,
|
||||
remove: true
|
||||
}
|
||||
}
|
||||
|
||||
AuthAPI.createToken(scopes).then(token => {
|
||||
AuthAPI.verifyToken(token).then(payload => {
|
||||
expect(payload.jti).toEqual(expect.any(String))
|
||||
expect(payload.iss).toEqual(expect.any(String))
|
||||
expect(payload.iat).toEqual(expect.any(Number))
|
||||
expect(payload.scopes).toMatchObject(scopes)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('refuses to verify revoked tokens', done => {
|
||||
const scopes = {}
|
||||
|
||||
AuthAPI.createToken(scopes).then(token => {
|
||||
AuthAPI.revokeToken(token).then(() => {
|
||||
AuthAPI.verifyToken(token).then(payload => {
|
||||
expect(payload).toBe(null)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
24
server/__tests__/BlacklistAPI-test.js
Normal file
24
server/__tests__/BlacklistAPI-test.js
Normal file
@ -0,0 +1,24 @@
|
||||
const BlacklistAPI = require('../BlacklistAPI')
|
||||
|
||||
describe('Blacklist API', () => {
|
||||
beforeEach(done => {
|
||||
BlacklistAPI.removeAllPackages().then(() => done(), done)
|
||||
})
|
||||
|
||||
it('adds and removes packages to/from the blacklist', done => {
|
||||
const packageName = 'bad-package'
|
||||
|
||||
BlacklistAPI.addPackage(packageName).then(() => {
|
||||
BlacklistAPI.getPackages().then(packageNames => {
|
||||
expect(packageNames).toEqual([packageName])
|
||||
|
||||
BlacklistAPI.removePackage(packageName).then(() => {
|
||||
BlacklistAPI.getPackages().then(packageNames => {
|
||||
expect(packageNames).toEqual([])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
201
server/__tests__/server-test.js
Normal file
201
server/__tests__/server-test.js
Normal file
@ -0,0 +1,201 @@
|
||||
const request = require('supertest')
|
||||
const createServer = require('../createServer')
|
||||
const withBlacklist = require('./utils/withBlacklist')
|
||||
const withRevokedToken = require('./utils/withRevokedToken')
|
||||
const withToken = require('./utils/withToken')
|
||||
|
||||
describe('The server', () => {
|
||||
let server
|
||||
beforeEach(() => {
|
||||
server = createServer()
|
||||
})
|
||||
|
||||
it('rejects invalid package names', done => {
|
||||
request(server)
|
||||
.get('/_invalid/index.js')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(403)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('redirects invalid query params', done => {
|
||||
request(server)
|
||||
.get('/react?main=index&invalid')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(302)
|
||||
expect(res.headers.location).toBe('/react?main=index')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('redirects /_meta to ?meta', done => {
|
||||
request(server)
|
||||
.get('/_meta/react?main=index')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(302)
|
||||
expect(res.headers.location).toBe('/react?main=index&meta')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('does not serve blacklisted packages', done => {
|
||||
withBlacklist(['bad-package'], () => {
|
||||
request(server)
|
||||
.get('/bad-package/index.js')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(403)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /_auth', () => {
|
||||
it('creates a new auth token', done => {
|
||||
request(server)
|
||||
.post('/_auth')
|
||||
.end((err, res) => {
|
||||
expect(res.body).toHaveProperty('token')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /_auth', () => {
|
||||
describe('with no auth', () => {
|
||||
it('echoes back null', done => {
|
||||
request(server)
|
||||
.get('/_auth')
|
||||
.end((err, res) => {
|
||||
expect(res.body).toHaveProperty('auth')
|
||||
expect(res.body.auth).toBe(null)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a revoked auth token', () => {
|
||||
it('echoes back null', done => {
|
||||
withRevokedToken({ some: { scope: true } }, token => {
|
||||
request(server)
|
||||
.get('/_auth?token=' + token)
|
||||
.end((err, res) => {
|
||||
expect(res.body).toHaveProperty('auth')
|
||||
expect(res.body.auth).toBe(null)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a valid auth token', () => {
|
||||
it('echoes back the auth payload', done => {
|
||||
withToken({ some: { scope: true } }, token => {
|
||||
request(server)
|
||||
.get('/_auth?token=' + token)
|
||||
.end((err, res) => {
|
||||
expect(res.body).toHaveProperty('auth')
|
||||
expect(typeof res.body.auth).toBe('object')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /_publicKey', () => {
|
||||
it('echoes the public key', done => {
|
||||
request(server)
|
||||
.get('/_publicKey')
|
||||
.end((err, res) => {
|
||||
expect(res.text).toMatch(/PUBLIC KEY/)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /_blacklist', () => {
|
||||
describe('with no auth', () => {
|
||||
it('is forbidden', done => {
|
||||
request(server)
|
||||
.post('/_blacklist')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(403)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with the "blacklist.add" scope', () => {
|
||||
it('can add to the blacklist', done => {
|
||||
withToken({ blacklist: { add: true } }, token => {
|
||||
request(server)
|
||||
.post('/_blacklist')
|
||||
.send({ token, packageName: 'bad-package' })
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(res.headers['content-location']).toEqual(
|
||||
'/_blacklist/bad-package'
|
||||
)
|
||||
expect(res.body.ok).toBe(true)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /_blacklist', () => {
|
||||
describe('with no auth', () => {
|
||||
it('is forbidden', done => {
|
||||
request(server)
|
||||
.get('/_blacklist')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(403)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with the "blacklist.read" scope', () => {
|
||||
it('can read the blacklist', done => {
|
||||
withToken({ blacklist: { read: true } }, token => {
|
||||
request(server)
|
||||
.get('/_blacklist?token=' + token)
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(200)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('DELETE /_blacklist/:packageName', () => {
|
||||
describe('with no auth', () => {
|
||||
it('is forbidden', done => {
|
||||
request(server)
|
||||
.delete('/_blacklist/bad-package')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(403)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with the "blacklist.remove" scope', () => {
|
||||
it('can remove a package from the blacklist', done => {
|
||||
withToken({ blacklist: { remove: true } }, token => {
|
||||
request(server)
|
||||
.delete('/_blacklist/bad-package')
|
||||
.send({ token })
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(res.body.ok).toBe(true)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
7
server/__tests__/utils/withBlacklist.js
Normal file
7
server/__tests__/utils/withBlacklist.js
Normal file
@ -0,0 +1,7 @@
|
||||
const BlacklistAPI = require('../../BlacklistAPI')
|
||||
|
||||
function withBlacklist(blacklist, callback) {
|
||||
return Promise.all(blacklist.map(BlacklistAPI.addPackage)).then(callback)
|
||||
}
|
||||
|
||||
module.exports = withBlacklist
|
12
server/__tests__/utils/withRevokedToken.js
Normal file
12
server/__tests__/utils/withRevokedToken.js
Normal file
@ -0,0 +1,12 @@
|
||||
const withToken = require('./withToken')
|
||||
const AuthAPI = require('../../AuthAPI')
|
||||
|
||||
function withRevokedToken(scopes, callback) {
|
||||
withToken(scopes, token => {
|
||||
AuthAPI.revokeToken(token).then(() => {
|
||||
callback(token)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = withRevokedToken
|
7
server/__tests__/utils/withToken.js
Normal file
7
server/__tests__/utils/withToken.js
Normal file
@ -0,0 +1,7 @@
|
||||
const AuthAPI = require('../../AuthAPI')
|
||||
|
||||
function withToken(scopes, callback) {
|
||||
AuthAPI.createToken(scopes).then(callback)
|
||||
}
|
||||
|
||||
module.exports = withToken
|
Reference in New Issue
Block a user