mirror of
https://github.com/caprover/caprover
synced 2026-08-04 06:41:01 +00:00
194 lines
5.4 KiB
JavaScript
194 lines
5.4 KiB
JavaScript
let express = require('express');
|
|
let path = require('path');
|
|
let favicon = require('serve-favicon');
|
|
let logger = require('morgan');
|
|
let cookieParser = require('cookie-parser');
|
|
let bodyParser = require('body-parser');
|
|
let httpProxy = require('http-proxy').createProxyServer({});
|
|
|
|
let CaptainManager = require('./src/user/CaptainManager');
|
|
let BaseApi = require('./src/api/BaseApi');
|
|
let ApiStatusCodes = require('./src/api/ApiStatusCodes');
|
|
let Injector = require('./src/injection/Injector');
|
|
let Logger = require('./src/utils/Logger');
|
|
let CaptainConstants = require('./src/utils/CaptainConstants');
|
|
|
|
let LoginRouter = require('./src/routes/LoginRouter');
|
|
let UserRouter = require('./src/routes/UserRouter');
|
|
|
|
let app = express();
|
|
|
|
app.set('views', path.join(__dirname, 'views'));
|
|
app.set('view engine', 'ejs');
|
|
|
|
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
|
|
app.use(logger('dev'));
|
|
app.use(bodyParser.json());
|
|
app.use(bodyParser.urlencoded({extended: false}));
|
|
app.use(cookieParser());
|
|
|
|
if (CaptainConstants.isDebug) {
|
|
|
|
app.use('*', function (req, res, next) {
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
res.setHeader('Access-Control-Allow-Credentials', true);
|
|
res.setHeader('Access-Control-Allow-Headers', CaptainConstants.header.namespace + ',' + CaptainConstants.header.auth + ',Content-Type');
|
|
next();
|
|
});
|
|
|
|
app.use('/force-exit', function (req, res, next) {
|
|
|
|
res.send('Okay... I will exit in a second...');
|
|
|
|
setTimeout(function () {
|
|
process.exit(0);
|
|
}, 500);
|
|
|
|
});
|
|
}
|
|
|
|
app.use(Injector.injectGlobal());
|
|
|
|
app.use(function (req, res, next) {
|
|
|
|
if (res.locals.forceSsl) {
|
|
|
|
let isRequestSsl = (req.secure || req.get('X-Forwarded-Proto') === 'https');
|
|
|
|
if (!isRequestSsl) {
|
|
let newUrl = 'https://' + req.get('host') + req.originalUrl;
|
|
res.redirect(302, newUrl);
|
|
return;
|
|
}
|
|
}
|
|
|
|
next();
|
|
});
|
|
|
|
if (!CaptainConstants.isDebug) {
|
|
app.use(express.static(path.join(__dirname, 'dist')));
|
|
}
|
|
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
app.use(CaptainConstants.healthCheckEndPoint, function (req, res, next) {
|
|
|
|
res.send(CaptainManager.get().getHealthCheckUuid());
|
|
|
|
});
|
|
|
|
// ************ Beginning of reverse proxy 3rd party services ****************************************
|
|
|
|
app.use(CaptainConstants.netDataRelativePath, function (req, res, next) {
|
|
|
|
if (req.originalUrl.indexOf(CaptainConstants.netDataRelativePath + '/') !== 0) {
|
|
let newUrl = 'https://' + req.get('host') + CaptainConstants.netDataRelativePath + '/';
|
|
res.redirect(302, newUrl);
|
|
return;
|
|
}
|
|
|
|
next();
|
|
});
|
|
|
|
app.use(CaptainConstants.netDataRelativePath, Injector.injectUserUsingCookieDataOnly());
|
|
|
|
app.use(CaptainConstants.netDataRelativePath, function (req, res, next) {
|
|
|
|
if (!res.locals.user) {
|
|
Logger.e('User not logged in for NetData');
|
|
res.sendStatus(500);
|
|
}
|
|
else {
|
|
next()
|
|
}
|
|
});
|
|
|
|
app.use(CaptainConstants.netDataRelativePath, function (req, res, next) {
|
|
|
|
httpProxy.web(req, res, {target: 'http://' + CaptainConstants.netDataContainerName + ':19999'});
|
|
httpProxy.on('error', function (err, req, res) {
|
|
if (res.locals.errorProxyHandled) {
|
|
return;
|
|
}
|
|
|
|
if (err) {
|
|
Logger.e(err);
|
|
}
|
|
|
|
res.locals.errorProxyHandled = true;
|
|
res.writeHead(500, {
|
|
'Content-Type': 'text/plain'
|
|
});
|
|
|
|
res.end('Something went wrong... err: \n ' + (err ? err : 'NULL'));
|
|
});
|
|
|
|
});
|
|
|
|
// ************ End of reverse proxy 3rd party services ****************************************
|
|
|
|
|
|
// ********************* Beginning of API End Points *******************************************
|
|
|
|
let API_PREFIX = '/api/';
|
|
|
|
app.use(API_PREFIX + ':apiVersionFromRequest/', function (req, res, next) {
|
|
|
|
if (req.params.apiVersionFromRequest !== CaptainConstants.apiVersion) {
|
|
res.send(new BaseApi(ApiStatusCodes.STATUS_ERROR_GENERIC, 'This captain instance only accepts API V1.'));
|
|
return;
|
|
}
|
|
|
|
if (!res.locals.initialized) {
|
|
let response = new BaseApi(ApiStatusCodes.STATUS_ERROR_CAPTAIN_NOT_INITIALIZED,
|
|
'Captain is not ready yet...');
|
|
res.send(response);
|
|
return;
|
|
}
|
|
|
|
if (!res.locals.namespace && !req.originalUrl.startsWith(API_PREFIX + CaptainConstants.apiVersion + '/user/webhooks/')) {
|
|
res.send(new BaseApi(ApiStatusCodes.STATUS_ERROR_GENERIC, 'no namespace'));
|
|
return;
|
|
}
|
|
|
|
next();
|
|
});
|
|
|
|
// unsecured end points:
|
|
app.use(API_PREFIX + CaptainConstants.apiVersion + '/login/', LoginRouter);
|
|
|
|
// secured end points
|
|
app.use(API_PREFIX + CaptainConstants.apiVersion + '/user/', UserRouter);
|
|
|
|
|
|
// ********************* End of API End Points *******************************************
|
|
|
|
|
|
// catch 404 and forward to error handler
|
|
app.use(function (req, res, next) {
|
|
let err = new Error('Not Found');
|
|
err.status = 404;
|
|
next(err);
|
|
});
|
|
|
|
// error handler
|
|
app.use(function (err, req, res, next) {
|
|
// set locals, only providing error in development
|
|
res.locals.error = req.app.get('env') === 'development' ? err : {};
|
|
|
|
Logger.e(err);
|
|
|
|
// render the error page
|
|
res.sendStatus(err.status || 500);
|
|
});
|
|
|
|
// Initializing with delay helps with debugging. Many times, docker didn't see the CAPTAIN service
|
|
// if this was done without a delay
|
|
setTimeout(function () {
|
|
|
|
CaptainManager.get().initialize();
|
|
|
|
}, 1500);
|
|
|
|
module.exports = app;
|