diff --git a/ghost/admin/app/components/gh-task-button.js b/ghost/admin/app/components/gh-task-button.js index 3e776e0f06..356d6d6d36 100644 --- a/ghost/admin/app/components/gh-task-button.js +++ b/ghost/admin/app/components/gh-task-button.js @@ -24,7 +24,7 @@ const GhTaskButton = Component.extend({ 'isSuccessClass', 'isFailureClass' ], - attributeBindings: ['disabled', 'type', 'tabindex'], + attributeBindings: ['disabled', 'form', 'type', 'tabindex'], task: null, disabled: false, diff --git a/ghost/admin/app/controllers/signup.js b/ghost/admin/app/controllers/signup.js index f090c7298b..5cc1e767db 100644 --- a/ghost/admin/app/controllers/signup.js +++ b/ghost/admin/app/controllers/signup.js @@ -1,6 +1,5 @@ import Controller from '@ember/controller'; import RSVP from 'rsvp'; -import ValidationEngine from 'ghost-admin/mixins/validation-engine'; import { VersionMismatchError, isVersionMismatchError @@ -10,7 +9,7 @@ import {isArray as isEmberArray} from '@ember/array'; import {inject as service} from '@ember/service'; import {task} from 'ember-concurrency'; -export default Controller.extend(ValidationEngine, { +export default Controller.extend({ ajax: service(), config: service(), ghostPaths: service(), @@ -21,13 +20,11 @@ export default Controller.extend(ValidationEngine, { flowErrors: '', profileImage: null, - // ValidationEngine settings - validationType: 'signup', signupDetails: alias('model'), actions: { - signup() { - this.get('signup').perform(); + validate(property) { + return this.signupDetails.validate({property}); }, setImage(image) { @@ -84,10 +81,10 @@ export default Controller.extend(ValidationEngine, { let notifications = this.get('notifications'); this.set('flowErrors', ''); - this.get('hasValidated').addObjects(setupProperties); + this.get('signupDetails.hasValidated').addObjects(setupProperties); try { - yield this.validate(); + yield this.signupDetails.validate(); yield this._completeInvitation(); try { @@ -100,6 +97,7 @@ export default Controller.extend(ValidationEngine, { // ValidationEngine throws undefined if (!error) { this.set('flowErrors', 'Please fill out the form to complete your sign-up'); + return false; } if (error && error.payload && error.payload.errors && isEmberArray(error.payload.errors)) { @@ -111,7 +109,7 @@ export default Controller.extend(ValidationEngine, { notifications.showAPIError(error, {key: 'signup.complete'}); } } - }), + }).drop(), _completeInvitation() { let authUrl = this.get('ghostPaths.url').api('authentication', 'invitation'); diff --git a/ghost/admin/app/routes/signup.js b/ghost/admin/app/routes/signup.js index 0e83d300c3..0e4159fefc 100644 --- a/ghost/admin/app/routes/signup.js +++ b/ghost/admin/app/routes/signup.js @@ -3,6 +3,7 @@ import EmberObject from '@ember/object'; import RSVP from 'rsvp'; import Route from '@ember/routing/route'; import UnauthenticatedRouteMixin from 'ghost-admin/mixins/unauthenticated-route-mixin'; +import ValidationEngine from 'ghost-admin/mixins/validation-engine'; import styleBody from 'ghost-admin/mixins/style-body'; import {inject as service} from '@ember/service'; @@ -27,7 +28,10 @@ export default Route.extend(styleBody, UnauthenticatedRouteMixin, { }, model(params) { - let signupDetails = EmberObject.create(); + let SignupDetails = EmberObject.extend(ValidationEngine, { + validationType: 'signup' + }); + let signupDetails = SignupDetails.create(); let re = /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2}|[A-Za-z0-9_-]{3})?$/; let email, tokenText; diff --git a/ghost/admin/app/templates/setup/two.hbs b/ghost/admin/app/templates/setup/two.hbs index 19920362d2..35eccb3374 100644 --- a/ghost/admin/app/templates/setup/two.hbs +++ b/ghost/admin/app/templates/setup/two.hbs @@ -16,6 +16,7 @@ {{gh-trim-focus-input tabindex="1" type="text" + id="blog-title" name="blog-title" placeholder="Eg. The Daily Awesome" autocorrect="off" @@ -33,6 +34,7 @@ {{svg-jar "user-circle"}} {{gh-text-input tabindex="2" + id="name" name="name" placeholder="Eg. John H. Watson" autocorrect="off" @@ -51,6 +53,7 @@ {{gh-text-input tabindex="3" type="email" + id="email" name="email" placeholder="Eg. john@example.com" autocorrect="off" @@ -69,6 +72,7 @@ {{gh-text-input tabindex="4" type="password" + id="password" name="password" placeholder="At least 10 characters" autocorrect="off" diff --git a/ghost/admin/app/templates/signup.hbs b/ghost/admin/app/templates/signup.hbs index 1ff4e5b826..eea45300ff 100644 --- a/ghost/admin/app/templates/signup.hbs +++ b/ghost/admin/app/templates/signup.hbs @@ -6,19 +6,20 @@

Create your account

-
+ {{!-- Hack to stop Chrome's broken auto-fills --}} {{gh-profile-image email=signupDetails.email setImage=(action "setImage")}} - {{#gh-form-group errors=signupDetails.errors hasValidated=hasValidated property="email"}} - + {{#gh-form-group errors=signupDetails.errors hasValidated=signupDetails.hasValidated property="email"}} + {{svg-jar "email"}} {{gh-text-input type="email" + id="email" name="email" placeholder="Eg. john@example.com" disabled="disabled" @@ -29,37 +30,35 @@ {{/gh-form-group}} - {{#gh-form-group errors=signupDetails.errors hasValidated=hasValidated property="name"}} - + {{#gh-form-group errors=signupDetails.errors hasValidated=signupDetails.hasValidated property="name"}} + {{svg-jar "user-circle"}} {{gh-trim-focus-input tabindex="1" type="text" + id="name" name="name" placeholder="Eg. John H. Watson" autocorrect="off" value=(readonly signupDetails.name) input=(action (mut signupDetails.name) value="target.value") - keyEvents=(hash - Enter=(action "signup") - ) focus-out=(action "validate" "name") }} {{gh-error-message errors=signupDetails.errors property="name"}} {{/gh-form-group}} - {{#gh-form-group errors=signupDetails.errors hasValidated=hasValidated property="password"}} + {{#gh-form-group errors=signupDetails.errors hasValidated=signupDetails.hasValidated property="password"}} {{svg-jar "lock"}} {{gh-text-input tabindex="2" type="password" + id="password" name="password" placeholder="At least 10 characters" - onenter=(action "signup") autocorrect="off" value=(readonly signupDetails.password) input=(action (mut signupDetails.password) value="target.value") @@ -67,9 +66,14 @@ {{gh-error-message errors=signupDetails.errors property="password"}} {{/gh-form-group}} + + {{!-- include the email field again in case password managers ignore the disabled input --}} +
{{gh-task-button "Create Account" + type="submit" + form="signup" runningText="Creating" task=signup class="gh-btn gh-btn-green gh-btn-lg gh-btn-block gh-btn-icon" diff --git a/ghost/admin/app/validators/new-user.js b/ghost/admin/app/validators/new-user.js index 1f5b6c3c25..fe373c66fe 100644 --- a/ghost/admin/app/validators/new-user.js +++ b/ghost/admin/app/validators/new-user.js @@ -14,6 +14,7 @@ export default BaseValidator.extend(PasswordValidatorMixin, { if (!validator.isLength(name || '', 1)) { model.get('errors').add('name', 'Please enter a name.'); + model.get('hasValidated').addObject('email'); this.invalidate(); } }, @@ -28,6 +29,8 @@ export default BaseValidator.extend(PasswordValidatorMixin, { model.get('errors').add('email', 'Invalid Email.'); this.invalidate(); } + + model.get('hasValidated').addObject('email'); }, password(model) {