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