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
{_t("Please review and accept the policies of this homeserver:")}
+ { checkboxes } + { errorSection } +