test: add authorizer and fixture
This commit is contained in:
parent
243a598f37
commit
02337add0d
@ -57,9 +57,7 @@
|
|||||||
"jest": {
|
"jest": {
|
||||||
"preset": "ts-jest",
|
"preset": "ts-jest",
|
||||||
"testEnvironment": "node",
|
"testEnvironment": "node",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src"
|
||||||
"collectCoverage": true,
|
|
||||||
"coverageDirectory": "../coverage/"
|
|
||||||
},
|
},
|
||||||
"ts-standard": {
|
"ts-standard": {
|
||||||
"files": [
|
"files": [
|
||||||
@ -89,15 +87,20 @@
|
|||||||
"@commitlint/cli": "11.0.0",
|
"@commitlint/cli": "11.0.0",
|
||||||
"@commitlint/config-conventional": "11.0.0",
|
"@commitlint/config-conventional": "11.0.0",
|
||||||
"@release-it/conventional-changelog": "2.0.0",
|
"@release-it/conventional-changelog": "2.0.0",
|
||||||
|
"@types/express": "4.17.9",
|
||||||
"@types/jest": "26.0.19",
|
"@types/jest": "26.0.19",
|
||||||
"@types/jsonwebtoken": "8.5.0",
|
"@types/jsonwebtoken": "8.5.0",
|
||||||
"@types/node": "14.14.16",
|
"@types/node": "14.14.16",
|
||||||
|
"@types/server-destroy": "1.0.1",
|
||||||
"@types/socket.io": "2.1.12",
|
"@types/socket.io": "2.1.12",
|
||||||
|
"@types/socket.io-client": "1.4.34",
|
||||||
|
"axios": "0.21.1",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"husky": "4.3.6",
|
"husky": "4.3.6",
|
||||||
"jest": "26.6.3",
|
"jest": "26.6.3",
|
||||||
"release-it": "14.2.2",
|
"release-it": "14.2.2",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
|
"server-destroy": "1.0.1",
|
||||||
"snazzy": "9.0.0",
|
"snazzy": "9.0.0",
|
||||||
"socket.io": "2.3.0",
|
"socket.io": "2.3.0",
|
||||||
"socket.io-client": "2.3.0",
|
"socket.io-client": "2.3.0",
|
||||||
|
139
src/__test__/authorizer.test.ts
Normal file
139
src/__test__/authorizer.test.ts
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import io from 'socket.io-client'
|
||||||
|
import { fixtureStart, fixtureStop } from './fixture/index'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
describe('authorizer', () => {
|
||||||
|
describe('when the user is not logged in', () => {
|
||||||
|
beforeEach((done) => {
|
||||||
|
jest.setTimeout(15_000)
|
||||||
|
fixtureStart(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach((done) => {
|
||||||
|
fixtureStop(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should emit error with unauthorized handshake', (done) => {
|
||||||
|
const socket = io.connect('http://localhost:9000?token=boooooo')
|
||||||
|
socket.on('error', (err: any) => {
|
||||||
|
expect(err.message).toEqual('jwt malformed')
|
||||||
|
expect(err.code).toEqual('invalid_token')
|
||||||
|
socket.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when the user is logged in', () => {
|
||||||
|
describe('authorizer disallows query string token when specified in startup options', () => {
|
||||||
|
let token: string = ''
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
jest.setTimeout(15_000)
|
||||||
|
fixtureStart(
|
||||||
|
async () => {
|
||||||
|
const response = await axios.post('http://localhost:9000/login')
|
||||||
|
token = response.data.token
|
||||||
|
done()
|
||||||
|
},
|
||||||
|
{ auth_header_required: true }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach((done) => {
|
||||||
|
fixtureStop(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('auth headers are supported', (done) => {
|
||||||
|
const socket = io.connect('http://localhost:9000', {
|
||||||
|
// @ts-ignore
|
||||||
|
extraHeaders: { Authorization: `Bearer ${token}` }
|
||||||
|
})
|
||||||
|
socket.on('connect', () => {
|
||||||
|
socket.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('auth token in query string is disallowed', (done) => {
|
||||||
|
const socket = io.connect('http://localhost:9000', {
|
||||||
|
query: `token=${token}`
|
||||||
|
})
|
||||||
|
socket.on('error', (err: any) => {
|
||||||
|
expect(err.message).toEqual('Server requires Authorization Header')
|
||||||
|
expect(err.code).toEqual('missing_authorization_header')
|
||||||
|
socket.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('authorizer all auth types allowed', () => {
|
||||||
|
let token: string = ''
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
jest.setTimeout(15_000)
|
||||||
|
fixtureStart(async () => {
|
||||||
|
const response = await axios.post('http://localhost:9000/login')
|
||||||
|
token = response.data.token
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach((done) => {
|
||||||
|
fixtureStop(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('auth headers are supported', (done) => {
|
||||||
|
const socket = io.connect('http://localhost:9000', {
|
||||||
|
// @ts-ignore
|
||||||
|
extraHeaders: { Authorization: `Bearer ${token}` }
|
||||||
|
})
|
||||||
|
socket.on('connect', () => {
|
||||||
|
socket.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should do the handshake and connect', (done) => {
|
||||||
|
const socket = io.connect('http://localhost:9000', {
|
||||||
|
query: `token=${token}`
|
||||||
|
})
|
||||||
|
socket.on('connect', () => {
|
||||||
|
socket.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('unsigned token', () => {
|
||||||
|
let token =
|
||||||
|
'eyJhbGciOiJub25lIiwiY3R5IjoiSldUIn0.eyJuYW1lIjoiSm9obiBGb28ifQ.'
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
jest.setTimeout(15_000)
|
||||||
|
fixtureStart(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach((done) => {
|
||||||
|
fixtureStop(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not do the handshake and connect', (done) => {
|
||||||
|
const socket = io.connect('http://localhost:9000', {
|
||||||
|
query: `token=${token}`
|
||||||
|
})
|
||||||
|
socket
|
||||||
|
.on('connect', () => {
|
||||||
|
socket.close()
|
||||||
|
done(new Error("this shouldn't happen"))
|
||||||
|
})
|
||||||
|
.on('error', (err: any) => {
|
||||||
|
socket.close()
|
||||||
|
expect(err.message).toEqual('jwt signature is required')
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
57
src/__test__/fixture/index.ts
Normal file
57
src/__test__/fixture/index.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import express from 'express'
|
||||||
|
import jwt from 'jsonwebtoken'
|
||||||
|
import { Server as HttpServer } from 'http'
|
||||||
|
import { Server as HttpsServer } from 'https'
|
||||||
|
import socketIo, { Server as SocketIoServer } from 'socket.io'
|
||||||
|
import enableDestroy from 'server-destroy'
|
||||||
|
|
||||||
|
import { authorize } from '../../index'
|
||||||
|
|
||||||
|
interface Socket {
|
||||||
|
io: null | SocketIoServer
|
||||||
|
init: (httpServer: HttpServer | HttpsServer) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const socket: Socket = {
|
||||||
|
io: null,
|
||||||
|
init(httpServer) {
|
||||||
|
socket.io = socketIo(httpServer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let server: HttpServer | null = null
|
||||||
|
|
||||||
|
export const fixtureStart = (done: any, optionsAuth: any = {}) => {
|
||||||
|
const options = Object.assign(
|
||||||
|
{
|
||||||
|
secret: 'aaafoo super sercret',
|
||||||
|
timeout: 1000,
|
||||||
|
handshake: true
|
||||||
|
},
|
||||||
|
optionsAuth
|
||||||
|
)
|
||||||
|
const app = express()
|
||||||
|
app.use(express.json())
|
||||||
|
app.post('/login', (_req, res) => {
|
||||||
|
const profile = {
|
||||||
|
first_name: 'John',
|
||||||
|
last_name: 'Doe',
|
||||||
|
email: 'john@doe.com',
|
||||||
|
id: 123
|
||||||
|
}
|
||||||
|
const token = jwt.sign(profile, options.secret, { expiresIn: 60 * 60 * 5 })
|
||||||
|
return res.json({ token })
|
||||||
|
})
|
||||||
|
server = app.listen(9000, done)
|
||||||
|
socket.init(server)
|
||||||
|
socket.io?.use(authorize(options))
|
||||||
|
enableDestroy(server)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fixtureStop = (callback: Function) => {
|
||||||
|
socket.io?.close()
|
||||||
|
try {
|
||||||
|
server?.destroy()
|
||||||
|
} catch (err) {}
|
||||||
|
callback()
|
||||||
|
}
|
Reference in New Issue
Block a user