// Copyright 2021 The Casdoor Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import React from "react"; import {Button, Form, Input, Result} from "antd"; import * as Setting from "../Setting"; import * as AuthBackend from "./AuthBackend"; import * as ProviderButton from "./ProviderButton"; import i18next from "i18next"; import * as Util from "./Util"; import {authConfig} from "./Auth"; import * as ApplicationBackend from "../backend/ApplicationBackend"; import * as AgreementModal from "../common/modal/AgreementModal"; import {SendCodeInput} from "../common/SendCodeInput"; import RegionSelect from "../common/select/RegionSelect"; import CustomGithubCorner from "../common/CustomGithubCorner"; import LanguageSelect from "../common/select/LanguageSelect"; import {withRouter} from "react-router-dom"; import {CountryCodeSelect} from "../common/select/CountryCodeSelect"; import * as PasswordChecker from "../common/PasswordChecker"; const formItemLayout = { labelCol: { xs: { span: 24, }, sm: { span: 8, }, }, wrapperCol: { xs: { span: 24, }, sm: { span: 16, }, }, }; export const tailFormItemLayout = { wrapperCol: { xs: { span: 24, offset: 0, }, sm: { span: 16, offset: 8, }, }, }; class SignupPage extends React.Component { constructor(props) { super(props); this.state = { classes: props, applicationName: (props.applicationName ?? props.match?.params?.applicationName) ?? null, email: "", phone: "", countryCode: "", emailCode: "", phoneCode: "", validEmail: false, validPhone: false, region: "", isTermsOfUseVisible: false, termsOfUseContent: "", }; this.form = React.createRef(); } componentDidMount() { const oAuthParams = Util.getOAuthGetParameters(); if (oAuthParams !== null) { const signinUrl = window.location.href.replace("/signup/oauth/authorize", "/login/oauth/authorize"); sessionStorage.setItem("signinUrl", signinUrl); } if (this.getApplicationObj() === undefined) { if (this.state.applicationName !== null) { this.getApplication(this.state.applicationName); } else if (oAuthParams !== null) { this.getApplicationLogin(oAuthParams); } else { Setting.showMessage("error", `Unknown application name: ${this.state.applicationName}`); this.onUpdateApplication(null); } } } getApplication(applicationName) { if (applicationName === undefined) { return; } ApplicationBackend.getApplication("admin", applicationName) .then((res) => { if (res.status === "error") { Setting.showMessage("error", res.msg); return; } this.onUpdateApplication(res.data); }); } getApplicationLogin(oAuthParams) { AuthBackend.getApplicationLogin(oAuthParams) .then((res) => { if (res.status === "ok") { const application = res.data; this.onUpdateApplication(application); } else { this.onUpdateApplication(null); this.setState({ msg: res.msg, }); } }); } getResultPath(application, signupParams) { if (signupParams?.plan && signupParams?.pricing) { // the prompt page needs the user to be signed in, so for paid-user sign up, just go to buy-plan page return `/buy-plan/${application.organization}/${signupParams?.pricing}?user=${signupParams.username}&plan=${signupParams.plan}`; } if (authConfig.appName === application.name) { return "/result"; } else { if (Setting.hasPromptPage(application)) { return `/prompt/${application.name}`; } else { return `/result/${application.name}`; } } } getApplicationObj() { return this.props.application; } onUpdateAccount(account) { this.props.onUpdateAccount(account); } onUpdateApplication(application) { this.props.onUpdateApplication(application); } parseOffset(offset) { if (offset === 2 || offset === 4 || Setting.inIframe() || Setting.isMobile()) { return "0 auto"; } if (offset === 1) { return "0 10%"; } if (offset === 3) { return "0 60%"; } } onFinish(values) { const application = this.getApplicationObj(); const params = new URLSearchParams(window.location.search); values.plan = params.get("plan"); values.pricing = params.get("pricing"); AuthBackend.signup(values) .then((res) => { if (res.status === "ok") { // the user's id will be returned by `signup()`, if user signup by phone, the `username` in `values` is undefined. values.username = res.data.split("/")[1]; if (Setting.hasPromptPage(application) && (!values.plan || !values.pricing)) { AuthBackend.getAccount("") .then((res) => { let account = null; if (res.status === "ok") { account = res.data; account.organization = res.data2; this.onUpdateAccount(account); Setting.goToLinkSoft(this, this.getResultPath(application, values)); } else { Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`); } }); } else { Setting.goToLinkSoft(this, this.getResultPath(application, values)); } } else { Setting.showMessage("error", i18next.t(`signup:${res.msg}`)); } }); } onFinishFailed(values, errorFields, outOfDate) { this.form.current.scrollToField(errorFields[0].name); } isProviderVisible(providerItem) { return Setting.isProviderVisibleForSignUp(providerItem); } renderFormItem(application, signupItem) { if (!signupItem.visible) { return null; } const required = signupItem.required; if (signupItem.name === "Username") { return (