/**
|
* AuthenticationController.js
|
*
|
* This controller handles login
|
*/
|
|
const ProcessArguments = require("../services/ProcessArguments");
|
const LocalFurnplan = require("../services/LocalFurnplan");
|
|
String.prototype.hexEncode = function () {
|
let hex, i;
|
let result = "";
|
for (i = 0; i < this.length; i++) {
|
hex = this.charCodeAt(i).toString(16);
|
result += ("000" + hex).slice(-4);
|
}
|
return result;
|
};
|
String.prototype.hexDecode = function () {
|
let j;
|
const hexes = this.match(/.{1,4}/g) || [];
|
let back = "";
|
for (j = 0; j < hexes.length; j++) {
|
back += String.fromCharCode(parseInt(hexes[j], 16));
|
}
|
return back;
|
};
|
|
const hash = function (str, decode) {
|
const hex = decode ? str : str.hexEncode();
|
let ret = "";
|
for (let c = 0; c < hex.length; c += 2) {
|
const one = hex[c];
|
const two = hex[c + 1];
|
ret += two;
|
ret += one;
|
}
|
return decode ? ret.hexDecode() : ret;
|
};
|
|
module.exports = {
|
|
/**
|
* Login page
|
*
|
* GET /login
|
*/
|
login: function (req, res) {
|
return res.view();
|
},
|
|
/**
|
* Login form
|
*
|
* POST /login
|
*/
|
login_form: async function (req, res) {
|
|
req.body.customerNo = req.body.customerNo || "";
|
req.body.username = req.body.username || "";
|
req.body.password = req.body.password || "";
|
|
req.body.customerNo.trim();
|
|
if (req.body.customerNo.toLowerCase() == "admin" && req.body.username.toLowerCase() == "admin") {
|
return res.json({ url: "/nice-try-dude", sessionId: "1337" });
|
}
|
|
// use access manager for protection from brute force attacks
|
AccessManagerService.create(req.auth_cookie);
|
|
const accessManager = req.auth_cookie.accessManager;
|
|
accessManager.setMaxTries(3).setPause(30);
|
|
if (accessManager.canTry()) {
|
try {
|
let user;
|
|
if (ProcessArguments.isLocal()) {
|
const customerNoOrTenant = req.body.customerNo;
|
|
const credential = await FurncloudCredential.findOne({ customerNo: customerNoOrTenant });
|
const existsCustomerNo = !!credential;
|
|
if (existsCustomerNo) {
|
// use customer number as specified
|
user = await Opus.login(customerNoOrTenant, "offlineUser", "offlineUser");
|
}
|
else {
|
// customer number seems to be a tenant, so try to find the corresponding customer number
|
const projectPath = await LocalFurnplan.getCustomerProjectsPath(customerNoOrTenant);
|
const customerNo = await LocalFurnplan.getCustomerNo(projectPath);
|
|
user = await Opus.login(customerNo, "offlineUser", "offlineUser");
|
}
|
}
|
else {
|
user = await Opus.login(req.body.customerNo, req.body.username, req.body.password, Helper.isLocalRequest(req.connection.remoteAddress) || !sails.config.needsAuth);
|
}
|
|
const configuration = await UseCaseConfiguration.findOne({
|
customerNo: req.body.customerNo,
|
externalConf: true
|
});
|
|
if (configuration) user.data.config = configuration.id;
|
|
await Session.update({ _id: req.session._id }, { $addToSet: { users: user } });
|
|
Winston.info((new Date).toISOString(), "Login granted with provided credentials:", req.body.customerNo, "/", req.body.username, "/", "***CENSORED***");
|
|
// delete access manager if everything went fine
|
delete accessManager;
|
delete req.auth_cookie.accessManager;
|
|
if (req.query.oriReq) return res.json({ url: req.query.oriReq, sessionId: user.opusSessionId });
|
|
return res.json({ url: "/", sessionId: user.opusSessionId });
|
}
|
catch (e) {
|
Winston.error(e);
|
accessManager.failed();
|
|
// TODO: i18n
|
return res.json(422, { error: "Ungültige Zugangsdaten" });
|
}
|
}
|
else {
|
// TODO: i18n
|
return res.json(422, { error: "Zugang gesperrt" });
|
}
|
},
|
|
/**
|
* Check if furnview
|
*/
|
check_access: function (req, res) {
|
if (req.param("c_sum")) {
|
let cToken = "";
|
let reverseExtendToken = req.param("c_sum");
|
if (reverseExtendToken) {
|
for (let t = reverseExtendToken.length - 2; t >= 0; t -= 2) {
|
cToken += reverseExtendToken[t];
|
}
|
cToken = new Buffer(cToken, "base64").toString("utf-8");
|
}
|
|
if (cToken) {
|
let str = hash(cToken, true);
|
const parting = str.length / 4;
|
const partOne = str.substr(0, parting);
|
const partTwo = str.substr(parting, parting);
|
const partThree = str.substr(parting * 2, parting);
|
const partFour = str.substr(parting * 3, parting);
|
const value = "suc" + partOne + "ce" + partTwo + "ss" + partThree + "furn" + partFour + "view";
|
str = hash(value);
|
cToken = Buffer.from(str).toString("base64");
|
reverseExtendToken = "";
|
for (let t = cToken.length - 1; t >= 0; t--) {
|
reverseExtendToken = reverseExtendToken + cToken[t] + String.fromCharCode(Math.floor(Math.random() * (90 - 65)) + 65);
|
}
|
res.status(200).json({ sec: reverseExtendToken });
|
}
|
else {
|
res.status(500).json({ err: "Failed! Internal Error." });
|
}
|
}
|
},
|
|
/**
|
* Logout
|
*
|
* POST /logout
|
*/
|
logout: async function (req, res) {
|
|
if (req.user) {
|
// close furnplan instance
|
FurnplanNodeManager.closeInstance(req.user.opusSessionId);
|
|
await Session.update({ _id: req.session._id }, { $pull: { users: { _id: req.user._id } } });
|
delete req.user;
|
}
|
|
let redirection = "/";
|
if (req.headers && req.headers.referer) {
|
if (new RegExp("article-url-configurator").test(req.headers.referer)) {
|
redirection = "/article-url-configurator";
|
}
|
}
|
return res.json({ url: redirection });
|
}
|
};
|