feat: add support for socket.io >= 3.0.0

This commit is contained in:
divlo
2020-12-29 03:32:28 +01:00
parent 76173f894f
commit 0e534dd8ee
16 changed files with 43 additions and 1635 deletions

View File

@ -1,139 +0,0 @@
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-expect-error
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-expect-error
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', () => {
const 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()
})
})
})
})

View File

@ -1,57 +0,0 @@
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()
}