const https = require("https");
|
const http = require("http");
|
|
const { decode } = FurncloudSecurity;
|
const WebviewerError = require("furncloud-library").Errors.WebviewerError;
|
const FurnplanInstanceHistoryService = require("../services/FurnplanInstaceHistoryService.js");
|
|
function requestPDF(server, sessionID, pdfGuid, cloudId) {
|
return new Promise(function (resolve, reject) {
|
const httpRequest = server.split("https://").length > 1 ? https : http;
|
server = server.replace("https://", "");
|
server = server.replace("http://", "");
|
const split = server.split(":");
|
const options = {
|
port: split[1],
|
hostname: split[0],
|
path: "/getPDF/" + sessionID + "/" + pdfGuid + "/" + cloudId
|
};
|
|
const callback = function (response) {
|
let str = new Buffer("", "utf8");
|
|
//another chunk of data has been recieved, so append it to `str`
|
response.on("data", function (chunk) {
|
const chunkBuffer = new Buffer(chunk, "utf8");
|
const length = str.length + chunkBuffer.length;
|
str = Buffer.concat([str, chunkBuffer], length);
|
});
|
|
response.on("error", function () {
|
reject();
|
});
|
|
//the whole response has been recieved, so we just print it out here
|
response.on("end", function () {
|
resolve(str);
|
});
|
};
|
httpRequest.request(options, callback).end();
|
});
|
}
|
|
module.exports = {
|
|
/**
|
* Article viewer page by manufacturer, program and article number.
|
*/
|
view: function (req, res) {
|
const token = req.query.token;
|
const configurationId = req.query.a;
|
const encodedArticle = req.query.b;
|
|
const emptyArticle = {
|
manu: "",
|
level1: "",
|
level2: "",
|
prog: "",
|
artno: "",
|
entityType: "a"
|
};
|
|
try {
|
var decodedArticle = JSON.parse(RB64.decode(encodedArticle));
|
}
|
catch (e) {
|
Winston.warn("Invalid article specified: " + encodedArticle);
|
|
var decodedArticle = emptyArticle;
|
}
|
|
// if article number is specified, use regex, else use empty string
|
const wantedArticleNo = decodedArticle.artno.length > 0 ? new RegExp(decodedArticle.artno, "i") : "";
|
|
const wantedArticle = {
|
manu: decodedArticle.manu,
|
mprog: decodedArticle.prog,
|
artno: wantedArticleNo
|
};
|
|
const isWantedArticleEmpty = (wantedArticle.manu + wantedArticle.mprog + wantedArticle.artno).length === 0;
|
|
Promise.all([
|
req.user || Opus.login(token, "webshopViewer", "webshopViewer"),
|
FurncloudCredential.findOne({ token: token })
|
])
|
.then(async function ([user, credential]) {
|
|
user.customerNo = credential.customerNo;
|
user.userAgent = req.get("user-agent");
|
|
await FurnplanInstanceHistoryService.writeDocument(user.opusSessionId, user.customerNo, req.originalUrl, configurationId, "Configuration", req.headers["user-agent"] || req.headers["User-Agent"] || "");
|
|
if (req.query.land && req.query.schiene) {
|
user.data.tenant = (`${req.query.land}-${req.query.schiene}`) || "";
|
}
|
else if (req.query.tenant) {
|
user.data.tenant = req.query.tenant;
|
}
|
else {
|
user.data.tenant = "";
|
}
|
|
let query = {
|
_id: Mongoose.Types.ObjectId(configurationId),
|
customerNo: user.customerNo,
|
externalConf: false
|
};
|
|
query = await UseCaseConfigurationStorePermissionService.addStorePermission(query, user.customerNo);
|
|
return await UseCaseConfiguration
|
.findOne(query)
|
.populate("hrThemeSettings")
|
.populate("dynamicSettings")
|
.populate("accessListSettings")
|
.populate("propertyOrderLists")
|
.populate("defaultArticleList")
|
////////////////https://joope.de/issues/46324 Kamera Zoom Tisch Stuhl FS / JM
|
.populate({ path: "autoZoomConfig.ignoreBox", model: "AccessListSetting" })
|
.populate({ path: "autoZoomConfig.ignoreAngle", model: "AccessListSetting" })
|
////////////////
|
.then(function (configuration) {
|
if (configuration) user.data.config = configuration.id;
|
|
return Promise.all([
|
user,
|
configuration,
|
true, // Für Messe
|
Article.findOne(wantedArticle),
|
Helper.isLocalRequest(req.connection.remoteAddress),
|
Session.update({ _id: req.session._id }, { $addToSet: { users: user } }).exec()
|
]);
|
});
|
})
|
.then(async function ([user, configuration, hasAccess, article, isLocalRequest]) {
|
|
if (!configuration) throw new WebviewerError.InvalidConfigurationId(configurationId);
|
|
if (configuration.configuration.webui_mode === true && req.query["is-webui-embedded"] !== "1") {
|
return res.redirect(req.originalUrl.replace("/webviewer", "/webui"));
|
}
|
|
if (!(isWantedArticleEmpty || hasAccess)) throw new WebviewerError.NoPermission(wantedArticle.manu, wantedArticle.mprog, wantedArticle.artno);
|
if (!article) {
|
article = decodedArticle;
|
article.mprog = article.prog;
|
article.entityType = "a";
|
}
|
|
// globally disable logout and pick mode button in webviewer
|
configuration.get("configuration").toolbar_button_logout = false;
|
configuration.get("configuration").toolbar_button_pickMode = false;
|
|
const newConfiguration = await ConfigurationManager.newConfiguration();
|
|
ConfigurationManager.merge(newConfiguration, configuration);
|
// newConfiguration.load_initial_article = true;
|
// dynamic settings are optional
|
if (configuration.dynamicSettings) {
|
const logoImage = configuration.dynamicSettings.properties.filter(function (child) {
|
return child._id === "manu_logo";
|
});
|
|
if (logoImage.length > 0) {
|
newConfiguration.manu_logo = logoImage[0].value;
|
}
|
}
|
|
if (DevConfigService.get("fv_developer") === true || newConfiguration.furnview_developer_key === "4cfb8ed4d8988dc2c2acf7fdb4c28999601c7644") {
|
newConfiguration.panel_left_show = true;
|
}
|
newConfiguration.furnview_developer_key = undefined;
|
|
|
//Switch between furnview and furnview in wizard mode
|
let path = "webviewer/view";
|
if (newConfiguration.enable_wizard) {
|
path = "wizard/view";
|
}
|
if (newConfiguration.enable_wizard_generic) {
|
path = "wizard-generic/view";
|
}
|
|
if (article && article.prog) {
|
article.prog = article.prog.toUpperCase();
|
}
|
|
let url = new URL(req.baseUrl + req.originalUrl);
|
let encodedArticleCategoryString = url.searchParams.get("articleCategory") || "";
|
let decodedArticleCategory = [];
|
if(encodedArticleCategoryString) {
|
encodedArticleCategoryString = RB64.decode(encodedArticleCategoryString);
|
decodedArticleCategory = encodedArticleCategoryString.split(",").map(x => x.trim());
|
}
|
|
return res.view(path, {
|
g_token: token,
|
g_auth_id: req.auth_cookie.id,
|
g_configuration: newConfiguration,
|
g_article: article,
|
g_manufacturer: newConfiguration.selectedManufacturer || "",
|
g_sessionId: user.opusSessionId,
|
g_language: req.query.lang || req.getLocale(),
|
g_reCaptcha: Config.furnview.reCaptchaSiteKey || "",
|
g_article_categories: decodedArticleCategory
|
});
|
})
|
.catch(function (error) {
|
if (error instanceof WebviewerError.InvalidConfigurationId || error instanceof WebviewerError.NoPermission) {
|
Winston.warn("Webviewer: " + error.getMessage(), error);
|
return res.send(422, error.getMessage());
|
}
|
Winston.warn("Unable to open webviewer. ", error);
|
return res.send(500, "internal server error");
|
});
|
},
|
|
shareByMail: async function (req, res) {
|
const user = req.user;
|
|
if (!user) {
|
return res.status(403).json({ status: "forbidden" });
|
}
|
|
try {
|
const pdfData = req.body.pdfData;
|
const configurationId = await user.data.config;
|
let query = { _id: Mongoose.Types.ObjectId(configurationId) };
|
|
query = await UseCaseConfigurationStorePermissionService.addStorePermission(query, user.customerNo);
|
|
const configuration = await UseCaseConfiguration.findOne(query);
|
const shareMailConfigurationId = configuration.get("dynamicSettingsShareMail");
|
const shareMailConfiguration = await DynamicSetting.findOne({ _id: shareMailConfigurationId });
|
|
if (shareMailConfiguration) {
|
const mailSettings = shareMailConfiguration.properties.id(req.body.language || "de");
|
|
let mailServerDecoded = "";
|
let mailServer = null;
|
|
try {
|
mailServerDecoded = decode(shareMailConfiguration.get("mailServer"), sails.config.furnview.symmetricKey);
|
mailServer = JSON.parse(mailServerDecoded);
|
}
|
catch (e) {
|
console.error("Unable to decode mail server");
|
|
mailServer = null;
|
}
|
|
const options = {
|
to: req.body.to,
|
cc: mailSettings.get("cc") || "",
|
bcc: mailSettings.get("bcc") || "",
|
subject: mailSettings.get("value"),
|
html: mailSettings.get("value2"),
|
encoding: "quoted-printable",
|
attachments: []
|
};
|
|
if (mailServer) {
|
options.from = mailSettings.get("sender");
|
}
|
else {
|
options.from = "cloud@furnview.de";
|
options.replyTo = mailSettings.get("sender");
|
}
|
|
const values = [{ key: "url", value: req.body.url }, { key: "message", value: req.body.message }];
|
|
if (pdfData) {
|
const pdfBinary = await requestPDF(pdfData.server, pdfData.sessionId, pdfData.pdf, pdfData.cloudId);
|
|
options.attachments.push({
|
filename: mailSettings.pdfFilename.replace("{{cloudId}}", pdfData.cloudId),
|
path: "data:application/pdf;base64," + pdfBinary.toString("base64"),
|
contentType: "application/pdf"
|
});
|
|
values.push({ key: "cloudId", value: pdfData.cloudId });
|
}
|
|
values.forEach((customValue) => {
|
const key = customValue.key;
|
const value = customValue.value;
|
const regEx = new RegExp(`{{ ?${key} ?}}`, "g");
|
|
options.html = options.html.replace(regEx, value);
|
});
|
|
mailSettings.images.forEach((image) => {
|
options.attachments.push({
|
filename: image.filename,
|
path: image.data,
|
cid: image.cid
|
});
|
});
|
|
Mailer.sendHtmlMail(options, mailServer);
|
}
|
else {
|
const recipient = req.body.to;
|
const message = req.body.message;
|
const url = req.body.url;
|
|
const subject = req.__({ phrase: "fv.email.homeviewer.share_by_mail.subject", locale: req.getLocale() });
|
|
const attachments = [{
|
filename: "furnview.png",
|
path: "assets/images/furnview-mail.png",
|
cid: "furnview-logo"
|
}];
|
|
let template = req.__("fv.email.webviewer.share_by_mail.template");
|
|
template = Mailer.renderHtmlTemplate(template, { url, message });
|
|
Mailer.sendHtmlMail(recipient, "furnview@dh-software.de", subject, template, attachments);
|
}
|
|
return res.json({ status: "ok" });
|
}
|
catch (e) {
|
console.error("unable to share by mail", e);
|
|
return res.status(404).json({ status: "not found" });
|
}
|
}
|
};
|