An amazing project that generates micro reports from tournament results
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.7 KiB

const ROS = require('realm-object-server');
const fs = require('fs');
const http = require('http');
const httpProxy = require('http-proxy');
const os = require('os');
const path = require('path');
// Bypass the mandatory email prompt.
process.env.ROS_TOS_EMAIL_ADDRESS = 'ci@realm.io';
process.env.DOCKER_DATA_PATH = '/tmp';
// Don't bother calling fsync() because we're throwing away all the files
// between runs anyway
process.env.REALM_DISABLE_SYNC_TO_DISK = 'true';
// Workaround for <https://github.com/realm/realm-object-server-private/issues/950>.
process.env.ROS_SUPERAGENT_RETRY_DELAY = '0';
// Enable timestamps in the logs
process.env.ROS_LOG_TIMESTAMP = '1';
if (!process.env.SYNC_WORKER_FEATURE_TOKEN) {
try {
require(os.homedir() + '/.ros-feature-token.js');
}
catch (e) {
console.error('ROS feature token not found. Running Object Server tests requires setting the SYNC_WORKER_FEATURE_TOKEN environment variable.');
process.exit(1);
}
}
// A "email handler" which actually just writes the tokens to files that the
// tests can read
class PasswordEmailHandler {
constructor(dataRoot) {
this.dataRoot = dataRoot;
fs.mkdirSync(this.dataRoot);
}
resetPassword(email, token, userAgent, remoteIp) {
fs.writeFileSync(path.join(this.dataRoot, email), token);
return new Promise(r => setTimeout(r, 0));
}
confirmEmail(email, token) {
fs.writeFileSync(path.join(this.dataRoot, email), token);
return new Promise(r => setTimeout(r, 0));
}
}
// A simple proxy server that runs in front of ROS and validates custom headers
class HeaderValidationProxy {
constructor(listenPort, targetPort) {
this.proxy = httpProxy.createProxyServer({target: `http://127.0.0.1:${targetPort}`, ws: true});
this.proxy.on('error', e => {
console.log('proxy error', e);
});
this.server = http.createServer((req, res) => {
if (this.validate(req)) {
this.proxy.web(req, res);
}
else {
res.writeHead(400);
res.end('Missing X-Allow-Connection header');
}
});
this.server.on('upgrade', (req, socket, head) => {
if (this.validate(req)) {
this.proxy.ws(req, socket, head);
}
else {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
}
});
this.server.listen(listenPort);
}
stop() {
this.server.close();
this.proxy.close();
}
validate(req) {
return !!req.headers['x-allow-connection'];
}
}
const server = new ROS.BasicServer();
server.start({
// The desired logging threshold. Can be one of: all, trace, debug, detail, info, warn, error, fatal, off)
logLevel: 'off',
// For all the full list of configuration parameters see:
// https://realm.io/docs/realm-object-server/latest/api/ros/interfaces/serverconfig.html
address: '0.0.0.0',
port: 9080,
httpsPort: 9443,
https: true,
httpsKeyPath: __dirname + '/certificates/localhost-cert-key.pem',
httpsCertChainPath: __dirname + '/certificates/localhost-cert.pem',
httpsForInternalComponents: false,
dataPath: process.argv[2],
authProviders: [
new ROS.auth.DebugAuthProvider(),
new ROS.auth.PasswordAuthProvider({
autoCreateAdminUser: true,
emailHandler: new PasswordEmailHandler(path.join(process.argv[2], 'email')),
}),
],
autoKeyGen: true,
}).then(() => {
console.log('started');
fs.closeSync(1);
}).catch(err => {
console.error(`Error starting Realm Object Server: ${err.message}`)
});
new HeaderValidationProxy(9081, 9080);