dh_ackergaul
2026-06-03 a25433795ec239654db2ef31af6d3f4e84b3b8dc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/**
 * 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 });
    }
};