Merge branch 'development' of https://github.com/Mailtrain-org/mailtrain into transactional-mail-v2
This commit is contained in:
commit
e3e1e7a086
153 changed files with 10570 additions and 9267 deletions
|
@ -1,76 +1,74 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const config = require('config');
|
||||
const log = require('./lib/log');
|
||||
const config = require("config");
|
||||
const log = require("./lib/log");
|
||||
|
||||
const express = require('express');
|
||||
const expressLocale = require('express-locale');
|
||||
const bodyParser = require('body-parser');
|
||||
const path = require('path');
|
||||
const favicon = require('serve-favicon');
|
||||
const logger = require('morgan');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const session = require('express-session');
|
||||
const flash = require('connect-flash');
|
||||
const hbs = require('hbs');
|
||||
const compression = require('compression');
|
||||
const passport = require('./lib/passport');
|
||||
const contextHelpers = require('./lib/context-helpers');
|
||||
const express = require("express");
|
||||
const expressLocale = require("express-locale");
|
||||
const bodyParser = require("body-parser");
|
||||
const path = require("path");
|
||||
const favicon = require("serve-favicon");
|
||||
const logger = require("morgan");
|
||||
const cookieParser = require("cookie-parser");
|
||||
const session = require("express-session");
|
||||
const flash = require("connect-flash");
|
||||
const hbs = require("hbs");
|
||||
const compression = require("compression");
|
||||
const passport = require("./lib/passport");
|
||||
const contextHelpers = require("./lib/context-helpers");
|
||||
|
||||
const api = require('./routes/api');
|
||||
const api = require("./routes/api");
|
||||
|
||||
// These are routes for the new React-based client
|
||||
const reports = require('./routes/reports');
|
||||
const subscriptions = require('./routes/subscriptions');
|
||||
const subscription = require('./routes/subscription');
|
||||
const sandboxedMosaico = require('./routes/sandboxed-mosaico');
|
||||
const sandboxedCKEditor = require('./routes/sandboxed-ckeditor');
|
||||
const sandboxedGrapesJS = require('./routes/sandboxed-grapesjs');
|
||||
const sandboxedCodeEditor = require('./routes/sandboxed-codeeditor');
|
||||
const files = require('./routes/files');
|
||||
const links = require('./routes/links');
|
||||
const archive = require('./routes/archive');
|
||||
const webhooks = require('./routes/webhooks');
|
||||
const reports = require("./routes/reports");
|
||||
const subscriptions = require("./routes/subscriptions");
|
||||
const subscription = require("./routes/subscription");
|
||||
const sandboxedMosaico = require("./routes/sandboxed-mosaico");
|
||||
const sandboxedCKEditor = require("./routes/sandboxed-ckeditor");
|
||||
const sandboxedGrapesJS = require("./routes/sandboxed-grapesjs");
|
||||
const sandboxedCodeEditor = require("./routes/sandboxed-codeeditor");
|
||||
const files = require("./routes/files");
|
||||
const links = require("./routes/links");
|
||||
const archive = require("./routes/archive");
|
||||
const webhooks = require("./routes/webhooks");
|
||||
|
||||
const namespacesRest = require('./routes/rest/namespaces');
|
||||
const sendConfigurationsRest = require('./routes/rest/send-configurations');
|
||||
const usersRest = require('./routes/rest/users');
|
||||
const accountRest = require('./routes/rest/account');
|
||||
const reportTemplatesRest = require('./routes/rest/report-templates');
|
||||
const reportsRest = require('./routes/rest/reports');
|
||||
const campaignsRest = require('./routes/rest/campaigns');
|
||||
const triggersRest = require('./routes/rest/triggers');
|
||||
const listsRest = require('./routes/rest/lists');
|
||||
const formsRest = require('./routes/rest/forms');
|
||||
const fieldsRest = require('./routes/rest/fields');
|
||||
const importsRest = require('./routes/rest/imports');
|
||||
const importRunsRest = require('./routes/rest/import-runs');
|
||||
const sharesRest = require('./routes/rest/shares');
|
||||
const segmentsRest = require('./routes/rest/segments');
|
||||
const subscriptionsRest = require('./routes/rest/subscriptions');
|
||||
const templatesRest = require('./routes/rest/templates');
|
||||
const mosaicoTemplatesRest = require('./routes/rest/mosaico-templates');
|
||||
const blacklistRest = require('./routes/rest/blacklist');
|
||||
const editorsRest = require('./routes/rest/editors');
|
||||
const filesRest = require('./routes/rest/files');
|
||||
const settingsRest = require('./routes/rest/settings');
|
||||
const namespacesRest = require("./routes/rest/namespaces");
|
||||
const sendConfigurationsRest = require("./routes/rest/send-configurations");
|
||||
const usersRest = require("./routes/rest/users");
|
||||
const accountRest = require("./routes/rest/account");
|
||||
const reportTemplatesRest = require("./routes/rest/report-templates");
|
||||
const reportsRest = require("./routes/rest/reports");
|
||||
const campaignsRest = require("./routes/rest/campaigns");
|
||||
const triggersRest = require("./routes/rest/triggers");
|
||||
const listsRest = require("./routes/rest/lists");
|
||||
const formsRest = require("./routes/rest/forms");
|
||||
const fieldsRest = require("./routes/rest/fields");
|
||||
const importsRest = require("./routes/rest/imports");
|
||||
const importRunsRest = require("./routes/rest/import-runs");
|
||||
const sharesRest = require("./routes/rest/shares");
|
||||
const segmentsRest = require("./routes/rest/segments");
|
||||
const subscriptionsRest = require("./routes/rest/subscriptions");
|
||||
const templatesRest = require("./routes/rest/templates");
|
||||
const mosaicoTemplatesRest = require("./routes/rest/mosaico-templates");
|
||||
const blacklistRest = require("./routes/rest/blacklist");
|
||||
const editorsRest = require("./routes/rest/editors");
|
||||
const filesRest = require("./routes/rest/files");
|
||||
const settingsRest = require("./routes/rest/settings");
|
||||
|
||||
const index = require('./routes/index');
|
||||
const index = require("./routes/index");
|
||||
|
||||
const interoperableErrors = require('../shared/interoperable-errors');
|
||||
|
||||
const { getTrustedUrl } = require('./lib/urls');
|
||||
const { AppType } = require('../shared/app');
|
||||
const interoperableErrors = require("../shared/interoperable-errors");
|
||||
|
||||
const { getTrustedUrl } = require("./lib/urls");
|
||||
const { AppType } = require("../shared/app");
|
||||
|
||||
let isReady = false;
|
||||
function setReady() {
|
||||
isReady = true;
|
||||
isReady = true;
|
||||
}
|
||||
|
||||
|
||||
hbs.registerPartials(__dirname + '/views/partials');
|
||||
hbs.registerPartials(__dirname + '/views/subscription/partials/');
|
||||
hbs.registerPartials(__dirname + "/views/partials");
|
||||
hbs.registerPartials(__dirname + "/views/subscription/partials/");
|
||||
|
||||
/**
|
||||
* We need this helper to make sure that we consume flash messages only
|
||||
|
@ -78,337 +76,388 @@ hbs.registerPartials(__dirname + '/views/subscription/partials/');
|
|||
* in a situation where we consume a flash messages but then comes a redirect
|
||||
* and the message is never displayed
|
||||
*/
|
||||
hbs.registerHelper('flash_messages', function () { // eslint-disable-line prefer-arrow-callback
|
||||
if (typeof this.flash !== 'function') { // eslint-disable-line no-invalid-this
|
||||
return '';
|
||||
}
|
||||
hbs.registerHelper("flash_messages", function() {
|
||||
// eslint-disable-line prefer-arrow-callback
|
||||
if (typeof this.flash !== "function") {
|
||||
// eslint-disable-line no-invalid-this
|
||||
return "";
|
||||
}
|
||||
|
||||
const messages = this.flash(); // eslint-disable-line no-invalid-this
|
||||
const response = [];
|
||||
const messages = this.flash(); // eslint-disable-line no-invalid-this
|
||||
const response = [];
|
||||
|
||||
// group messages by type
|
||||
for (const key in messages) {
|
||||
let el = '<div class="alert alert-' + key + ' alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>';
|
||||
// group messages by type
|
||||
for (const key in messages) {
|
||||
let el =
|
||||
'<div class="alert alert-' +
|
||||
key +
|
||||
' alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>';
|
||||
|
||||
if (key === 'danger') {
|
||||
el += '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> ';
|
||||
}
|
||||
if (key === "danger") {
|
||||
el +=
|
||||
'<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> ';
|
||||
}
|
||||
|
||||
let rows = [];
|
||||
let rows = [];
|
||||
|
||||
for (const message of messages[key]) {
|
||||
rows.push(hbs.handlebars.escapeExpression(message).replace(/(\r\n|\n|\r)/gm, '<br>'));
|
||||
}
|
||||
for (const message of messages[key]) {
|
||||
rows.push(
|
||||
hbs.handlebars
|
||||
.escapeExpression(message)
|
||||
.replace(/(\r\n|\n|\r)/gm, "<br>")
|
||||
);
|
||||
}
|
||||
|
||||
if (rows.length > 1) {
|
||||
el += '<p>' + rows.join('</p>\n<p>') + '</p>';
|
||||
} else {
|
||||
el += rows.join('');
|
||||
}
|
||||
if (rows.length > 1) {
|
||||
el += "<p>" + rows.join("</p>\n<p>") + "</p>";
|
||||
} else {
|
||||
el += rows.join("");
|
||||
}
|
||||
|
||||
el += '</div>';
|
||||
el += "</div>";
|
||||
|
||||
response.push(el);
|
||||
}
|
||||
response.push(el);
|
||||
}
|
||||
|
||||
return new hbs.handlebars.SafeString(
|
||||
response.join('\n')
|
||||
);
|
||||
return new hbs.handlebars.SafeString(response.join("\n"));
|
||||
});
|
||||
|
||||
|
||||
|
||||
function createApp(appType) {
|
||||
const app = express();
|
||||
const app = express();
|
||||
|
||||
function install404Fallback(url) {
|
||||
app.use(url, (req, res, next) => {
|
||||
next(new interoperableErrors.NotFoundError());
|
||||
});
|
||||
function install404Fallback(url) {
|
||||
app.use(url, (req, res, next) => {
|
||||
next(new interoperableErrors.NotFoundError());
|
||||
});
|
||||
|
||||
app.use(url + '/*', (req, res, next) => {
|
||||
next(new interoperableErrors.NotFoundError());
|
||||
});
|
||||
}
|
||||
app.use(url + "/*", (req, res, next) => {
|
||||
next(new interoperableErrors.NotFoundError());
|
||||
});
|
||||
}
|
||||
|
||||
function useWith404Fallback(url, route) {
|
||||
app.use(url, route);
|
||||
install404Fallback(url);
|
||||
}
|
||||
function useWith404Fallback(url, route) {
|
||||
app.use(url, route);
|
||||
install404Fallback(url);
|
||||
}
|
||||
|
||||
// view engine setup
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
app.set('view engine', 'hbs');
|
||||
// view engine setup
|
||||
app.set("views", path.join(__dirname, "views"));
|
||||
app.set("view engine", "hbs");
|
||||
|
||||
// Handle proxies. Needed to resolve client IP
|
||||
if (config.www.proxy) {
|
||||
app.set('trust proxy', config.www.proxy);
|
||||
}
|
||||
// Handle proxies. Needed to resolve client IP
|
||||
if (config.www.proxy) {
|
||||
app.set("trust proxy", config.www.proxy);
|
||||
}
|
||||
|
||||
// Do not expose software used
|
||||
app.disable('x-powered-by');
|
||||
// Do not expose software used
|
||||
app.disable("x-powered-by");
|
||||
|
||||
app.use(compression());
|
||||
app.use(favicon(path.join(__dirname, '..', 'client', 'static', 'favicon.ico')));
|
||||
app.use(compression());
|
||||
app.use(
|
||||
favicon(path.join(__dirname, "..", "client", "static", "favicon.ico"))
|
||||
);
|
||||
|
||||
app.use(logger(config.www.log, {
|
||||
stream: {
|
||||
write: message => {
|
||||
message = (message || '').toString();
|
||||
if (message) {
|
||||
log.info('HTTP', message.replace('\n', '').trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
app.use(
|
||||
logger(config.www.log, {
|
||||
stream: {
|
||||
write: message => {
|
||||
message = (message || "").toString();
|
||||
if (message) {
|
||||
log.info("HTTP", message.replace("\n", "").trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
app.use(cookieParser());
|
||||
app.use(cookieParser());
|
||||
|
||||
if (config.redis.enabled) {
|
||||
const RedisStore = require('connect-redis')(session);
|
||||
if (config.redis.enabled) {
|
||||
const RedisStore = require("connect-redis")(session);
|
||||
|
||||
app.use(session({
|
||||
store: new RedisStore(config.redis),
|
||||
secret: config.www.secret,
|
||||
saveUninitialized: false,
|
||||
resave: false
|
||||
}));
|
||||
} else {
|
||||
app.use(session({
|
||||
store: false,
|
||||
secret: config.www.secret,
|
||||
saveUninitialized: false,
|
||||
resave: false
|
||||
}));
|
||||
}
|
||||
app.use(
|
||||
session({
|
||||
store: new RedisStore(config.redis),
|
||||
secret: config.www.secret,
|
||||
saveUninitialized: false,
|
||||
resave: false
|
||||
})
|
||||
);
|
||||
} else {
|
||||
app.use(
|
||||
session({
|
||||
store: false,
|
||||
secret: config.www.secret,
|
||||
saveUninitialized: false,
|
||||
resave: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
app.use(expressLocale({
|
||||
priority: ['query', 'cookie', 'accept-language', 'default'],
|
||||
query: {
|
||||
name: 'locale'
|
||||
},
|
||||
cookie: {
|
||||
name: 'i18nextLng'
|
||||
},
|
||||
default: config.defaultLanguage
|
||||
}));
|
||||
app.use(
|
||||
expressLocale({
|
||||
priority: ["query", "cookie", "accept-language", "default"],
|
||||
query: {
|
||||
name: "locale"
|
||||
},
|
||||
cookie: {
|
||||
name: "i18nextLng"
|
||||
},
|
||||
default: config.defaultLanguage
|
||||
})
|
||||
);
|
||||
|
||||
app.use(flash());
|
||||
app.use(flash());
|
||||
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true,
|
||||
limit: config.www.postSize
|
||||
}));
|
||||
app.use(
|
||||
bodyParser.urlencoded({
|
||||
extended: true,
|
||||
limit: config.www.postSize
|
||||
})
|
||||
);
|
||||
|
||||
app.use(bodyParser.text({
|
||||
limit: config.www.postSize
|
||||
}));
|
||||
app.use(
|
||||
bodyParser.text({
|
||||
limit: config.www.postSize
|
||||
})
|
||||
);
|
||||
|
||||
app.use(bodyParser.json({
|
||||
limit: config.www.postSize
|
||||
}));
|
||||
app.use(
|
||||
bodyParser.json({
|
||||
limit: config.www.postSize
|
||||
})
|
||||
);
|
||||
|
||||
app.use((req, res, next) => {
|
||||
if (isReady) {
|
||||
next();
|
||||
} else {
|
||||
res.status(500);
|
||||
res.render("error", {
|
||||
message: "Mailtrain is starting. Try again after a few seconds.",
|
||||
error: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.use((req, res, next) => {
|
||||
if (isReady) {
|
||||
next();
|
||||
} else {
|
||||
res.status(500);
|
||||
res.render('error', {
|
||||
message: 'Mailtrain is starting. Try again after a few seconds.',
|
||||
error: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (appType === AppType.TRUSTED) {
|
||||
passport.setupRegularAuth(app);
|
||||
} else if (appType === AppType.SANDBOXED) {
|
||||
app.use(passport.tryAuthByRestrictedAccessToken);
|
||||
}
|
||||
|
||||
if (appType === AppType.TRUSTED) {
|
||||
passport.setupRegularAuth(app);
|
||||
} else if (appType === AppType.SANDBOXED) {
|
||||
app.use(passport.tryAuthByRestrictedAccessToken);
|
||||
}
|
||||
if (appType === AppType.TRUSTED || appType === AppType.SANDBOXED) {
|
||||
// Endpoint under /api are authenticated by access token
|
||||
app.all("/api/*", passport.authByAccessToken);
|
||||
}
|
||||
|
||||
if (appType === AppType.TRUSTED || appType === AppType.SANDBOXED) {
|
||||
// Endpoint under /api are authenticated by access token
|
||||
app.all('/api/*', passport.authByAccessToken);
|
||||
}
|
||||
useWith404Fallback(
|
||||
"/static",
|
||||
express.static(path.join(__dirname, "..", "client", "static"))
|
||||
);
|
||||
useWith404Fallback(
|
||||
"/client",
|
||||
express.static(path.join(__dirname, "..", "client", "dist"))
|
||||
);
|
||||
|
||||
useWith404Fallback('/static', express.static(path.join(__dirname, '..', 'client', 'static')));
|
||||
useWith404Fallback('/client', express.static(path.join(__dirname, '..', 'client', 'dist')));
|
||||
useWith404Fallback(
|
||||
"/static-npm/fontawesome",
|
||||
express.static(
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"client",
|
||||
"node_modules",
|
||||
"@fortawesome",
|
||||
"fontawesome-free",
|
||||
"webfonts"
|
||||
)
|
||||
)
|
||||
);
|
||||
useWith404Fallback(
|
||||
"/static-npm/jquery.min.js",
|
||||
express.static(
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"client",
|
||||
"node_modules",
|
||||
"jquery",
|
||||
"dist",
|
||||
"jquery.min.js"
|
||||
)
|
||||
)
|
||||
);
|
||||
useWith404Fallback(
|
||||
"/static-npm/popper.min.js",
|
||||
express.static(
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"client",
|
||||
"node_modules",
|
||||
"popper.js",
|
||||
"dist",
|
||||
"umd",
|
||||
"popper.min.js"
|
||||
)
|
||||
)
|
||||
);
|
||||
useWith404Fallback(
|
||||
"/static-npm/bootstrap.min.js",
|
||||
express.static(
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"client",
|
||||
"node_modules",
|
||||
"bootstrap",
|
||||
"dist",
|
||||
"js",
|
||||
"bootstrap.min.js"
|
||||
)
|
||||
)
|
||||
);
|
||||
useWith404Fallback(
|
||||
"/static-npm/coreui.min.js",
|
||||
express.static(
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"client",
|
||||
"node_modules",
|
||||
"@coreui",
|
||||
"coreui",
|
||||
"dist",
|
||||
"js",
|
||||
"coreui.min.js"
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
useWith404Fallback('/static-npm/fontawesome', express.static(path.join(__dirname, '..', 'client', 'node_modules', '@fortawesome', 'fontawesome-free', 'webfonts')));
|
||||
useWith404Fallback('/static-npm/jquery.min.js', express.static(path.join(__dirname, '..', 'client', 'node_modules', 'jquery', 'dist', 'jquery.min.js')));
|
||||
useWith404Fallback('/static-npm/popper.min.js', express.static(path.join(__dirname, '..', 'client', 'node_modules', 'popper.js', 'dist', 'umd', 'popper.min.js')));
|
||||
useWith404Fallback('/static-npm/bootstrap.min.js', express.static(path.join(__dirname, '..', 'client', 'node_modules', 'bootstrap', 'dist', 'js', 'bootstrap.min.js')));
|
||||
useWith404Fallback('/static-npm/coreui.min.js', express.static(path.join(__dirname, '..', 'client', 'node_modules', '@coreui', 'coreui', 'dist', 'js', 'coreui.min.js')));
|
||||
// Make sure flash messages are available
|
||||
// Currently, flash messages are used only from routes/subscription.js
|
||||
app.use((req, res, next) => {
|
||||
res.locals.flash = req.flash.bind(req);
|
||||
next();
|
||||
});
|
||||
|
||||
// Marks the following endpoint to return JSON object when error occurs
|
||||
app.all("/api/*", (req, res, next) => {
|
||||
req.needsAPIJSONResponse = true;
|
||||
next();
|
||||
});
|
||||
|
||||
// Make sure flash messages are available
|
||||
// Currently, flash messages are used only from routes/subscription.js
|
||||
app.use((req, res, next) => {
|
||||
res.locals.flash = req.flash.bind(req);
|
||||
next();
|
||||
});
|
||||
app.all("/rest/*", (req, res, next) => {
|
||||
req.needsRESTJSONResponse = true;
|
||||
next();
|
||||
});
|
||||
|
||||
// Marks the following endpoint to return JSON object when error occurs
|
||||
app.all('/api/*', (req, res, next) => {
|
||||
req.needsAPIJSONResponse = true;
|
||||
next();
|
||||
});
|
||||
// Initializes the request context to be used for authorization
|
||||
app.use((req, res, next) => {
|
||||
req.context = contextHelpers.getRequestContext(req);
|
||||
next();
|
||||
});
|
||||
|
||||
app.all('/rest/*', (req, res, next) => {
|
||||
req.needsRESTJSONResponse = true;
|
||||
next();
|
||||
});
|
||||
if (appType === AppType.PUBLIC) {
|
||||
useWith404Fallback("/subscription", subscription);
|
||||
useWith404Fallback("/links", links);
|
||||
useWith404Fallback("/archive", archive);
|
||||
useWith404Fallback("/files", files);
|
||||
}
|
||||
|
||||
// Initializes the request context to be used for authorization
|
||||
app.use((req, res, next) => {
|
||||
req.context = contextHelpers.getRequestContext(req);
|
||||
next();
|
||||
});
|
||||
useWith404Fallback("/mosaico", sandboxedMosaico.getRouter(appType));
|
||||
useWith404Fallback("/ckeditor", sandboxedCKEditor.getRouter(appType));
|
||||
useWith404Fallback("/grapesjs", sandboxedGrapesJS.getRouter(appType));
|
||||
useWith404Fallback("/codeeditor", sandboxedCodeEditor.getRouter(appType));
|
||||
|
||||
if (appType === AppType.PUBLIC) {
|
||||
useWith404Fallback('/subscription', subscription);
|
||||
useWith404Fallback('/links', links);
|
||||
useWith404Fallback('/archive', archive);
|
||||
useWith404Fallback('/files', files);
|
||||
}
|
||||
if (appType === AppType.TRUSTED || appType === AppType.SANDBOXED) {
|
||||
useWith404Fallback("/subscriptions", subscriptions);
|
||||
useWith404Fallback("/webhooks", webhooks);
|
||||
|
||||
useWith404Fallback('/mosaico', sandboxedMosaico.getRouter(appType));
|
||||
useWith404Fallback('/ckeditor', sandboxedCKEditor.getRouter(appType));
|
||||
useWith404Fallback('/grapesjs', sandboxedGrapesJS.getRouter(appType));
|
||||
useWith404Fallback('/codeeditor', sandboxedCodeEditor.getRouter(appType));
|
||||
if (config.reports && config.reports.enabled === true) {
|
||||
useWith404Fallback("/rpts", reports); // This needs to be different from "reports", which is already used by the UI
|
||||
}
|
||||
|
||||
if (appType === AppType.TRUSTED || appType === AppType.SANDBOXED) {
|
||||
useWith404Fallback('/subscriptions', subscriptions);
|
||||
useWith404Fallback('/webhooks', webhooks);
|
||||
// API endpoints
|
||||
useWith404Fallback("/api", api);
|
||||
|
||||
if (config.reports && config.reports.enabled === true) {
|
||||
useWith404Fallback('/rpts', reports); // This needs to be different from "reports", which is already used by the UI
|
||||
}
|
||||
// REST endpoints
|
||||
app.use("/rest", namespacesRest);
|
||||
app.use("/rest", sendConfigurationsRest);
|
||||
app.use("/rest", usersRest);
|
||||
app.use("/rest", accountRest);
|
||||
app.use("/rest", campaignsRest);
|
||||
app.use("/rest", triggersRest);
|
||||
app.use("/rest", listsRest);
|
||||
app.use("/rest", formsRest);
|
||||
app.use("/rest", fieldsRest);
|
||||
app.use("/rest", importsRest);
|
||||
app.use("/rest", importRunsRest);
|
||||
app.use("/rest", sharesRest);
|
||||
app.use("/rest", segmentsRest);
|
||||
app.use("/rest", subscriptionsRest);
|
||||
app.use("/rest", templatesRest);
|
||||
app.use("/rest", mosaicoTemplatesRest);
|
||||
app.use("/rest", blacklistRest);
|
||||
app.use("/rest", editorsRest);
|
||||
app.use("/rest", filesRest);
|
||||
app.use("/rest", settingsRest);
|
||||
|
||||
// API endpoints
|
||||
useWith404Fallback('/api', api);
|
||||
if (config.reports && config.reports.enabled === true) {
|
||||
app.use("/rest", reportTemplatesRest);
|
||||
app.use("/rest", reportsRest);
|
||||
}
|
||||
install404Fallback("/rest");
|
||||
}
|
||||
|
||||
// REST endpoints
|
||||
app.use('/rest', namespacesRest);
|
||||
app.use('/rest', sendConfigurationsRest);
|
||||
app.use('/rest', usersRest);
|
||||
app.use('/rest', accountRest);
|
||||
app.use('/rest', campaignsRest);
|
||||
app.use('/rest', triggersRest);
|
||||
app.use('/rest', listsRest);
|
||||
app.use('/rest', formsRest);
|
||||
app.use('/rest', fieldsRest);
|
||||
app.use('/rest', importsRest);
|
||||
app.use('/rest', importRunsRest);
|
||||
app.use('/rest', sharesRest);
|
||||
app.use('/rest', segmentsRest);
|
||||
app.use('/rest', subscriptionsRest);
|
||||
app.use('/rest', templatesRest);
|
||||
app.use('/rest', mosaicoTemplatesRest);
|
||||
app.use('/rest', blacklistRest);
|
||||
app.use('/rest', editorsRest);
|
||||
app.use('/rest', filesRest);
|
||||
app.use('/rest', settingsRest);
|
||||
app.use("/", index.getRouter(appType));
|
||||
|
||||
if (config.reports && config.reports.enabled === true) {
|
||||
app.use('/rest', reportTemplatesRest);
|
||||
app.use('/rest', reportsRest);
|
||||
}
|
||||
install404Fallback('/rest');
|
||||
}
|
||||
app.use((err, req, res, next) => {
|
||||
if (!err) {
|
||||
return next();
|
||||
}
|
||||
|
||||
app.use('/', index.getRouter(appType));
|
||||
if (req.needsRESTJSONResponse) {
|
||||
const resp = {
|
||||
message: err.message,
|
||||
error: config.sendStacktracesToClient ? err : {}
|
||||
};
|
||||
|
||||
// Error handlers
|
||||
if (app.get('env') === 'development' || app.get('env') === 'test') {
|
||||
// development error handler
|
||||
// will print stacktrace
|
||||
app.use((err, req, res, next) => {
|
||||
if (!err) {
|
||||
return next();
|
||||
}
|
||||
if (err instanceof interoperableErrors.InteroperableError) {
|
||||
resp.type = err.type;
|
||||
resp.data = err.data;
|
||||
}
|
||||
|
||||
if (req.needsRESTJSONResponse) {
|
||||
const resp = {
|
||||
message: err.message,
|
||||
error: err
|
||||
};
|
||||
log.verbose("HTTP", err);
|
||||
res.status(err.status || 500).json(resp);
|
||||
} else if (req.needsAPIJSONResponse) {
|
||||
const resp = {
|
||||
error: err.message || err,
|
||||
data: []
|
||||
};
|
||||
|
||||
if (err instanceof interoperableErrors.InteroperableError) {
|
||||
resp.type = err.type;
|
||||
resp.data = err.data;
|
||||
}
|
||||
log.verbose("HTTP", err);
|
||||
return res.status(err.status || 500).json(resp);
|
||||
} else {
|
||||
// TODO: Render interoperable errors using a special client that does internationalization of the error message
|
||||
|
||||
res.status(err.status || 500).json(resp);
|
||||
if (err instanceof interoperableErrors.NotLoggedInError) {
|
||||
return res.redirect(
|
||||
getTrustedUrl("/login?next=" + encodeURIComponent(req.originalUrl))
|
||||
);
|
||||
} else {
|
||||
log.verbose("HTTP", err);
|
||||
res.status(err.status || 500);
|
||||
res.render("error", {
|
||||
message: err.message,
|
||||
error: config.sendStacktracesToClient ? err : {}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else if (req.needsAPIJSONResponse) {
|
||||
const resp = {
|
||||
error: err.message || err,
|
||||
data: []
|
||||
};
|
||||
|
||||
return res.status(err.status || 500).json(resp);
|
||||
|
||||
} else {
|
||||
if (err instanceof interoperableErrors.NotLoggedInError) {
|
||||
return res.redirect(getTrustedUrl('/login?next=' + encodeURIComponent(req.originalUrl)));
|
||||
} else {
|
||||
res.status(err.status || 500);
|
||||
res.render('error', {
|
||||
message: err.message,
|
||||
error: err
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
// production error handler
|
||||
// no stacktraces leaked to user
|
||||
app.use((err, req, res, next) => {
|
||||
if (!err) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (req.needsRESTJSONResponse) {
|
||||
const resp = {
|
||||
message: err.message,
|
||||
error: {}
|
||||
};
|
||||
|
||||
if (err instanceof interoperableErrors.InteroperableError) {
|
||||
resp.type = err.type;
|
||||
resp.data = err.data;
|
||||
}
|
||||
|
||||
res.status(err.status || 500).json(resp);
|
||||
|
||||
} else if (req.needsAPIJSONResponse) {
|
||||
const resp = {
|
||||
error: err.message || err,
|
||||
data: []
|
||||
};
|
||||
|
||||
return res.status(err.status || 500).json(resp);
|
||||
|
||||
} else {
|
||||
// TODO: Render interoperable errors using a special client that does internationalization of the error message
|
||||
|
||||
if (err instanceof interoperableErrors.NotLoggedInError) {
|
||||
return res.redirect(getTrustedUrl('/login?next=' + encodeURIComponent(req.originalUrl)));
|
||||
} else {
|
||||
res.status(err.status || 500);
|
||||
res.render('error', {
|
||||
message: err.message,
|
||||
error: {}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return app;
|
||||
return app;
|
||||
}
|
||||
|
||||
module.exports.createApp = createApp;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue