"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useRequiredSSO = exports.RequiredSSO = exports.StrategyAvatar = exports.getLink = void 0;
var jsx_runtime_1 = require("react/jsx-runtime");
/*
 *  This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
var icon_1 = require("@cocalc/frontend/components/icon");
var check_required_sso_1 = require("@cocalc/server/auth/sso/check-required-sso");
var passport_types_1 = require("@cocalc/util/types/passport-types");
var antd_1 = require("antd");
var loading_1 = __importDefault(require("components/share/loading"));
var base_path_1 = __importDefault(require("lib/base-path"));
var customize_1 = require("lib/customize");
var router_1 = require("next/router");
var path_1 = require("path");
var react_1 = require("react");
var AntdLink = antd_1.Typography.Link;
var sso_module_css_1 = __importDefault(require("./sso.module.css"));
function getLink(strategy, target) {
    // special case: private SSO mechanism, we point to the overview page
    if (strategy === "sso") {
        return "".concat((0, path_1.join)(base_path_1.default, "sso"));
    }
    // TODO: the target is ignored by the server right now -- it's not implemented
    // and I don't know how... yet.  Code is currently in src/packages/hub/auth.ts
    return "".concat((0, path_1.join)(base_path_1.default, "auth", strategy)).concat(target ? "?target=" + encodeURIComponent(target) : "");
}
exports.getLink = getLink;
function SSO(props) {
    var size = props.size, style = props.style, header = props.header;
    var strategies = (0, customize_1.useCustomize)().strategies;
    var havePrivateSSO = (0, react_1.useMemo)(function () {
        var _a;
        return (_a = strategies === null || strategies === void 0 ? void 0 : strategies.some(function (s) { return !s.public; })) !== null && _a !== void 0 ? _a : false;
    }, [strategies]);
    if (strategies == null) {
        return (0, jsx_runtime_1.jsx)(loading_1.default, { style: { fontSize: "16pt" } });
    }
    if (strategies.length == 0)
        return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
    function renderPrivateSSO() {
        if (!havePrivateSSO)
            return;
        // a fake entry to point the user to the page for private SSO login options
        var sso = {
            name: "sso",
            display: "institutional Single-Sign-On",
            icon: "api",
            backgroundColor: "",
            public: true,
            exclusiveDomains: [],
            doNotHide: true,
        };
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Institutional Single-Sign-On: ", (0, jsx_runtime_1.jsx)(StrategyAvatar, { strategy: sso, size: size !== null && size !== void 0 ? size : 60 }, "sso")] }));
    }
    function renderStrategies() {
        if (strategies == null)
            return;
        return strategies
            .filter(function (s) { return s.public || s.doNotHide; })
            .map(function (strategy) { return ((0, jsx_runtime_1.jsx)(StrategyAvatar, { strategy: strategy, size: size !== null && size !== void 0 ? size : 60 }, strategy.name)); });
    }
    // The -5px is to offset the initial avatar image, since they
    // all have a left margin.
    return ((0, jsx_runtime_1.jsxs)("div", __assign({ style: __assign({}, style) }, { children: [header, (0, jsx_runtime_1.jsx)("div", __assign({ style: { marginLeft: "-5px" } }, { children: renderStrategies() })), (0, jsx_runtime_1.jsx)("div", __assign({ style: { marginLeft: "-5px", marginTop: "10px" } }, { children: renderPrivateSSO() }))] })));
}
exports.default = SSO;
function useSSOHref(name) {
    var router = (0, router_1.useRouter)();
    if (name == null)
        return "";
    return getLink(name, (0, path_1.join)(router.basePath, router.pathname));
}
function StrategyAvatar(props) {
    var strategy = props.strategy, size = props.size, noLink = props.noLink, toolTip = props.toolTip, _a = props.showName, showName = _a === void 0 ? false : _a;
    var name = strategy.name, display = strategy.display, backgroundColor = strategy.backgroundColor;
    var icon = iconName();
    var ssoHREF = useSSOHref(name);
    var STYLE = {
        fontSize: "".concat(size - 2, "px"),
        color: backgroundColor ? "white" : "black",
        margin: "0 2px",
    };
    // this derives the name of the icon, that's shown on the avatar
    // in particular, the old public SSO mechanisms are special cases.
    function iconName() {
        // icon could be "null"
        if (strategy.icon != null)
            return strategy.icon;
        if (passport_types_1.PRIMARY_SSO.includes(strategy.name)) {
            return strategy.name;
        }
        return "link"; // a chain link, very general fallback
    }
    function renderIconImg() {
        if (icon === null || icon === void 0 ? void 0 : icon.includes("://")) {
            return ((0, jsx_runtime_1.jsx)("img", { src: icon, style: {
                    height: "".concat(size - 2, "px"),
                    width: "".concat(size - 2, "px"),
                    marginLeft: "2.5px",
                    objectFit: "contain",
                } }));
        }
        else {
            return (0, jsx_runtime_1.jsx)(icon_1.Icon, { name: icon, style: __assign(__assign({}, STYLE), { backgroundColor: backgroundColor }) });
        }
    }
    function renderAvatar() {
        var avatar = ((0, jsx_runtime_1.jsx)(antd_1.Avatar, { shape: "square", size: size, src: renderIconImg(), gap: 1, className: sso_module_css_1.default.icon }));
        if (noLink) {
            return avatar;
        }
        else {
            return (0, jsx_runtime_1.jsx)("a", __assign({ href: ssoHREF }, { children: avatar }));
        }
    }
    function renderIcon() {
        if (icon === null || icon === void 0 ? void 0 : icon.includes("://"))
            return "";
        return ((0, jsx_runtime_1.jsx)(icon_1.Icon, { name: icon, style: { fontSize: "14pt", marginRight: "10px" } }));
    }
    function renderName() {
        if (!showName)
            return;
        return ((0, jsx_runtime_1.jsx)("div", __assign({ style: { textAlign: "center", whiteSpace: "nowrap" } }, { children: display })));
    }
    return ((0, jsx_runtime_1.jsx)(antd_1.Tooltip, __assign({ title: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [renderIcon(), " ", toolTip !== null && toolTip !== void 0 ? toolTip : (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Use your ", display, " account."] })] }), color: backgroundColor }, { children: (0, jsx_runtime_1.jsxs)("div", __assign({ style: { display: "inline-block" } }, { children: [renderAvatar(), renderName()] })) })));
}
exports.StrategyAvatar = StrategyAvatar;
function RequiredSSO(_a) {
    var strategy = _a.strategy;
    if (strategy == null)
        return null;
    if (strategy.name == "null")
        return (0, jsx_runtime_1.jsx)(antd_1.Alert, { type: "error", message: "SSO Strategy not defined!" });
    var ssoLink = (0, path_1.join)(base_path_1.default, "sso", strategy.name);
    return ((0, jsx_runtime_1.jsx)(antd_1.Alert, { style: { margin: "15px 0" }, type: "warning", showIcon: false, message: "Single-Sign-On required", description: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["You must sign up using the", " ", (0, jsx_runtime_1.jsx)(AntdLink, __assign({ strong: true, underline: true, href: ssoLink }, { children: strategy.display })), " ", "Single-Sign-On strategy."] }), (0, jsx_runtime_1.jsx)("p", __assign({ style: { textAlign: "center" } }, { children: (0, jsx_runtime_1.jsx)(StrategyAvatar, { strategy: strategy, size: 120 }, strategy.name) }))] }) }));
}
exports.RequiredSSO = RequiredSSO;
// based on (partially) entered email address.
// if user has to sign up via SSO, this will tell which strategy to use.
// this also checks for subdomains via a simple heuristic – the precise test is on the backend.
// hence this should be good enough to catch @email.foo.edu for foo.edu domains
function useRequiredSSO(strategies, email) {
    return (0, react_1.useMemo)(function () {
        return (0, check_required_sso_1.checkRequiredSSO)({ email: email, strategies: strategies });
    }, [strategies == null, email]);
}
exports.useRequiredSSO = useRequiredSSO;
//# sourceMappingURL=sso.js.map