diff --git a/app/assets/javascripts/discourse/app/controllers/create-account.js b/app/assets/javascripts/discourse/app/controllers/create-account.js index a74aa542e3b..f1fd1c66a63 100644 --- a/app/assets/javascripts/discourse/app/controllers/create-account.js +++ b/app/assets/javascripts/discourse/app/controllers/create-account.js @@ -20,6 +20,7 @@ import { userPath } from "discourse/lib/url"; import { findAll } from "discourse/models/login-method"; import EmberObject from "@ember/object"; import User from "discourse/models/user"; +import { Promise } from "rsvp"; export default Controller.extend( ModalFunctionality, @@ -41,9 +42,13 @@ export default Controller.extend( hasAuthOptions: notEmpty("authOptions"), canCreateLocal: setting("enable_local_logins"), - showCreateForm: or("hasAuthOptions", "canCreateLocal"), requireInviteCode: setting("require_invite_code"), + @discourseComputed("hasAuthOptions", "canCreateLocal", "skipConfirmation") + showCreateForm(hasAuthOptions, canCreateLocal, skipConfirmation) { + return (hasAuthOptions || canCreateLocal) && !skipConfirmation; + }, + resetForm() { // We wrap the fields in a structure so we can assign a value this.setProperties({ @@ -197,26 +202,44 @@ export default Controller.extend( @on("init") fetchConfirmationValue() { - return ajax(userPath("hp.json")).then(json => { - this._challengeDate = new Date(); - // remove 30 seconds for jitter, make sure this works for at least - // 30 seconds so we don't have hard loops - this._challengeExpiry = parseInt(json.expires_in, 10) - 30; - if (this._challengeExpiry < 30) { - this._challengeExpiry = 30; - } + if (this._challengeDate === undefined && this._hpPromise) { + // Request already in progress + return this._hpPromise; + } - this.setProperties({ - accountHoneypot: json.value, - accountChallenge: json.challenge - .split("") - .reverse() - .join("") - }); - }); + this._hpPromise = ajax(userPath("hp.json")) + .then(json => { + this._challengeDate = new Date(); + // remove 30 seconds for jitter, make sure this works for at least + // 30 seconds so we don't have hard loops + this._challengeExpiry = parseInt(json.expires_in, 10) - 30; + if (this._challengeExpiry < 30) { + this._challengeExpiry = 30; + } + + this.setProperties({ + accountHoneypot: json.value, + accountChallenge: json.challenge + .split("") + .reverse() + .join("") + }); + }) + .finally(() => (this._hpPromise = undefined)); + + return this._hpPromise; }, performAccountCreation() { + if ( + !this._challengeDate || + new Date() - this._challengeDate > 1000 * this._challengeExpiry + ) { + return this.fetchConfirmationValue().then(() => + this.performAccountCreation() + ); + } + const attrs = this.getProperties( "accountName", "accountEmail", @@ -263,6 +286,7 @@ export default Controller.extend( .find("input[name=redirect]") .val(userPath("account-created")); $hidden_login_form.submit(); + return new Promise(() => {}); // This will never resolve, the page will reload instead } else { this.flash( result.message || I18n.t("create_account.failed"), @@ -298,6 +322,14 @@ export default Controller.extend( ); }, + onShow() { + if (this.skipConfirmation) { + this.performAccountCreation().finally(() => + this.set("skipConfirmation", false) + ); + } + }, + actions: { externalLogin(provider) { this.login.send("externalLogin", provider); @@ -332,13 +364,7 @@ export default Controller.extend( return; } - if (new Date() - this._challengeDate > 1000 * this._challengeExpiry) { - this.fetchConfirmationValue().then(() => - this.performAccountCreation() - ); - } else { - this.performAccountCreation(); - } + this.performAccountCreation(); } } } diff --git a/app/assets/javascripts/discourse/app/controllers/login.js b/app/assets/javascripts/discourse/app/controllers/login.js index 36e686d6106..870c75d9000 100644 --- a/app/assets/javascripts/discourse/app/controllers/login.js +++ b/app/assets/javascripts/discourse/app/controllers/login.js @@ -381,12 +381,16 @@ export default Controller.extend(ModalFunctionality, { return; } + const skipConfirmation = + options && this.siteSettings.external_auth_skip_create_confirm; + const createAccountController = this.createAccount; createAccountController.setProperties({ accountEmail: options.email, accountUsername: options.username, accountName: options.name, - authOptions: EmberObject.create(options) + authOptions: EmberObject.create(options), + skipConfirmation }); showModal("createAccount", { modalClass: "create-account" }); diff --git a/app/assets/javascripts/discourse/app/templates/modal/create-account.hbs b/app/assets/javascripts/discourse/app/templates/modal/create-account.hbs index eb2c7940809..2edb94b483e 100644 --- a/app/assets/javascripts/discourse/app/templates/modal/create-account.hbs +++ b/app/assets/javascripts/discourse/app/templates/modal/create-account.hbs @@ -7,6 +7,10 @@ {{login-buttons externalLogin=(action "externalLogin")}} {{/unless}} + {{#if skipConfirmation}} + {{loading-spinner size="large"}} + {{/if}} + {{#if showCreateForm}}