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

#!/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);