<!--
~ Copyright (c) 2021, WSO2 Inc. (http://www.wso2.com). All Rights Reserved.
~
~ This software is the property of WSO2 Inc. and its suppliers, if any.
~ Dissemination of any information or reproduction of any material contained
~ herein in any form is strictly forbidden, unless permitted by WSO2 expressly.
~ You may not alter or remove any copyright or other notice from copies of this content."
-->

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="org.apache.commons.lang.StringUtils" %>
<%@ page import="org.owasp.encoder.Encode" %>
<%@ page import="org.wso2.carbon.identity.mgt.constants.SelfRegistrationStatusCodes" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointConstants" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointUtil" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementServiceUtil" %>
<%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.client.model.User" %>
<%@ page import="org.wso2.carbon.identity.core.util.IdentityTenantUtil" %>
<%@ page import="java.io.File" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.Enumeration" %>
<%@ taglib prefix="layout" uri="org.wso2.identity.apps.taglibs.layout.controller" %>

<jsp:directive.include file="includes/localize.jsp"/>
<jsp:directive.include file="tenant-resolve.jsp"/>

<!-- Branding Preferences -->
<jsp:directive.include file="extensions/branding-preferences.jsp"/>

<%
    boolean error = IdentityManagementEndpointUtil.getBooleanValue(request.getAttribute("error"));
    boolean isSaaSApp = Boolean.parseBoolean(request.getParameter("isSaaSApp"));
    boolean skipSignUpEnableCheck = Boolean.parseBoolean(request.getParameter("skipsignupenablecheck"));
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    User user = IdentityManagementServiceUtil.getInstance().resolveUser(username, tenantDomain, isSaaSApp);
    Object errorCodeObj = request.getAttribute("errorCode");
    Object errorMsgObj = request.getAttribute("errorMsg");
    String callback = Encode.forHtmlAttribute(request.getParameter("callback"));
    String errorCode = null;
    String errorMsg = null;

    if (errorCodeObj != null) {
        errorCode = errorCodeObj.toString();
    }
    if (SelfRegistrationStatusCodes.ERROR_CODE_INVALID_TENANT.equalsIgnoreCase(errorCode)) {
        errorMsg = "Invalid tenant domain - " + user.getTenantDomain();
    } else if (SelfRegistrationStatusCodes.ERROR_CODE_USER_ALREADY_EXISTS.equalsIgnoreCase(errorCode)) {
        errorMsg = "Username '" + username + "' is already taken. Please pick a different username";
    } else if (SelfRegistrationStatusCodes.ERROR_CODE_SELF_REGISTRATION_DISABLED.equalsIgnoreCase(errorCode)) {
        errorMsg = "Self registration is disabled for tenant - " + user.getTenantDomain();
    } else if (SelfRegistrationStatusCodes.CODE_USER_NAME_INVALID.equalsIgnoreCase(errorCode)) {
        if (request.getAttribute("errorMessage") != null) {
            errorMsg = (String) request.getAttribute("errorMessage");
        } else {
            errorMsg = user.getUsername() + " is an invalid user name. Please pick a valid username.";
        }
    } else if (StringUtils.equalsIgnoreCase(SelfRegistrationStatusCodes.ERROR_CODE_INVALID_EMAIL_USERNAME,
            errorCode)) {
        errorMsg = "Username is invalid. Username should be in email format.";
    } else if (errorMsgObj != null) {
        errorMsg = errorMsgObj.toString();
    }
%>

<!doctype html>
<html>
<head>
    <!-- header -->
    <%
        File headerFile = new File(getServletContext().getRealPath("extensions/header.jsp"));
        if (headerFile.exists()) {
    %>
        <jsp:include page="extensions/header.jsp"/>
    <% } else { %>
        <jsp:include page="includes/header.jsp"/>
    <% } %>
</head>
<body class="login-portal layout recovery-layout">
    <layout:main layoutName="<%= layout %>" layoutFileRelativePath="<%= layoutFileRelativePath %>" data="<%= layoutData %>" >
        <layout:component componentName="ProductHeader" >
            <!-- product-title -->
            <%
                File productTitleFile = new File(getServletContext().getRealPath("extensions/product-title.jsp"));
                if (productTitleFile.exists()) {
            %>
                <jsp:include page="extensions/product-title.jsp"/>
            <% } else { %>
                <jsp:include page="includes/product-title.jsp"/>
            <% } %>
        </layout:component>
        <layout:component componentName="MainSection" >
            <div class="ui segment">
                <h3 class="ui header" data-testid="self-registration-username-request-old-page-header">
                    <%=IdentityManagementEndpointUtil.i18n(recoveryResourceBundle, "Start.signing.up")%>
                </h3>

                <% if (error) { %>
                <div class="ui negative message" id="server-error-msg">
                    <%= IdentityManagementEndpointUtil.i18nBase64(recoveryResourceBundle, errorMsg) %>
                </div>
                <% } %>
                <!-- validation -->

                <div class="segment-form">
                    <form class="ui large form" action="signup.do" method="post" id="register" novalidate>
                        <div id="usernameField" class="field">
                            <label><%=IdentityManagementEndpointUtil.i18n(recoveryResourceBundle, "Email")%></label>
                            <div class="ui fluid left icon input">
                                <input
                                    type="email"
                                    id="usernameUserInput"
                                    value=""
                                    name="usernameUserInput"
                                    tabindex="1"
                                    placeholder="Enter your email"
                                    data-testid="self-register-page-username-input"
                                    required
                                />
                                <i aria-hidden="true" class="envelope outline icon"></i>
                                <input id="username" name="username" type="hidden"
                                    <% if(skipSignUpEnableCheck) {%> value="<%=Encode.forHtmlAttribute(username)%>" <%}%>>
                            </div>
                            <div class="mt-1" id="username-error-msg" hidden="hidden">
                                <div class="ui grid">
                                    <div class="one wide column">
                                        <i class="red exclamation circle icon"></i>
                                    </div>
                                    <div class="fourteen wide column validation-error-message" id="username-error-msg-text"></div>
                                </div>
                            </div>
                        </div>
                        <div id="passwordField" class="field">
                            <label><%=IdentityManagementEndpointUtil.i18n(recoveryResourceBundle, "Password")%></label>
                            <div class="ui fluid left icon input addon-wrapper">
                                <input
                                    type="password"
                                    id="passwordUserInput"
                                    value=""
                                    name="passwordUserInput"
                                    tabindex="1"
                                    placeholder="Enter your password"
                                    data-testid="self-register-page-password-input"
                                    required
                                />
                                <i aria-hidden="true" class="lock icon"></i>
                                <i id="password-eye" class="eye icon right-align password-toggle" onclick="showPassword()"></i>
                                <input id="password" name="password" type="hidden"
                                    <% if(skipSignUpEnableCheck) {%> value="<%=Encode.forHtmlAttribute(username)%>" <%}%>>
                            </div>
                            <div class="mt-1" id="password-error-msg" hidden="hidden">
                                <div class="ui grid">
                                    <div class="one wide column">
                                        <i class="red exclamation circle icon"></i>
                                    </div>
                                    <div class="fourteen wide column validation-error-message" id="password-error-msg-text"></div>
                                </div>
                            </div>
                        </div>
                        <input name="previous_step" type="hidden" id="previous_step" />

                        <% Map<String, String[]> requestMap = request.getParameterMap();
                            for (Map.Entry<String, String[]> entry : requestMap.entrySet()) {
                                String key = Encode.forHtmlAttribute(entry.getKey());
                                String value = Encode.forHtmlAttribute(entry.getValue()[0]); %>
                        <div class="field">
                            <input id="<%= key%>" name="<%= key%>" type="hidden"
                                value="<%=value%>" class="form-control">
                        </div>
                        <% } %>

                        <div class="ui divider hidden"></div>

                        <div class="buttons mt-4">
                            <button id="registrationSubmit" class="ui primary button large fluid" type="submit" disabled>
                                <%=IdentityManagementEndpointUtil.i18n(recoveryResourceBundle,
                                        "Continue")%>
                            </button>
                        </div>
                        <div class="ui divider hidden"></div>
                        <div class="buttons mt-2">
                            <div class="field external-link-container text-small">
                                <%=IdentityManagementEndpointUtil.i18n(recoveryResourceBundle,
                                        "Already.have.an.account")%>
                                <a href="<%=callback%>">
                                    <%=IdentityManagementEndpointUtil.i18n(recoveryResourceBundle, "Sign.in")%>
                                </a>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </layout:component>
        <layout:component componentName="ProductFooter" >
            <!-- product-footer -->
            <%
                File productFooterFile = new File(getServletContext().getRealPath("extensions/product-footer.jsp"));
                if (productFooterFile.exists()) {
            %>
                <jsp:include page="extensions/product-footer.jsp"/>
            <% } else { %>
                <jsp:include page="includes/product-footer.jsp"/>
            <% } %>
        </layout:component>
    </layout:main>

    <!-- footer -->
    <%
        File footerFile = new File(getServletContext().getRealPath("extensions/footer.jsp"));
        if (footerFile.exists()) {
    %>
        <jsp:include page="extensions/footer.jsp"/>
    <% } else { %>
        <jsp:include page="includes/footer.jsp"/>
    <% } %>

    <script>
        var $registerForm = $("#register");
        var validUsername = false;
        var validPassword = false;

        // Reloads the page if the page is loaded by going back in history.
        // Fixes issues with Firefox.
        window.addEventListener( "pageshow", function ( event ) {
            var historyTraversal = event.persisted ||
                                ( typeof window.performance != "undefined" &&
                                    window.performance.navigation.type === 2 );

            if ( historyTraversal ) {
                if($registerForm){
                    $registerForm.data("submitted", false);
                }
            }
        });

        function goBack() {
            window.history.back();
        }

        // Fires when password field lose focus.
        $('#usernameUserInput').bind('blur', function () {
            showUsernameValidationStatus();
        });

        // Fires when password field lose focus.
        $('#passwordUserInput').bind('blur', function () {
            showPasswordValidationStatus();
        });

        // Fires when password field click or keyup.
        $('#usernameUserInput').bind('keyup click blur', function () {
            validateUsername();
            changeSubmitButtonStatus();
            var username_error = $("#username-error-msg");
            // This will make the error disappear when the user enter a valid username
            // without the need of the focus loss event above.
            if (!username_error.is(":hidden")) {
                showUsernameValidationStatus();
            }
        });

        // Fires when password field click or keyup.
        $('#passwordUserInput').bind('keyup click blur', function () {
            validatePassword();
            changeSubmitButtonStatus();
            var password_error = $("#password-error-msg");
            // This will make the error disappear when the user enter a valid password
            // without the need of the focus loss event above.
            if (!password_error.is(":hidden")) {
                showPasswordValidationStatus();
            }
        });

        // Handle form submission preventing double submission.
        $(document).ready(function(){
            $.fn.preventDoubleSubmission = function() {
                $(this).on("submit", function(e){
                    var $form = $(this);
                    if ($form.data("submitted") === true) {
                        // Previously submitted - don't submit again.
                        e.preventDefault();
                        console.warn("Prevented a possible double submit event");
                    } else {
                        e.preventDefault();

                        if (validUsername && validatePassword) {
                            // Username validation
                            var userName = document.getElementById("username");
                            var usernameUserInput = document.getElementById("usernameUserInput");

                            if (usernameUserInput) {
                                userName.value = usernameUserInput.value.trim();
                            }

                            // Password Validation
                            var password = document.getElementById("password");
                            var passwordUserInput = document.getElementById("passwordUserInput");

                            if (passwordUserInput) {
                                password.value = passwordUserInput.value.trim();
                            }

                            // Mark it so that the next submit can be ignored.
                            $form.data("submitted", true);
                            document.getElementById("register").submit();
                        }
                    }
                });

                return this;
            };

            $registerForm.preventDoubleSubmission();

            $("#previous_step").val(window.location.href);
        });

        var passwordField = $('#passwordUserInput');

        // show password function
        function showPassword() {
            if (passwordField.attr("type") === 'text') {
                passwordField.attr("type", "password")
                document.getElementById("password-eye").classList.remove("slash");
            } else {
                passwordField.attr("type", "text")
                document.getElementById("password-eye").classList.add("slash");
            }
        }

        function validateUsername() {
            // Username validation
            var userName = document.getElementById("username");
            var usernameUserInput = document.getElementById("usernameUserInput");

            if (usernameUserInput.value.trim() === "")  {
                    validUsername = false;
            } else {
                const usernamePattern = /^([\u00C0-\u00FFa-zA-Z0-9_\+\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,10})$/;
                if (!usernamePattern.test(usernameUserInput.value.trim())) {
                    validUsername = false;
                } else {
                    // When username is accepted.
                    validUsername = true;
                }
            }
        }

        function showUsernameValidationStatus() {
            var userName = document.getElementById("username");
            var usernameUserInput = document.getElementById("usernameUserInput");
            var usernameField = $("#usernameField");

            var username_error_msg = $("#username-error-msg");
            var server_error_msg = $("#server-error-msg");
            var username_error_msg_text = $("#username-error-msg-text");
            if (server_error_msg.text() !== null && server_error_msg.text().trim() !== ""  ) {
                $("#username-error-msg").hide();
                usernameField.removeClass("error");
            }

            if (usernameUserInput.value.trim() === "")  {
                    username_error_msg_text.text("Enter your email");
                    username_error_msg.show();
                    usernameField.addClass("error");
                    $("html, body").animate({scrollTop: username_error_msg.offset().top}, 'slow');
            } else {
                const usernamePattern = /^([\u00C0-\u00FFa-zA-Z0-9_\+\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,10})$/;
                if (!usernamePattern.test(usernameUserInput.value.trim())) {
                    username_error_msg_text.text("Enter a valid email address")
                    username_error_msg.show();
                    usernameField.addClass("error");
                    $("html, body").animate({scrollTop: username_error_msg.offset().top}, 'slow');
                } else {
                    // When username is accepted.
                    username_error_msg.hide();
                    usernameField.removeClass("error");
                }
            }
        }

        function validatePassword() {
            // Password Validation
            var password = document.getElementById("password");
            var passwordUserInput = document.getElementById("passwordUserInput");

            if (passwordUserInput.value.trim() === "")  {
                    validPassword = false;
            } else {
                const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/;
                if (!passwordPattern.test(passwordUserInput.value.trim())) {
                    validPassword = false;
                } else {
                    // When password is accepted.
                    validPassword = true;
                }
            }
        }

        function showPasswordValidationStatus() {
            var password = document.getElementById("password");
            var passwordUserInput = document.getElementById("passwordUserInput");
            var passwordField = $("#passwordField");

            var password_error_msg = $("#password-error-msg");
            var server_error_msg = $("#server-error-msg");
            var password_error_msg_text = $("#password-error-msg-text");
            if (server_error_msg.text() !== null && server_error_msg.text().trim() !== ""  ) {
                $("#password-error-msg").hide();
                passwordField.removeClass("error");
            }

            if (passwordUserInput.value.trim() === "")  {
                    password_error_msg_text.text("Enter your password");
                    password_error_msg.show();
                    passwordField.addClass("error");
                    $("html, body").animate({scrollTop: password_error_msg.offset().top}, 'slow');
            } else {
                const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/;
                if (!passwordPattern.test(passwordUserInput.value.trim())) {
                    password_error_msg_text.text("Your password should contain at least eight characters, " +
                        "including at least one each from uppercase and lowercase letters, " +
                        "numbers and symbols ( ! @ # $ % ^ & * ).");
                    password_error_msg.show();
                    passwordField.addClass("error");
                    $("html, body").animate({scrollTop: password_error_msg.offset().top}, 'slow');
                } else {
                    // When password is accepted.
                    password_error_msg.hide();
                    passwordField.removeClass("error");
                }
            }
        }

        function changeSubmitButtonStatus() {
            if (validUsername && validPassword) {
                $('#registrationSubmit').removeClass('disabled').prop('disabled', false); // enables button
            } else {
                $('#registrationSubmit').addClass('disabled').prop('disabled', true);   // disables button
            }
        }
    </script>
</body>
</html>
