| | |
| | | * 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 { OpusAuthenticationService } = require("../services/OpusAuthenticationService");
|
| | | const { OAuth2AuthenticationService } = require("../services/OAuth2AuthenticationService");
|
| | |
|
| | | 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;
|
| | | };
|
| | | let authenticationService;
|
| | |
|
| | | if (sails.config.oauth && sails.config.oauth.useNewAuthentication === true) {
|
| | | authenticationService = new OAuth2AuthenticationService();
|
| | | }
|
| | | else {
|
| | | authenticationService = new OpusAuthenticationService();
|
| | | }
|
| | |
|
| | | module.exports = {
|
| | |
|
| | | /**
|
| | | * Login page
|
| | | *
|
| | | * GET /login
|
| | | * GET /auth/login
|
| | | */
|
| | | login: function (req, res) {
|
| | | return res.view();
|
| | | return authenticationService.login(req, res);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Login form
|
| | | *
|
| | | * POST /login
|
| | | * POST /auth/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." });
|
| | | }
|
| | | }
|
| | | login_form: function (req, res) {
|
| | | return authenticationService.login_form(req, res);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Logout
|
| | | *
|
| | | * POST /logout
|
| | | * POST /auth/logout
|
| | | */
|
| | | logout: async function (req, res) {
|
| | | logout: function (req, res) {
|
| | | return authenticationService.logout(req, res);
|
| | | },
|
| | |
|
| | | if (req.user) {
|
| | | // close furnplan instance
|
| | | FurnplanNodeManager.closeInstance(req.user.opusSessionId);
|
| | | /**
|
| | | * OAuth Login Callback
|
| | | *
|
| | | * GET /auth/login/callback
|
| | | */
|
| | | callback(req, res) {
|
| | | return authenticationService.callback(req, res);
|
| | | },
|
| | |
|
| | | 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 });
|
| | | /**
|
| | | * OAuth Logout Callback
|
| | | *
|
| | | * POST /auth/logout/back-channel
|
| | | */
|
| | | backchannelLogout(req, res) {
|
| | | return authenticationService.backchannelLogout(req, res);
|
| | | }
|
| | | };
|