bbb.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { Request, ParamsDictionary, createHash, server } from "./deps.ts";
  2. export class BBB {
  3. call: string
  4. checksum_incoming: string
  5. query: string
  6. params: string
  7. meeting_id: string
  8. url: string
  9. constructor (req: Request<ParamsDictionary, any, any>) {
  10. this.call = req.params.call
  11. this.checksum_incoming = req.query.checksum
  12. this.query = req._parsedUrl?.query || ""
  13. this.params = this.query.replace(/[?&]?checksum.*$/, '')
  14. this.meeting_id = req.query.meetingID
  15. this.url = req.originalUrl
  16. }
  17. // generate a checksum for various calls
  18. generate_checksum = (secret: string, call: string = this.call, params: string = this.params) => {
  19. const hash = createHash("sha1");
  20. hash.update(`${call}${params}${secret}`)
  21. return hash.toString()
  22. }
  23. // generate a url to check if meeting is available
  24. check_for_meeting_query = (server: server) => {
  25. const checksum = this.generate_checksum(server.secret, 'getMeetingInfo', `meetingID=${this.meeting_id}`)
  26. return `${server.host}/bigbluebutton/api/getMeetingInfo?meetingID=${this.meeting_id}&checksum=${checksum}`
  27. }
  28. // write new query for target bbb server
  29. rewritten_query = (server: server) => {
  30. const checksum_outgoing = this.generate_checksum(server.secret)
  31. return `${server.host}${this.url.replace(this.checksum_incoming, checksum_outgoing)}`
  32. }
  33. // check if request is autheticated with correct checksum
  34. authenticated = (secret: string) => {
  35. const checksum = this.generate_checksum(secret)
  36. const ok = checksum === this.checksum_incoming
  37. return ok
  38. }
  39. find_meeting_id = (servers: server[]): Promise<server> => {
  40. if (!this.meeting_id) throw Error
  41. const promises = servers.map(async s => {
  42. const res = await fetch(this.check_for_meeting_query(s))
  43. if (!res.ok) throw Error
  44. const text = await res.text()
  45. if (text.includes(this.meeting_id)) return s
  46. else throw Error
  47. })
  48. return Promise.any(promises)
  49. }
  50. }