out-of-your-element/matrix/mreq.js

86 lines
2.4 KiB
JavaScript
Raw Normal View History

2023-05-04 20:25:00 +00:00
// @ts-check
const fetch = require("node-fetch").default
2024-07-20 13:30:07 +00:00
const mixin = require("@cloudrac3r/mixin-deep")
2024-01-20 04:03:03 +00:00
const stream = require("stream")
const getStream = require("get-stream")
2023-05-04 20:25:00 +00:00
const passthrough = require("../passthrough")
const { sync } = passthrough
/** @type {import("./read-registration")} */
const reg = sync.require("./read-registration.js")
2023-09-12 08:43:56 +00:00
const baseUrl = `${reg.ooye.server_origin}/_matrix`
2023-05-04 20:25:00 +00:00
class MatrixServerError extends Error {
2023-05-09 03:29:46 +00:00
constructor(data, opts) {
super(data.error || data.errcode)
2023-05-04 20:25:00 +00:00
this.data = data
/** @type {string} */
this.errcode = data.errcode
2023-05-09 03:29:46 +00:00
this.opts = opts
2023-05-04 20:25:00 +00:00
}
}
/**
* @param {string} method
* @param {string} url
* @param {any} [body]
* @param {any} [extra]
*/
async function mreq(method, url, body, extra = {}) {
2024-01-20 04:03:03 +00:00
if (body == undefined || Object.is(body.constructor, Object)) {
body = JSON.stringify(body)
} else if (body instanceof stream.Readable && reg.ooye.content_length_workaround) {
body = await getStream.buffer(body)
}
2023-05-04 20:25:00 +00:00
const opts = mixin({
method,
2024-01-20 04:03:03 +00:00
body,
2023-05-04 20:25:00 +00:00
headers: {
Authorization: `Bearer ${reg.as_token}`
}
}, extra)
// console.log(baseUrl + url, opts)
const res = await fetch(baseUrl + url, opts)
const root = await res.json()
2024-01-20 04:03:03 +00:00
if (!res.ok || root.errcode) {
2024-01-20 04:25:58 +00:00
if (root.error?.includes("Content-Length")) {
console.error(`OOYE cannot stream uploads to Synapse. Please choose one of these workarounds:`
+ `\n * Run an nginx reverse proxy to Synapse, and point registration.yaml's`
+ `\n \`server_origin\` to nginx`
+ `\n * Set \`content_length_workaround: true\` in registration.yaml (this will`
+ `\n halve the speed of bridging d->m files)`)
throw new Error("Synapse is not accepting stream uploads, see the message above.")
}
2024-01-20 04:03:03 +00:00
delete opts.headers.Authorization
throw new MatrixServerError(root, {baseUrl, url, ...opts})
}
return root
2023-05-04 20:25:00 +00:00
}
2023-09-03 13:38:30 +00:00
/**
* JavaScript doesn't have Racket-like parameters with dynamic scoping, so
* do NOT do anything else at the same time as this.
* @template T
* @param {string} token
* @param {(...arg: any[]) => Promise<T>} callback
* @returns {Promise<T>}
*/
async function withAccessToken(token, callback) {
const prevToken = reg.as_token
reg.as_token = token
try {
return await callback()
} finally {
reg.as_token = prevToken
}
}
2023-05-04 20:25:00 +00:00
module.exports.MatrixServerError = MatrixServerError
module.exports.mreq = mreq
2023-09-03 13:38:30 +00:00
module.exports.withAccessToken = withAccessToken