The communications platform that puts data protection first.
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.
 
 
 
 
 
Rocket.Chat/app/apps/server/bridges/api.js

114 lines
2.7 KiB

import { Meteor } from 'meteor/meteor';
import express from 'express';
import { WebApp } from 'meteor/webapp';
const apiServer = express();
apiServer.disable('x-powered-by');
WebApp.connectHandlers.use(apiServer);
export class AppApisBridge {
constructor(orch) {
this.orch = orch;
this.appRouters = new Map();
// apiServer.use('/api/apps', (req, res, next) => {
// this.orch.debugLog({
// method: req.method.toLowerCase(),
// url: req.url,
// query: req.query,
// body: req.body,
// });
// next();
// });
apiServer.use('/api/apps/private/:appId/:hash', (req, res) => {
const notFound = () => res.send(404);
const router = this.appRouters.get(req.params.appId);
if (router) {
req._privateHash = req.params.hash;
return router(req, res, notFound);
}
notFound();
});
apiServer.use('/api/apps/public/:appId', (req, res) => {
const notFound = () => res.send(404);
const router = this.appRouters.get(req.params.appId);
if (router) {
return router(req, res, notFound);
}
notFound();
});
}
registerApi({ api, computedPath, endpoint }, appId) {
this.orch.debugLog(`The App ${ appId } is registering the api: "${ endpoint.path }" (${ computedPath })`);
this._verifyApi(api, endpoint);
if (!this.appRouters.get(appId)) {
this.appRouters.set(appId, express.Router()); // eslint-disable-line
}
const router = this.appRouters.get(appId);
const method = api.method || 'all';
let routePath = endpoint.path.trim();
if (!routePath.startsWith('/')) {
routePath = `/${ routePath }`;
}
router[method](routePath, Meteor.bindEnvironment(this._appApiExecutor(api, endpoint, appId)));
}
unregisterApis(appId) {
this.orch.debugLog(`The App ${ appId } is unregistering all apis`);
if (this.appRouters.get(appId)) {
this.appRouters.delete(appId);
}
}
_verifyApi(api, endpoint) {
if (typeof api !== 'object') {
throw new Error('Invalid Api parameter provided, it must be a valid IApi object.');
}
if (typeof endpoint.path !== 'string') {
throw new Error('Invalid Api parameter provided, it must be a valid IApi object.');
}
}
_appApiExecutor(api, endpoint, appId) {
return (req, res) => {
const request = {
method: req.method.toLowerCase(),
headers: req.headers,
query: req.query || {},
params: req.params || {},
content: req.body,
privateHash: req._privateHash,
};
this.orch.getManager().getApiManager().executeApi(appId, endpoint.path, request)
.then(({ status, headers = {}, content }) => {
res.set(headers);
res.status(status);
res.send(content);
})
.catch((reason) => {
// Should we handle this as an error?
res.status(500).send(reason.message);
});
};
}
}