"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoginProvider = exports.samlauthstrategyoptions = exports.googleauthstrategyoptions = exports.Provider = void 0;
var crypto = require("crypto");
var url = require("url");
var cookieSession = require("cookie-session");
var bodyParser = require("body-parser");
var path = require("path");
// import * as SAMLStrategy from "passport-saml";
var GoogleStrategy = require("passport-google-oauth20");
var LocalStrategy = require("passport-local");
var passport = require("passport");
var Config_1 = require("./Config");
var Crypt_1 = require("./Crypt");
var Audit_1 = require("./Audit");
var saml = require("saml20");
var multer = require('multer');
var GridFsStorage = require('multer-gridfs-storage');
var mongodb_1 = require("mongodb");
var openflow_api_1 = require("@openiap/openflow-api");
var DBHelper_1 = require("./DBHelper");
var safeObjectID = function (s) { return mongodb_1.ObjectID.isValid(s) ? new mongodb_1.ObjectID(s) : null; };
var Provider = /** @class */ (function (_super) {
    __extends(Provider, _super);
    function Provider() {
        var _this = _super.call(this) || this;
        _this.provider = "";
        _this.id = "";
        _this.name = "";
        _this.issuer = "";
        _this.saml_federation_metadata = "";
        _this._type = "provider";
        return _this;
    }
    return Provider;
}(openflow_api_1.Base));
exports.Provider = Provider;
// tslint:disable-next-line: class-name
var googleauthstrategyoptions = /** @class */ (function () {
    function googleauthstrategyoptions() {
        this.clientID = "";
        this.clientSecret = "";
        this.callbackURL = "auth/strategy/callback/";
        this.scope = ["profile", "email"];
    }
    return googleauthstrategyoptions;
}());
exports.googleauthstrategyoptions = googleauthstrategyoptions;
// tslint:disable-next-line: class-name
var samlauthstrategyoptions = /** @class */ (function () {
    function samlauthstrategyoptions() {
        this.callbackUrl = "auth/strategy/callback/";
        this.entryPoint = "";
        this.issuer = "";
        this.cert = null;
        this.audience = null;
        this.signatureAlgorithm = "sha256";
        this.callbackMethod = "POST";
    }
    return samlauthstrategyoptions;
}());
exports.samlauthstrategyoptions = samlauthstrategyoptions;
var LoginProvider = /** @class */ (function () {
    function LoginProvider() {
    }
    LoginProvider.escape = function (s) {
        var lookup = {
            '&': "&amp;",
            '"': "&quot;",
            '<': "&lt;",
            '>': "&gt;"
        };
        return s.replace(/[&"<>]/g, function (c) { return lookup[c]; });
    };
    LoginProvider.redirect = function (res, originalUrl) {
        res.write('<!DOCTYPE html>');
        res.write('<body>');
        // res.write('<script>top.location = "' + encodeURI(originalUrl) + '";</script>');
        res.write('<script>top.location = "' + LoginProvider.escape(originalUrl) + '";</script>');
        // res.write('<a href="' + originalUrl + '">click here</a>');
        res.write('</body>');
        res.write('</html>');
        res.end();
        // res.redirect(originalUrl);
    };
    LoginProvider.validateToken = function (rawAssertion) {
        return __awaiter(this, void 0, void 0, function () {
            var _this = this;
            return __generator(this, function (_a) {
                return [2 /*return*/, new Promise(function (resolve, reject) {
                        var options = {
                            publicKey: Buffer.from(Config_1.Config.signing_crt, "base64").toString("ascii")
                        };
                        saml.validate(rawAssertion, options, function (err, profile) { return __awaiter(_this, void 0, void 0, function () {
                            var claims, username, user, error_1;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        _a.trys.push([0, 2, , 3]);
                                        if (err) {
                                            return [2 /*return*/, reject(err)];
                                        }
                                        claims = profile.claims;
                                        username = claims["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"] ||
                                            claims["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"] ||
                                            claims["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"];
                                        return [4 /*yield*/, DBHelper_1.DBHelper.FindByUsername(username)];
                                    case 1:
                                        user = _a.sent();
                                        if (user) {
                                            resolve(user);
                                        }
                                        else {
                                            reject("Unknown user");
                                        }
                                        return [3 /*break*/, 3];
                                    case 2:
                                        error_1 = _a.sent();
                                        reject(error_1);
                                        return [3 /*break*/, 3];
                                    case 3: return [2 /*return*/];
                                }
                            });
                        }); });
                    })];
            });
        });
    };
    LoginProvider.getProviders = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _a, result, item;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = LoginProvider;
                        return [4 /*yield*/, Config_1.Config.db.query({ _type: "provider" }, null, 10, 0, null, "config", Crypt_1.Crypt.rootToken())];
                    case 1:
                        _a.login_providers = _b.sent();
                        result = [];
                        LoginProvider.login_providers.forEach(function (provider) {
                            var item = { name: provider.name, id: provider.id, provider: provider.provider, logo: "fa-question-circle" };
                            if (provider.provider === "google") {
                                item.logo = "fa-google";
                            }
                            if (provider.provider === "saml") {
                                item.logo = "fa-windows";
                            }
                            result.push(item);
                        });
                        if (result.length === 0) {
                            item = { name: "Local", id: "local", provider: "local", logo: "fa-question-circle" };
                            result.push(item);
                        }
                        return [2 /*return*/, result];
                }
            });
        });
    };
    LoginProvider.configure = function (logger, app, baseurl) {
        return __awaiter(this, void 0, void 0, function () {
            var storage, upload_1;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        LoginProvider._logger = logger;
                        app.use(cookieSession({
                            name: "session", secret: Config_1.Config.cookie_secret
                        }));
                        app.use(passport.initialize());
                        app.use(passport.session());
                        passport.serializeUser(function (user, done) {
                            return __awaiter(this, void 0, void 0, function () {
                                return __generator(this, function (_a) {
                                    done(null, user);
                                    return [2 /*return*/];
                                });
                            });
                        });
                        passport.deserializeUser(function (user, done) {
                            done(null, user);
                        });
                        app.use(function (req, res, next) {
                            res.header('Access-Control-Allow-Origin', req.headers.origin);
                            res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                            res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
                            res.header('Expires', '-1');
                            res.header('Pragma', 'no-cache');
                            next();
                        });
                        app.get("/Signout", function (req, res, next) {
                            // const providerid: string = req.cookies.provider;
                            // const provider: passport.Strategy;
                            // if (providerid != null && providerid != undefined && providerid != "") {
                            //     provider = LoginProvider._providers[providerid];
                            // }
                            // if (provider != null && provider != undefined) {
                            //     (provider as any).logout(req, function (err, requestUrl) {
                            //         // LOCAL logout
                            //         req.logout();
                            //         // redirect to the IdP with the encrypted SAML logout request
                            //         res.redirect(requestUrl);
                            //     });
                            //     return;
                            // }
                            req.logout();
                            var originalUrl = req.cookies.originalUrl;
                            if (!openflow_api_1.NoderedUtil.IsNullEmpty(originalUrl)) {
                                res.cookie("originalUrl", "", { expires: new Date(0) });
                                LoginProvider.redirect(res, originalUrl);
                            }
                            else {
                                res.redirect("/");
                            }
                        });
                        app.get("/PassiveSignout", function (req, res, next) {
                            req.logout();
                            var originalUrl = req.cookies.originalUrl;
                            if (!openflow_api_1.NoderedUtil.IsNullEmpty(originalUrl)) {
                                res.cookie("originalUrl", "", { expires: new Date(0) });
                                LoginProvider.redirect(res, originalUrl);
                            }
                            else {
                                res.redirect("/Login");
                            }
                        });
                        return [4 /*yield*/, LoginProvider.RegisterProviders(app, baseurl)];
                    case 1:
                        _a.sent();
                        app.get("/user", function (req, res, next) { return __awaiter(_this, void 0, void 0, function () {
                            var user;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        // console.log("/user " + !(req.user == null));
                                        res.setHeader("Content-Type", "application/json");
                                        if (!req.user) return [3 /*break*/, 2];
                                        return [4 /*yield*/, DBHelper_1.DBHelper.FindById(req.user._id)];
                                    case 1:
                                        user = _a.sent();
                                        res.end(JSON.stringify(user));
                                        return [3 /*break*/, 3];
                                    case 2:
                                        res.end(JSON.stringify({}));
                                        _a.label = 3;
                                    case 3:
                                        res.end();
                                        return [2 /*return*/];
                                }
                            });
                        }); });
                        app.get("/jwt", function (req, res, next) {
                            // console.log("/jwt " + !(req.user == null));
                            res.setHeader("Content-Type", "application/json");
                            if (req.user) {
                                var user = openflow_api_1.TokenUser.From(req.user);
                                res.end(JSON.stringify({ jwt: Crypt_1.Crypt.createToken(user, Config_1.Config.shorttoken_expires_in), user: user }));
                            }
                            else {
                                res.end(JSON.stringify({ jwt: "" }));
                            }
                            res.end();
                        });
                        app.get("/jwtlong", function (req, res, next) {
                            // console.log("/jwtlong " + !(req.user == null));
                            res.setHeader("Content-Type", "application/json");
                            if (req.user) {
                                var user = openflow_api_1.TokenUser.From(req.user);
                                if (!(user.validated == true) && Config_1.Config.validate_user_form != "") {
                                    res.end(JSON.stringify({ jwt: "" }));
                                }
                                else {
                                    res.end(JSON.stringify({ jwt: Crypt_1.Crypt.createToken(user, Config_1.Config.longtoken_expires_in), user: user }));
                                }
                            }
                            else {
                                res.end(JSON.stringify({ jwt: "" }));
                            }
                            res.end();
                        });
                        app.post("/jwt", function (req, res, next) { return __awaiter(_this, void 0, void 0, function () {
                            var rawAssertion, user, tuser, error_2;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        _a.trys.push([0, 2, , 3]);
                                        rawAssertion = req.body.token;
                                        return [4 /*yield*/, LoginProvider.validateToken(rawAssertion)];
                                    case 1:
                                        user = _a.sent();
                                        tuser = openflow_api_1.TokenUser.From(user);
                                        res.setHeader("Content-Type", "application/json");
                                        res.end(JSON.stringify({ jwt: Crypt_1.Crypt.createToken(tuser, Config_1.Config.shorttoken_expires_in) }));
                                        return [3 /*break*/, 3];
                                    case 2:
                                        error_2 = _a.sent();
                                        console.error(error_2.message ? error_2.message : error_2);
                                        return [2 /*return*/, res.status(500).send({ message: error_2.message ? error_2.message : error_2 })];
                                    case 3: return [2 /*return*/];
                                }
                            });
                        }); });
                        app.get("/config", function (req, res, next) {
                            var _url = Config_1.Config.basewsurl();
                            if (!openflow_api_1.NoderedUtil.IsNullEmpty(Config_1.Config.api_ws_url))
                                _url = Config_1.Config.api_ws_url;
                            if (!_url.endsWith("/"))
                                _url += "/";
                            var res2 = {
                                wshost: _url,
                                wsurl: _url,
                                domain: Config_1.Config.domain,
                                allow_user_registration: Config_1.Config.allow_user_registration,
                                allow_personal_nodered: Config_1.Config.allow_personal_nodered,
                                auto_create_personal_nodered_group: Config_1.Config.auto_create_personal_nodered_group,
                                namespace: Config_1.Config.namespace,
                                nodered_domain_schema: Config_1.Config.nodered_domain_schema,
                                websocket_package_size: Config_1.Config.websocket_package_size,
                                version: Config_1.Config.version,
                                stripe_api_key: Config_1.Config.stripe_api_key,
                                getting_started_url: Config_1.Config.getting_started_url,
                                validate_user_form: Config_1.Config.validate_user_form
                            };
                            res.end(JSON.stringify(res2));
                        });
                        app.get("/login", function (req, res, next) { return __awaiter(_this, void 0, void 0, function () {
                            var originalUrl, validateurl, user, tuser, file, error_3;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        _a.trys.push([0, 3, , 4]);
                                        originalUrl = req.cookies.originalUrl;
                                        validateurl = req.cookies.validateurl;
                                        if (openflow_api_1.NoderedUtil.IsNullEmpty(originalUrl))
                                            res.cookie("originalUrl", req.originalUrl, { maxAge: 900000, httpOnly: true });
                                        if (!!openflow_api_1.NoderedUtil.IsNullEmpty(validateurl)) return [3 /*break*/, 2];
                                        if (!req.user) return [3 /*break*/, 2];
                                        return [4 /*yield*/, DBHelper_1.DBHelper.FindById(req.user._id)];
                                    case 1:
                                        user = _a.sent();
                                        tuser = openflow_api_1.TokenUser.From(user);
                                        req.session.passport.user.validated = tuser.validated;
                                        if (!(tuser.validated == true) && Config_1.Config.validate_user_form != "") {
                                        }
                                        else {
                                            res.cookie("validateurl", "", { expires: new Date(0) });
                                            res.cookie("originalUrl", "", { expires: new Date(0) });
                                            this.redirect(res, "/#" + validateurl);
                                            return [2 /*return*/];
                                        }
                                        _a.label = 2;
                                    case 2:
                                        file = path.join(__dirname, 'public', 'PassiveLogin.html');
                                        res.sendFile(file);
                                        return [3 /*break*/, 4];
                                    case 3:
                                        error_3 = _a.sent();
                                        console.error(error_3.message ? error_3.message : error_3);
                                        return [2 /*return*/, res.status(500).send({ message: error_3.message ? error_3.message : error_3 })];
                                    case 4:
                                        try {
                                            LoginProvider.RegisterProviders(app, baseurl);
                                        }
                                        catch (error) {
                                        }
                                        return [2 /*return*/];
                                }
                            });
                        }); });
                        app.get("/validateuserform", function (req, res, next) { return __awaiter(_this, void 0, void 0, function () {
                            var forms;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        // console.log("/validateuserform " + !(req.user == null));
                                        res.setHeader("Content-Type", "application/json");
                                        if (openflow_api_1.NoderedUtil.IsNullEmpty(Config_1.Config.validate_user_form)) {
                                            res.end(JSON.stringify({}));
                                            res.end();
                                            return [2 /*return*/];
                                        }
                                        return [4 /*yield*/, Config_1.Config.db.query({ _id: Config_1.Config.validate_user_form, _type: "form" }, null, 1, 0, null, "forms", Crypt_1.Crypt.rootToken())];
                                    case 1:
                                        forms = _a.sent();
                                        if (forms.length == 1) {
                                            res.end(JSON.stringify(forms[0]));
                                            res.end();
                                            return [2 /*return*/];
                                        }
                                        LoginProvider._logger.error("validate_user_form " + Config_1.Config.validate_user_form + " does not exists!");
                                        Config_1.Config.validate_user_form = "";
                                        res.end(JSON.stringify({}));
                                        res.end();
                                        return [2 /*return*/];
                                }
                            });
                        }); });
                        app.post("/validateuserform", function (req, res) { return __awaiter(_this, void 0, void 0, function () {
                            var tuser, UpdateDoc_1, keys, res2, user, error_4;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        // console.log("/validateuserform " + !(req.user == null));
                                        res.setHeader("Content-Type", "application/json");
                                        _a.label = 1;
                                    case 1:
                                        _a.trys.push([1, 6, , 7]);
                                        if (!req.user) return [3 /*break*/, 4];
                                        if (!(req.body && req.body.data)) return [3 /*break*/, 3];
                                        tuser = openflow_api_1.TokenUser.From(req.user);
                                        delete req.body.data._id;
                                        delete req.body.data.username;
                                        delete req.body.data.disabled;
                                        delete req.body.data.type;
                                        delete req.body.data.roles;
                                        delete req.body.data.submit;
                                        req.body.data.validated = true;
                                        delete req.body.data.federationids;
                                        delete req.body.data.nodered;
                                        delete req.body.data.billing;
                                        delete req.body.data.clientagent;
                                        delete req.body.data.clientversion;
                                        UpdateDoc_1 = { "$set": {} };
                                        keys = Object.keys(req.body.data);
                                        keys.forEach(function (key) {
                                            if (key.startsWith("_")) {
                                            }
                                            else if (key.indexOf("$") > -1) {
                                            }
                                            else {
                                                UpdateDoc_1.$set[key] = req.body.data[key];
                                            }
                                        });
                                        return [4 /*yield*/, Config_1.Config.db._UpdateOne({ "_id": tuser._id }, UpdateDoc_1, "users", 1, false, Crypt_1.Crypt.rootToken())];
                                    case 2:
                                        res2 = _a.sent();
                                        user = Object.assign(tuser, req.body.data);
                                        req.session.passport.user.validated = true;
                                        if (!(user.validated == true) && Config_1.Config.validate_user_form != "") {
                                            res.end(JSON.stringify({ jwt: "" }));
                                        }
                                        else {
                                            res.end(JSON.stringify({ jwt: Crypt_1.Crypt.createToken(user, Config_1.Config.longtoken_expires_in), user: user }));
                                        }
                                        _a.label = 3;
                                    case 3: return [3 /*break*/, 5];
                                    case 4:
                                        res.end(JSON.stringify({ jwt: "" }));
                                        _a.label = 5;
                                    case 5: return [3 /*break*/, 7];
                                    case 6:
                                        error_4 = _a.sent();
                                        console.error(error_4);
                                        return [2 /*return*/, res.status(500).send({ message: error_4.message ? error_4.message : error_4 })];
                                    case 7:
                                        res.end();
                                        return [2 /*return*/];
                                }
                            });
                        }); });
                        app.get("/loginproviders", function (req, res, next) { return __awaiter(_this, void 0, void 0, function () {
                            var result, error_5;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        _a.trys.push([0, 2, , 3]);
                                        return [4 /*yield*/, this.getProviders()];
                                    case 1:
                                        result = _a.sent();
                                        res.setHeader("Content-Type", "application/json");
                                        res.end(JSON.stringify(result));
                                        res.end();
                                        return [3 /*break*/, 3];
                                    case 2:
                                        error_5 = _a.sent();
                                        console.error(error_5.message ? error_5.message : error_5);
                                        return [2 /*return*/, res.status(500).send({ message: error_5.message ? error_5.message : error_5 })];
                                    case 3:
                                        try {
                                            LoginProvider.RegisterProviders(app, baseurl);
                                        }
                                        catch (error) {
                                        }
                                        return [2 /*return*/];
                                }
                            });
                        }); });
                        app.get("/download/:id", function (req, res) { return __awaiter(_this, void 0, void 0, function () {
                            var user, jwt, authHeader, id, rows, file, bucket, downloadStream, error_6;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        _a.trys.push([0, 2, , 3]);
                                        user = null;
                                        jwt = null;
                                        authHeader = req.headers.authorization;
                                        if (authHeader) {
                                            user = Crypt_1.Crypt.verityToken(authHeader);
                                            jwt = Crypt_1.Crypt.createToken(user, Config_1.Config.downloadtoken_expires_in);
                                        }
                                        else if (req.user) {
                                            user = openflow_api_1.TokenUser.From(req.user);
                                            jwt = Crypt_1.Crypt.createToken(user, Config_1.Config.downloadtoken_expires_in);
                                        }
                                        if (user == null) {
                                            return [2 /*return*/, res.status(404).send({ message: 'Route ' + req.url + ' Not found.' })];
                                        }
                                        id = req.params.id;
                                        return [4 /*yield*/, Config_1.Config.db.query({ _id: safeObjectID(id) }, null, 1, 0, null, "files", jwt)];
                                    case 1:
                                        rows = _a.sent();
                                        if (rows == null || rows.length != 1) {
                                            return [2 /*return*/, res.status(404).send({ message: 'id ' + id + ' Not found.' })];
                                        }
                                        file = rows[0];
                                        bucket = new mongodb_1.GridFSBucket(Config_1.Config.db.db);
                                        downloadStream = bucket.openDownloadStream(safeObjectID(id));
                                        res.set('Content-Type', file.contentType);
                                        res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
                                        res.set('Content-Length', file.length);
                                        downloadStream.on("error", function (err) {
                                            res.end();
                                        });
                                        downloadStream.pipe(res);
                                        return [3 /*break*/, 3];
                                    case 2:
                                        error_6 = _a.sent();
                                        return [2 /*return*/, res.status(500).send({ message: error_6.message ? error_6.message : error_6 })];
                                    case 3: return [2 /*return*/];
                                }
                            });
                        }); });
                        try {
                            storage = GridFsStorage({
                                db: Config_1.Config.db,
                                file: function (req, file) {
                                    return new Promise(function (resolve, reject) {
                                        crypto.randomBytes(16, function (err, buf) {
                                            if (err) {
                                                return reject(err);
                                            }
                                            // const filename = buf.toString('hex') + path.extname(file.originalname);
                                            var filename = file.originalname;
                                            var fileInfo = {
                                                filename: filename,
                                                metadata: new openflow_api_1.Base()
                                            };
                                            var user = null;
                                            var jwt = null;
                                            var authHeader = req.headers.authorization;
                                            if (authHeader) {
                                                user = Crypt_1.Crypt.verityToken(authHeader);
                                                jwt = Crypt_1.Crypt.createToken(user, Config_1.Config.downloadtoken_expires_in);
                                            }
                                            else if (req.user) {
                                                user = openflow_api_1.TokenUser.From(req.user);
                                                jwt = Crypt_1.Crypt.createToken(user, Config_1.Config.downloadtoken_expires_in);
                                            }
                                            fileInfo.metadata.name = file.originalname;
                                            fileInfo.metadata.filename = file.originalname;
                                            fileInfo.metadata.path = "";
                                            fileInfo.metadata._acl = [];
                                            fileInfo.metadata._createdby = user.name;
                                            fileInfo.metadata._createdbyid = user._id;
                                            fileInfo.metadata._created = new Date(new Date().toISOString());
                                            fileInfo.metadata._modifiedby = user.name;
                                            fileInfo.metadata._modifiedbyid = user._id;
                                            fileInfo.metadata._modified = fileInfo.metadata._created;
                                            openflow_api_1.Base.addRight(fileInfo.metadata, user._id, user.name, [openflow_api_1.Rights.full_control]);
                                            openflow_api_1.Base.addRight(fileInfo.metadata, openflow_api_1.WellknownIds.filestore_admins, "filestore admins", [openflow_api_1.Rights.full_control]);
                                            openflow_api_1.Base.addRight(fileInfo.metadata, openflow_api_1.WellknownIds.filestore_users, "filestore users", [openflow_api_1.Rights.read]);
                                            // Fix acl
                                            fileInfo.metadata._acl.forEach(function (a, index) {
                                                if (typeof a.rights === "string") {
                                                    fileInfo.metadata._acl[index].rights = new mongodb_1.Binary(Buffer.from(a.rights, "base64"), 0);
                                                }
                                            });
                                            resolve(fileInfo);
                                        });
                                    });
                                },
                            });
                            upload_1 = multer({
                                storage: storage
                            }).any();
                            app.post("/upload", function (req, res) { return __awaiter(_this, void 0, void 0, function () {
                                var user, jwt, authHeader;
                                return __generator(this, function (_a) {
                                    user = null;
                                    jwt = null;
                                    authHeader = req.headers.authorization;
                                    if (authHeader) {
                                        user = Crypt_1.Crypt.verityToken(authHeader);
                                        jwt = Crypt_1.Crypt.createToken(user, Config_1.Config.downloadtoken_expires_in);
                                    }
                                    else if (req.user) {
                                        user = openflow_api_1.TokenUser.From(req.user);
                                        jwt = Crypt_1.Crypt.createToken(user, Config_1.Config.downloadtoken_expires_in);
                                    }
                                    if (user == null) {
                                        return [2 /*return*/, res.status(404).send({ message: 'Route ' + req.url + ' Not found.' })];
                                    }
                                    upload_1(req, res, function (err) {
                                        if (err) {
                                            res.json({ error_code: 1, err_desc: err });
                                            return;
                                        }
                                        LoginProvider.redirect(res, req.headers.referer);
                                        // res.json({ error_code: 0, err_desc: null });
                                    });
                                    return [2 /*return*/];
                                });
                            }); });
                        }
                        catch (error) {
                            console.error(error.message ? error.message : error);
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    LoginProvider.RegisterProviders = function (app, baseurl) {
        return __awaiter(this, void 0, void 0, function () {
            var _jwt, _a, hasLocal;
            var _this = this;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!(LoginProvider.login_providers.length === 0)) return [3 /*break*/, 2];
                        _jwt = Crypt_1.Crypt.rootToken();
                        _a = LoginProvider;
                        return [4 /*yield*/, Config_1.Config.db.query({ _type: "provider" }, null, 10, 0, null, "config", _jwt)];
                    case 1:
                        _a.login_providers = _b.sent();
                        _b.label = 2;
                    case 2:
                        hasLocal = false;
                        if (LoginProvider.login_providers.length === 0) {
                            hasLocal = true;
                        }
                        LoginProvider.login_providers.forEach(function (provider) { return __awaiter(_this, void 0, void 0, function () {
                            var metadata, error_7;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        _a.trys.push([0, 4, , 5]);
                                        if (!openflow_api_1.NoderedUtil.IsNullUndefinded(LoginProvider._providers[provider.id])) return [3 /*break*/, 3];
                                        if (!(provider.provider === "saml")) return [3 /*break*/, 2];
                                        return [4 /*yield*/, Config_1.Config.parse_federation_metadata(provider.saml_federation_metadata)];
                                    case 1:
                                        metadata = _a.sent();
                                        LoginProvider._providers[provider.id] =
                                            LoginProvider.CreateSAMLStrategy(app, provider.id, metadata.cert, metadata.identityProviderUrl, provider.issuer, baseurl);
                                        _a.label = 2;
                                    case 2:
                                        if (provider.provider === "google") {
                                            LoginProvider._providers[provider.id] =
                                                LoginProvider.CreateGoogleStrategy(app, provider.id, provider.consumerKey, provider.consumerSecret, baseurl);
                                        }
                                        _a.label = 3;
                                    case 3:
                                        if (provider.provider === "local") {
                                            hasLocal = true;
                                        }
                                        return [3 /*break*/, 5];
                                    case 4:
                                        error_7 = _a.sent();
                                        console.error(error_7.message ? error_7.message : error_7);
                                        return [3 /*break*/, 5];
                                    case 5: return [2 /*return*/];
                                }
                            });
                        }); });
                        if (hasLocal === true) {
                            if (openflow_api_1.NoderedUtil.IsNullUndefinded(LoginProvider._providers.local)) {
                                LoginProvider._providers.local = LoginProvider.CreateLocalStrategy(app, baseurl);
                            }
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    LoginProvider.CreateGoogleStrategy = function (app, key, consumerKey, consumerSecret, baseurl) {
        var options = new googleauthstrategyoptions();
        options.clientID = consumerKey;
        options.clientSecret = consumerSecret;
        options.callbackURL = url.parse(baseurl).protocol + "//" + url.parse(baseurl).host + "/" + key + "/";
        options.verify = (LoginProvider.googleverify).bind(this);
        var strategy = new GoogleStrategy.Strategy(options, options.verify);
        passport.use(key, strategy);
        strategy.name = key;
        LoginProvider._logger.info(options.callbackURL);
        app.use("/" + key, bodyParser.urlencoded({ extended: false }), passport.authenticate(key, { failureRedirect: "/" + key, failureFlash: true }), function (req, res) {
            var originalUrl = req.cookies.originalUrl;
            res.cookie("provider", key, { maxAge: 900000, httpOnly: true });
            if (!openflow_api_1.NoderedUtil.IsNullEmpty(originalUrl)) {
                res.cookie("originalUrl", "", { expires: new Date(0) });
                LoginProvider.redirect(res, originalUrl);
            }
            else {
                res.redirect("/");
            }
        });
        return strategy;
    };
    // tslint:disable-next-line: max-line-length
    LoginProvider.CreateSAMLStrategy = function (app, key, cert, singin_url, issuer, baseurl) {
        var options = new samlauthstrategyoptions();
        options.entryPoint = singin_url;
        options.cert = cert;
        options.issuer = issuer;
        options.callbackUrl = url.parse(baseurl).protocol + "//" + url.parse(baseurl).host + "/" + key + "/";
        options.verify = (LoginProvider.samlverify).bind(this);
        var SamlStrategy = require('passport-saml').Strategy;
        var strategy = new SamlStrategy(options, options.verify);
        passport.use(key, strategy);
        strategy.name = key;
        LoginProvider._logger.info(options.callbackUrl);
        // app.get("/" + key + "/FederationMetadata/2007-06/FederationMetadata.xml",
        //     wsfed.metadata({
        //         cert: Buffer.from(Config.signing_crt, "base64").toString("ascii"),
        //         issuer: issuer
        //     }));
        var CertPEM = Buffer.from(Config_1.Config.signing_crt, "base64").toString("ascii").replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, '');
        app.get("/" + key + "/FederationMetadata/2007-06/FederationMetadata.xml", function (req, res, next) {
            res.set("Content-Type", "text/xml");
            res.send("\n            <EntityDescriptor xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"" + issuer + "\">\n            <RoleDescriptor xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:fed=\"http://docs.oasis-open.org/wsfed/federation/200706\" xsi:type=\"fed:SecurityTokenServiceType\" protocolSupportEnumeration=\"http://docs.oasis-open.org/wsfed/federation/200706\" \n            ServiceDisplayName=\"" + issuer + "\">\n            <KeyDescriptor use=\"signing\">\n            <KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\">\n            <X509Data>\n            <X509Certificate>" + CertPEM + "</X509Certificate>\n            </X509Data>\n            </KeyInfo>\n            </KeyDescriptor>\n            <fed:TokenTypesOffered>\n            <fed:TokenType Uri=\"urn:oasis:names:tc:SAML:2.0:assertion\"/>\n            <fed:TokenType Uri=\"urn:oasis:names:tc:SAML:1.0:assertion\"/>\n            </fed:TokenTypesOffered>\n            <fed:ClaimTypesOffered>\n            <auth:ClaimType xmlns:auth=\"http://docs.oasis-open.org/wsfed/authorization/200706\" Uri=\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress\" Optional=\"true\">\n            <auth:DisplayName>E-Mail Address</auth:DisplayName>\n            <auth:Description>The e-mail address of the user</auth:Description>\n            </auth:ClaimType>\n            <auth:ClaimType xmlns:auth=\"http://docs.oasis-open.org/wsfed/authorization/200706\" Uri=\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname\" Optional=\"true\">\n            <auth:DisplayName>Given Name</auth:DisplayName>\n            <auth:Description>The given name of the user</auth:Description>\n            </auth:ClaimType>\n            <auth:ClaimType xmlns:auth=\"http://docs.oasis-open.org/wsfed/authorization/200706\" Uri=\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name\" Optional=\"true\">\n            <auth:DisplayName>Name</auth:DisplayName>\n            <auth:Description>The unique name of the user</auth:Description>\n            </auth:ClaimType>\n            <auth:ClaimType xmlns:auth=\"http://docs.oasis-open.org/wsfed/authorization/200706\" Uri=\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname\" Optional=\"true\">\n            <auth:DisplayName>Surname</auth:DisplayName>\n            <auth:Description>The surname of the user</auth:Description>\n            </auth:ClaimType>\n            <auth:ClaimType xmlns:auth=\"http://docs.oasis-open.org/wsfed/authorization/200706\" Uri=\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier\" Optional=\"true\">\n            <auth:DisplayName>Name ID</auth:DisplayName>\n            <auth:Description>The SAML name identifier of the user</auth:Description>\n            </auth:ClaimType>\n            </fed:ClaimTypesOffered>originalUrl\n            <fed:PassiveRequestorEndpoint>\n            <EndpointReference xmlns=\"http://www.w3.org/2005/08/addressing\">\n            <Address>" + options.callbackUrl + "</Address>\n            </EndpointReference>\n            </fed:PassiveRequestorEndpoint>\n            </RoleDescriptor>\n            </EntityDescriptor>\n            ");
        });
        app.use("/" + key, bodyParser.urlencoded({ extended: false }), passport.authenticate(key, { failureRedirect: "/" + key, failureFlash: true }), function (req, res) {
            var originalUrl = req.cookies.originalUrl;
            res.cookie("provider", key, { maxAge: 900000, httpOnly: true });
            if (!openflow_api_1.NoderedUtil.IsNullEmpty(originalUrl)) {
                res.cookie("originalUrl", "", { expires: new Date(0) });
                LoginProvider.redirect(res, originalUrl);
            }
            else {
                res.redirect("/");
            }
        });
        return strategy;
    };
    LoginProvider.CreateLocalStrategy = function (app, baseurl) {
        var _this = this;
        var strategy = new LocalStrategy(function (username, password, done) { return __awaiter(_this, void 0, void 0, function () {
            var user, admins, provider, result, tuser_1, tuser, error_8;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _a.trys.push([0, 16, , 17]);
                        if (username !== null && username != undefined) {
                            username = username.toLowerCase();
                        }
                        user = null;
                        if (!(LoginProvider.login_providers.length === 0)) return [3 /*break*/, 10];
                        return [4 /*yield*/, DBHelper_1.DBHelper.FindByUsername(username)];
                    case 1:
                        user = _a.sent();
                        if (!(user == null)) return [3 /*break*/, 6];
                        user = new openflow_api_1.User();
                        user.name = username;
                        user.username = username;
                        return [4 /*yield*/, Crypt_1.Crypt.SetPassword(user, password)];
                    case 2:
                        _a.sent();
                        return [4 /*yield*/, Config_1.Config.db.InsertOne(user, "users", 0, false, Crypt_1.Crypt.rootToken())];
                    case 3:
                        user = _a.sent();
                        return [4 /*yield*/, DBHelper_1.DBHelper.FindRoleByName("admins")];
                    case 4:
                        admins = _a.sent();
                        admins.AddMember(user);
                        return [4 /*yield*/, DBHelper_1.DBHelper.Save(admins, Crypt_1.Crypt.rootToken())];
                    case 5:
                        _a.sent();
                        return [3 /*break*/, 8];
                    case 6:
                        if (user.disabled) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "local", "", "browser", "unknown");
                            done("Disabled user " + username, null);
                            return [2 /*return*/];
                        }
                        return [4 /*yield*/, Crypt_1.Crypt.ValidatePassword(user, password)];
                    case 7:
                        if (!(_a.sent())) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "local", "", "browser", "unknown");
                            return [2 /*return*/, done(null, false)];
                        }
                        _a.label = 8;
                    case 8:
                        Audit_1.Audit.LoginSuccess(openflow_api_1.TokenUser.From(user), "weblogin", "local", "", "browser", "unknown");
                        provider = new Provider();
                        provider.provider = "local";
                        provider.name = "Local";
                        return [4 /*yield*/, Config_1.Config.db.InsertOne(provider, "config", 0, false, Crypt_1.Crypt.rootToken())];
                    case 9:
                        result = _a.sent();
                        LoginProvider.login_providers.push(result);
                        tuser_1 = openflow_api_1.TokenUser.From(user);
                        return [2 /*return*/, done(null, tuser_1)];
                    case 10: return [4 /*yield*/, DBHelper_1.DBHelper.FindByUsername(username)];
                    case 11:
                        user = _a.sent();
                        if (!openflow_api_1.NoderedUtil.IsNullUndefinded(user)) return [3 /*break*/, 13];
                        if (!Config_1.Config.allow_user_registration) {
                            return [2 /*return*/, done(null, false)];
                        }
                        return [4 /*yield*/, DBHelper_1.DBHelper.ensureUser(Crypt_1.Crypt.rootToken(), username, username, null, password)];
                    case 12:
                        user = _a.sent();
                        return [3 /*break*/, 15];
                    case 13:
                        if (user.disabled) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "local", "", "browser", "unknown");
                            done("Disabled user " + username, null);
                            return [2 /*return*/];
                        }
                        return [4 /*yield*/, Crypt_1.Crypt.ValidatePassword(user, password)];
                    case 14:
                        if (!(_a.sent())) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "local", "", "browser", "unknown");
                            return [2 /*return*/, done(null, false)];
                        }
                        _a.label = 15;
                    case 15:
                        tuser = openflow_api_1.TokenUser.From(user);
                        Audit_1.Audit.LoginSuccess(tuser, "weblogin", "local", "", "browser", "unknown");
                        return [2 /*return*/, done(null, tuser)];
                    case 16:
                        error_8 = _a.sent();
                        console.error(error_8.message ? error_8.message : error_8);
                        done(error_8.message ? error_8.message : error_8);
                        return [3 /*break*/, 17];
                    case 17: return [2 /*return*/];
                }
            });
        }); });
        passport.use("local", strategy);
        app.use("/local", bodyParser.urlencoded({ extended: false }), function (req, res, next) {
            LoginProvider._logger.debug("passport.authenticate local");
            passport.authenticate("local", function (err, user, info) {
                var originalUrl = req.cookies.originalUrl;
                LoginProvider._logger.debug("originalUrl: " + originalUrl);
                if (err) {
                    LoginProvider._logger.error(err);
                }
                if (!err && user) {
                    LoginProvider._logger.info(user);
                    req.logIn(user, function (err) {
                        if (err) {
                            LoginProvider._logger.info("req.logIn failed");
                            LoginProvider._logger.error(err);
                            return next(err);
                        }
                        LoginProvider._logger.info("req.logIn success");
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(originalUrl)) {
                            try {
                                res.cookie("originalUrl", "", { expires: new Date(0) });
                                LoginProvider.redirect(res, originalUrl);
                                LoginProvider._logger.debug("redirect: " + originalUrl);
                                return;
                            }
                            catch (error) {
                                console.error(error.message ? error.message : error);
                            }
                        }
                        else {
                            LoginProvider._logger.debug("redirect: to /");
                            res.redirect("/");
                            return next();
                        }
                    });
                    return;
                }
                if (!openflow_api_1.NoderedUtil.IsNullEmpty(originalUrl)) {
                    if (originalUrl.indexOf("?") == -1) {
                        originalUrl = originalUrl + "?error=1";
                    }
                    else if (originalUrl.indexOf("error=1") == -1) {
                        originalUrl = originalUrl + "&error=1";
                    }
                    try {
                        LoginProvider._logger.debug("remove originalUrl");
                        res.cookie("originalUrl", "", { expires: new Date(0) });
                        LoginProvider._logger.debug("redirect: " + originalUrl);
                        LoginProvider.redirect(res, originalUrl);
                    }
                    catch (error) {
                        console.error(error.message ? error.message : error);
                    }
                }
                else {
                    try {
                        LoginProvider._logger.debug("redirect: to /");
                        res.redirect("/");
                        return next();
                    }
                    catch (error) {
                        console.error(error.message ? error.message : error);
                    }
                }
            })(req, res, next);
        });
        return strategy;
    };
    LoginProvider.samlverify = function (profile, done) {
        return __awaiter(this, void 0, void 0, function () {
            var username, _user, createUser, jwt, jwt, jwt, strroles, i, role, tuser;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        username = profile.username;
                        if (openflow_api_1.NoderedUtil.IsNullEmpty(username))
                            username = profile.nameID;
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(username)) {
                            username = username.toLowerCase();
                        }
                        LoginProvider._logger.debug("verify: " + username);
                        return [4 /*yield*/, DBHelper_1.DBHelper.FindByUsernameOrFederationid(username)];
                    case 1:
                        _user = _a.sent();
                        if (!openflow_api_1.NoderedUtil.IsNullUndefinded(_user)) return [3 /*break*/, 4];
                        createUser = Config_1.Config.auto_create_users;
                        if (Config_1.Config.auto_create_domains.map(function (x) { return username.endsWith(x); }).length == -1) {
                            createUser = false;
                        }
                        if (!createUser) return [3 /*break*/, 3];
                        _user = new openflow_api_1.User();
                        _user.name = profile.name;
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(profile["http://schemas.microsoft.com/identity/claims/displayname"])) {
                            _user.name = profile["http://schemas.microsoft.com/identity/claims/displayname"];
                        }
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(profile["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"])) {
                            _user.name = profile["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"];
                        }
                        _user.username = username;
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(profile["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobile"])) {
                            _user.mobile = profile["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobile"];
                        }
                        if (openflow_api_1.NoderedUtil.IsNullEmpty(_user.name)) {
                            done("Cannot add new user, name is empty, please add displayname to claims", null);
                            return [2 /*return*/];
                        }
                        jwt = Crypt_1.Crypt.rootToken();
                        return [4 /*yield*/, DBHelper_1.DBHelper.ensureUser(jwt, _user.name, _user.username, null, null)];
                    case 2:
                        _user = _a.sent();
                        _a.label = 3;
                    case 3: return [3 /*break*/, 6];
                    case 4:
                        if (!!openflow_api_1.NoderedUtil.IsNullUndefinded(_user)) return [3 /*break*/, 6];
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(profile["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobile"])) {
                            _user.mobile = profile["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobile"];
                        }
                        jwt = Crypt_1.Crypt.rootToken();
                        return [4 /*yield*/, DBHelper_1.DBHelper.Save(_user, jwt)];
                    case 5:
                        _a.sent();
                        _a.label = 6;
                    case 6:
                        if (!!openflow_api_1.NoderedUtil.IsNullUndefinded(_user)) return [3 /*break*/, 13];
                        if (!!openflow_api_1.NoderedUtil.IsNullEmpty(profile["http://schemas.xmlsoap.org/claims/Group"])) return [3 /*break*/, 13];
                        jwt = Crypt_1.Crypt.rootToken();
                        strroles = profile["http://schemas.xmlsoap.org/claims/Group"];
                        i = 0;
                        _a.label = 7;
                    case 7:
                        if (!(i < strroles.length)) return [3 /*break*/, 11];
                        return [4 /*yield*/, DBHelper_1.DBHelper.FindRoleByName(strroles[i])];
                    case 8:
                        role = _a.sent();
                        if (!!openflow_api_1.NoderedUtil.IsNullUndefinded(role)) return [3 /*break*/, 10];
                        role.AddMember(_user);
                        return [4 /*yield*/, DBHelper_1.DBHelper.Save(role, jwt)];
                    case 9:
                        _a.sent();
                        _a.label = 10;
                    case 10:
                        i++;
                        return [3 /*break*/, 7];
                    case 11: return [4 /*yield*/, DBHelper_1.DBHelper.DecorateWithRoles(_user)];
                    case 12:
                        _a.sent();
                        _a.label = 13;
                    case 13:
                        if (openflow_api_1.NoderedUtil.IsNullUndefinded(_user)) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "saml", "", "samlverify", "unknown");
                            done("unknown user " + username, null);
                            return [2 /*return*/];
                        }
                        if (_user.disabled) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "saml", "", "samlverify", "unknown");
                            done("Disabled user " + username, null);
                            return [2 /*return*/];
                        }
                        tuser = openflow_api_1.TokenUser.From(_user);
                        Audit_1.Audit.LoginSuccess(tuser, "weblogin", "saml", "", "samlverify", "unknown");
                        done(null, tuser);
                        return [2 /*return*/];
                }
            });
        });
    };
    LoginProvider.googleverify = function (token, tokenSecret, profile, done) {
        return __awaiter(this, void 0, void 0, function () {
            var email, username, _user, createUser, jwt, tuser;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (profile.emails) {
                            email = profile.emails[0];
                            profile.username = email.value;
                        }
                        username = profile.username;
                        if (openflow_api_1.NoderedUtil.IsNullEmpty(username))
                            username = profile.nameID;
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(username)) {
                            username = username.toLowerCase();
                        }
                        LoginProvider._logger.debug("verify: " + username);
                        return [4 /*yield*/, DBHelper_1.DBHelper.FindByUsernameOrFederationid(username)];
                    case 1:
                        _user = _a.sent();
                        if (!openflow_api_1.NoderedUtil.IsNullUndefinded(_user)) return [3 /*break*/, 3];
                        createUser = Config_1.Config.auto_create_users;
                        if (Config_1.Config.auto_create_domains.map(function (x) { return username.endsWith(x); }).length == -1) {
                            createUser = false;
                        }
                        if (!createUser) return [3 /*break*/, 3];
                        jwt = Crypt_1.Crypt.rootToken();
                        _user = new openflow_api_1.User();
                        _user.name = profile.name;
                        if (!openflow_api_1.NoderedUtil.IsNullEmpty(profile.displayName)) {
                            _user.name = profile.displayName;
                        }
                        _user.username = username;
                        _user.mobile = profile.mobile;
                        if (openflow_api_1.NoderedUtil.IsNullEmpty(_user.name)) {
                            done("Cannot add new user, name is empty.", null);
                            return [2 /*return*/];
                        }
                        return [4 /*yield*/, DBHelper_1.DBHelper.ensureUser(jwt, _user.name, _user.username, null, null)];
                    case 2:
                        _user = _a.sent();
                        _a.label = 3;
                    case 3:
                        if (openflow_api_1.NoderedUtil.IsNullUndefinded(_user)) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "google", "", "googleverify", "unknown");
                            done("unknown user " + username, null);
                            return [2 /*return*/];
                        }
                        if (_user.disabled) {
                            Audit_1.Audit.LoginFailed(username, "weblogin", "google", "", "googleverify", "unknown");
                            done("Disabled user " + username, null);
                            return [2 /*return*/];
                        }
                        tuser = openflow_api_1.TokenUser.From(_user);
                        Audit_1.Audit.LoginSuccess(tuser, "weblogin", "google", "", "googleverify", "unknown");
                        done(null, tuser);
                        return [2 /*return*/];
                }
            });
        });
    };
    LoginProvider._providers = {};
    LoginProvider.login_providers = [];
    return LoginProvider;
}());
exports.LoginProvider = LoginProvider;
//# sourceMappingURL=LoginProvider.js.map