1 | import { Application, Params, RealTimeConnection } from '@feathersjs/feathers'
|
2 | import { createDebug } from '@feathersjs/commons'
|
3 | import { Socket } from 'socket.io'
|
4 |
|
5 | const debug = createDebug('@feathersjs/socketio/middleware')
|
6 |
|
7 | export type ParamsGetter = (socket: Socket) => any
|
8 | export type NextFunction = (err?: any) => void
|
9 | export interface FeathersSocket extends Socket {
|
10 | feathers?: Params & { [key: string]: any }
|
11 | }
|
12 |
|
13 | export const disconnect = (
|
14 | app: Application,
|
15 | getParams: ParamsGetter,
|
16 | socketMap: WeakMap<RealTimeConnection, FeathersSocket>
|
17 | ) => {
|
18 | app.on('disconnect', (connection: RealTimeConnection) => {
|
19 | const socket = socketMap.get(connection)
|
20 | if (socket && socket.connected) {
|
21 | socket.disconnect()
|
22 | }
|
23 | })
|
24 |
|
25 | return (socket: FeathersSocket, next: NextFunction) => {
|
26 | socket.on('disconnect', () => app.emit('disconnect', getParams(socket)))
|
27 | next()
|
28 | }
|
29 | }
|
30 |
|
31 | export const params =
|
32 | (_app: Application, socketMap: WeakMap<RealTimeConnection, FeathersSocket>) =>
|
33 | (socket: FeathersSocket, next: NextFunction) => {
|
34 | socket.feathers = {
|
35 | provider: 'socketio',
|
36 | headers: socket.handshake.headers
|
37 | }
|
38 |
|
39 | socketMap.set(socket.feathers, socket)
|
40 |
|
41 | next()
|
42 | }
|
43 |
|
44 | export const authentication =
|
45 | (app: Application, getParams: ParamsGetter, settings: any = {}) =>
|
46 | (socket: FeathersSocket, next: NextFunction) => {
|
47 | const service = (app as any).defaultAuthentication
|
48 | ? (app as any).defaultAuthentication(settings.service)
|
49 | : null
|
50 |
|
51 | if (service === null) {
|
52 | return next()
|
53 | }
|
54 |
|
55 | const config = service.configuration
|
56 | const authStrategies = config.parseStrategies || config.authStrategies || []
|
57 |
|
58 | if (authStrategies.length === 0) {
|
59 | return next()
|
60 | }
|
61 |
|
62 | service
|
63 | .parse(socket.handshake, null, ...authStrategies)
|
64 | .then(async (authentication: any) => {
|
65 | if (authentication) {
|
66 | debug('Parsed authentication from HTTP header', authentication)
|
67 | socket.feathers.authentication = authentication
|
68 | await service.create(authentication, {
|
69 | provider: 'socketio',
|
70 | connection: getParams(socket)
|
71 | })
|
72 | }
|
73 |
|
74 | next()
|
75 | })
|
76 | .catch(next)
|
77 | }
|