diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js index bfdfbb63bf..d4c2f58aa9 100644 --- a/src/components/views/login/InteractiveAuthEntryComponents.js +++ b/src/components/views/login/InteractiveAuthEntryComponents.js @@ -22,6 +22,7 @@ import classnames from 'classnames'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import SettingsStore from "../../../settings/SettingsStore"; /* This file contains a collection of components which are used by the * InteractiveAuth to prompt the user to enter the information needed @@ -209,6 +210,103 @@ export const RecaptchaAuthEntry = React.createClass({ }, }); +export const TermsAuthEntry = React.createClass({ + displayName: 'TermsAuthEntry', + + statics: { + LOGIN_TYPE: "m.login.terms", + }, + + propTypes: { + submitAuthDict: PropTypes.func.isRequired, + stageParams: PropTypes.object.isRequired, + errorText: PropTypes.string, + busy: PropTypes.bool, + }, + + componentWillMount: function() { + const allPolicies = this.props.stageParams.policies || {}; + const prefLang = SettingsStore.getValue("language"); + const initToggles = {}; + const pickedPolicies = []; + for (const policyId of Object.keys(allPolicies)) { + const policy = allPolicies[policyId]; + + // Pick a language based on the user's language, falling back to english, + // and finally to the first language available. If there's still no policy + // available then the homeserver isn't respecting the spec. + const availableLangs = Object.keys(policy).filter(e => e !== "version"); + let langPolicy = policy[prefLang]; + if (!langPolicy) langPolicy = "en"; + if (!langPolicy) langPolicy = policy[availableLangs[0]]; // last resort + if (!langPolicy) throw new Error("Failed to find a policy to show the user"); + + initToggles[policyId] = false; + + langPolicy.id = policyId; + pickedPolicies.push(langPolicy); + } + + this.setState({ + "toggledPolicies": initToggles, + "policies": pickedPolicies, + }); + }, + + _trySubmit: function(policyId) { + const newToggles = {}; + let allChecked = true; + for (const policy of this.state.policies) { + let checked = this.state.toggledPolicies[policy.id]; + if (policy.id === policyId) checked = !checked; + + newToggles[policy.id] = checked; + allChecked = allChecked && checked; + } + + this.setState({"toggledPolicies": newToggles}); + if (allChecked) this.props.submitAuthDict({type: TermsAuthEntry.LOGIN_TYPE}); + }, + + render: function() { + if (this.props.busy) { + const Loader = sdk.getComponent("elements.Spinner"); + return <Loader />; + } + + let checkboxes = []; + let allChecked = true; + for (const policy of this.state.policies) { + const checked = this.state.toggledPolicies[policy.id]; + allChecked = allChecked && checked; + + checkboxes.push( + <label key={"policy_checkbox_" + policy.id}> + <input type="checkbox" onClick={() => this._trySubmit(policy.id)} checked={checked} /> + <a href={policy.url} target="_blank" rel="noopener">{ policy.name }</a> + </label> + ); + } + + let errorSection; + if (this.props.errorText) { + errorSection = ( + <div className="error" role="alert"> + { this.props.errorText } + </div> + ); + } + + return ( + <div> + <p>{_t("Please review and accept the policies of this homeserver:")}</p> + { checkboxes } + { errorSection } + </div> + ); + }, +}); + export const EmailIdentityAuthEntry = React.createClass({ displayName: 'EmailIdentityAuthEntry', @@ -496,6 +594,7 @@ const AuthEntryComponents = [ RecaptchaAuthEntry, EmailIdentityAuthEntry, MsisdnAuthEntry, + TermsAuthEntry, ]; export function getEntryComponentForLoginType(loginType) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 338f744a9f..e00be22d1c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -643,6 +643,8 @@ "Dismiss": "Dismiss", "To continue, please enter your password.": "To continue, please enter your password.", "Password:": "Password:", + "Please accept all of the policies": "Please accept all of the policies", + "Please review and accept the policies of this homeserver:": "Please review and accept the policies of this homeserver:", "An email has been sent to %(emailAddress)s": "An email has been sent to %(emailAddress)s", "Please check your email to continue registration.": "Please check your email to continue registration.", "Token incorrect": "Token incorrect",