diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js index bfdfbb63bf..6e0e5d538a 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,125 @@ 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() { + // example stageParams: + // + // { + // "policies": { + // "privacy_policy": { + // "version": "1.0", + // "en": { + // "name": "Privacy Policy", + // "url": "https://example.org/privacy-1.0-en.html", + // }, + // "fr": { + // "name": "Politique de confidentialité", + // "url": "https://example.org/privacy-1.0-fr.html", + // }, + // }, + // "other_policy": { ... }, + // } + // } + + 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. + let langPolicy = policy[prefLang]; + if (!langPolicy) langPolicy = policy["en"]; + if (!langPolicy) { + // last resort + const firstLang = Object.keys(policy).find(e => e !== "version"); + langPolicy = policy[firstLang]; + } + 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 ; + } + + let checkboxes = []; + let allChecked = true; + for (const policy of this.state.policies) { + const checked = this.state.toggledPolicies[policy.id]; + allChecked = allChecked && checked; + + checkboxes.push( + + ); + } + + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } + + return ( +
+

{_t("Please review and accept the policies of this homeserver:")}

+ { checkboxes } + { errorSection } +
+ ); + }, +}); + export const EmailIdentityAuthEntry = React.createClass({ displayName: 'EmailIdentityAuthEntry', @@ -496,6 +616,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",