You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.7 KiB
JavaScript
97 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
"use strict";
|
|
|
|
const Promise = require("bluebird");
|
|
const express = require("express");
|
|
const expressPromiseRouter = require("express-promise-router");
|
|
const expressReactViews = require("@joepie91/express-react-views");
|
|
const path = require("path");
|
|
const url = require("url");
|
|
const autodiscoverClientConfiguration = require("@modular-matrix/autodiscover-client-configuration");
|
|
const bhttp = require("bhttp");
|
|
const createError = require("create-error");
|
|
const { ValidationError, validateValue, required, isString } = require("validatem");
|
|
|
|
require('@babel/register')({
|
|
extensions: [".jsx"],
|
|
presets: [
|
|
require.resolve("@babel/preset-react"),
|
|
[require.resolve("@babel/preset-env"), { targets: { node: "current" } }]
|
|
]
|
|
});
|
|
|
|
let UpstreamError = createError("UpstreamError");
|
|
|
|
function generateSince(hostname, token) {
|
|
return url.format({ pathname: "/show-rooms", query: {
|
|
hostname: hostname,
|
|
since: token
|
|
} });
|
|
}
|
|
|
|
let app = express();
|
|
|
|
app.set("views", path.join(__dirname, "../views"));
|
|
app.set("view engine", "jsx");
|
|
app.engine("jsx", expressReactViews.createEngine({ transformViews: false }));
|
|
|
|
app.use(express.static(path.join(__dirname, "../public")));
|
|
|
|
let router = expressPromiseRouter();
|
|
|
|
router.get("/", (req, res) => {
|
|
res.render("index");
|
|
});
|
|
|
|
router.get("/show-rooms", (req, res) => {
|
|
validateValue(req.query, {
|
|
hostname: [ required, isString, (string) => {
|
|
if (string.length === 0) {
|
|
throw new ValidationError("May not be empty");
|
|
}
|
|
} ],
|
|
since: [ isString ]
|
|
});
|
|
|
|
return Promise.try(() => {
|
|
return autodiscoverClientConfiguration.discover(req.query.hostname);
|
|
}).then((clientConfiguration) => {
|
|
let roomsUrl = url.format({
|
|
... url.parse(clientConfiguration.homeserver),
|
|
pathname: "/_matrix/client/r0/publicRooms",
|
|
query: { since: req.query.since }
|
|
});
|
|
|
|
return Promise.try(() => {
|
|
return bhttp.get(roomsUrl);
|
|
}).then((response) => {
|
|
if (response.statusCode === 200) {
|
|
res.render("rooms", {
|
|
rooms: response.body.chunk,
|
|
nextBatchUrl: (response.body.next_batch != null)
|
|
? generateSince(req.query.hostname, response.body.next_batch)
|
|
: null,
|
|
previousBatchUrl: (response.body.previous_batch != null)
|
|
? generateSince(req.query.hostname, response.body.previous_batch)
|
|
: null,
|
|
});
|
|
} else {
|
|
throw new UpstreamError(`Non-200 status code received from homeserver: ${response.statusCode}`);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
app.use(router);
|
|
|
|
app.use((error, req, res, next) => {
|
|
if (error instanceof UpstreamError || error instanceof autodiscoverClientConfiguration.LookupFailed || error instanceof ValidationError) {
|
|
res.render("error", { error: error });
|
|
} else {
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
app.listen(3842);
|