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",