Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 1x | /* eslint-disable security/detect-object-injection */
import Adapter from '../../lib/adapter.js'
import GleeQuoreMessage from '../../lib/message.js'
import ws from 'ws'
import GleeQuoreAuth from '../../lib/wsHttpAuth.js'
import { applyAddressParameters } from '../../lib/util.js'
import Debug from 'debug'
const debug = Debug("glee:ws:client")
interface Client {
channel: string
client: ws
binding?: any
}
class WsClientAdapter extends Adapter {
private clients: Array<Client> = []
name(): string {
return 'WS adapter'
}
async connect(): Promise<this> {
return this._connect()
}
async send(message: GleeQuoreMessage) {
return this._send(message)
}
private async _connect(): Promise<this> {
const channelsOnThisServer = this.getWsChannels()
debug("connecting to ", this.serverName)
for (const channelName of channelsOnThisServer) {
let headers = {}
const authConfig = await this.app.clientAuthConfig(this.serverName)
const gleeAuth = new GleeQuoreAuth(
this.AsyncAPIServer,
this.parsedAsyncAPI,
this.serverName,
authConfig
)
const protocol = this.AsyncAPIServer.protocol()
const serverHost = this.AsyncAPIServer.host()
const channel = this.parsedAsyncAPI.channels().get(channelName)
const channelAddress = applyAddressParameters(channel)
let url = new URL(`${protocol}://${serverHost}${channelAddress}`)
Iif (authConfig) {
const modedAuth = await gleeAuth.processClientAuth({ url, headers, query: {} })
headers = modedAuth.headers
url = modedAuth.url
}
this.clients.push({
channel: channelName,
client: new ws(url, { headers }),
binding: this.parsedAsyncAPI.channels().get(channelName).bindings().get('ws'),
})
}
for (const { client, channel } of this.clients) {
client.on('open', () => {
this.emit('connect', {
name: this.name(),
adapter: this,
connection: client,
channels: this.channelNames,
})
})
client.on('message', (data) => {
const msg = this._createMessage(channel, data)
this.emit('message', msg, client)
})
client.on('error', (err: any) => {
const errMessage = `Error: Authentication function not found at location auth/${this.serverName}. Expected function 'clientAuth'`
this.emit('error', new Error(errMessage))
console.error(err)
})
}
return this
}
private getWsChannels() {
const channels = []
for (const channel of this.channelNames) {
if (this.parsedAsyncAPI.channels().get(channel).servers().all().length !== 0) { // NOSONAR
Iif (
this.parsedAsyncAPI
.channels().get(channel)
.servers().get(this.serverName)
) {
channels.push(channel)
}
} else {
channels.push(channel)
}
}
return channels
}
async _send(message: GleeQuoreMessage): Promise<void> {
const client = this.clients.find(
(cl) => cl.channel === message.channel
)?.client
if (client) {
client.send(message.payload)
} else {
throw new Error(
'There is no WebSocker connection to send the message yet.'
)
}
}
_createMessage(eventName: string, payload: any): GleeQuoreMessage {
return new GleeQuoreMessage({
payload: payload,
channel: eventName,
})
}
}
export default WsClientAdapter
|