0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Refactored reset controller to Octane patterns

refs https://github.com/TryGhost/Ghost/issues/14101

- migrated to full native class syntax
- swapped use of `<GhTextInput>` in favor of native `<input>` and removed use of `{{action}}` in associated template
This commit is contained in:
Kevin Ansfield 2022-10-07 19:07:51 +01:00
parent ef0178cd06
commit 717e89113c
4 changed files with 73 additions and 60 deletions

View file

@ -998,3 +998,8 @@ remove|ember-template-lint|no-action|12|36|12|36|796968d082daba388ca19e97d45c727
remove|ember-template-lint|no-action|15|32|15|32|796968d082daba388ca19e97d45c7278d1076f04|1662681600000|1673053200000|1678237200000|app/templates/posts-loading.hbs remove|ember-template-lint|no-action|15|32|15|32|796968d082daba388ca19e97d45c7278d1076f04|1662681600000|1673053200000|1678237200000|app/templates/posts-loading.hbs
remove|ember-template-lint|no-action|18|29|18|29|796968d082daba388ca19e97d45c7278d1076f04|1662681600000|1673053200000|1678237200000|app/templates/posts-loading.hbs remove|ember-template-lint|no-action|18|29|18|29|796968d082daba388ca19e97d45c7278d1076f04|1662681600000|1673053200000|1678237200000|app/templates/posts-loading.hbs
remove|ember-template-lint|no-action|21|31|21|31|796968d082daba388ca19e97d45c7278d1076f04|1662681600000|1673053200000|1678237200000|app/templates/posts-loading.hbs remove|ember-template-lint|no-action|21|31|21|31|796968d082daba388ca19e97d45c7278d1076f04|1662681600000|1673053200000|1678237200000|app/templates/posts-loading.hbs
remove|ember-template-lint|no-action|4|85|4|85|ef910eebe8656965ebc73588c6f34a6260006b96|1662681600000|1673053200000|1678237200000|app/templates/reset.hbs
remove|ember-template-lint|no-action|19|35|19|35|8b04fb9251c6a34b6bfc2995b527539bb4106c37|1662681600000|1673053200000|1678237200000|app/templates/reset.hbs
remove|ember-template-lint|no-action|31|35|31|35|ddfad6e48c0df2368eed5dd9faf83f2a96dc182e|1662681600000|1673053200000|1678237200000|app/templates/reset.hbs
remove|ember-template-lint|no-passed-in-event-handlers|19|28|19|28|ea0378c5df53f2be82f0fd59e0c538efd7176851|1662681600000|1673053200000|1678237200000|app/templates/reset.hbs
remove|ember-template-lint|no-passed-in-event-handlers|31|28|31|28|06311a82a9589d4c126863466d56c7c4a76409d0|1662681600000|1673053200000|1678237200000|app/templates/reset.hbs

View file

@ -1,50 +1,55 @@
/* eslint-disable ghost/ember/alias-model-in-controller */ /* eslint-disable ghost/ember/alias-model-in-controller */
import Controller from '@ember/controller'; import Controller from '@ember/controller';
import ValidationEngine from 'ghost-admin/mixins/validation-engine'; import ValidationEngine from 'ghost-admin/mixins/validation-engine';
import {computed} from '@ember/object'; import {action} from '@ember/object';
import {inject as service} from '@ember/service'; import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency'; import {task} from 'ember-concurrency';
import {tracked} from '@glimmer/tracking';
export default Controller.extend(ValidationEngine, { export default class ResetController extends Controller.extend(ValidationEngine) {
ghostPaths: service(), @service ghostPaths;
notifications: service(), @service notifications;
session: service(), @service session;
ajax: service(), @service ajax;
config: service(), @service config;
newPassword: '', @tracked newPassword = '';
ne2Password: '', @tracked ne2Password = '';
token: '', @tracked token = '';
flowErrors: '', @tracked flowErrors = '';
validationType: 'reset', validationType = 'reset';
email: computed('token', function () { get email() {
// The token base64 encodes the email (and some other stuff), // The token base64 encodes the email (and some other stuff),
// each section is divided by a '|'. Email comes second. // each section is divided by a '|'. Email comes second.
return atob(this.token).split('|')[1]; return atob(this.token).split('|')[1];
}),
actions: {
submit() {
return this.resetPassword.perform();
} }
},
// Used to clear sensitive information // Used to clear sensitive information
clearData() { clearData() {
this.setProperties({ this.newPassword = '';
newPassword: '', this.ne2Password = '';
ne2Password: '', this.token = '';
token: ''
});
},
resetPassword: task(function* () { document.querySelector('form#reset')?.reset();
let credentials = this.getProperties('newPassword', 'ne2Password', 'token'); }
let authUrl = this.get('ghostPaths.url').api('authentication', 'password_reset');
this.set('flowErrors', ''); @action
handleInput(event) {
this.flowErrors = '';
this.errors.clear();
this.hasValidated.addObjects(['newPassword', 'ne2Password']);
this[event.currentTarget.name] = event.target.value;
}
@task({drop: true})
*resetPasswordTask() {
const {email, newPassword, ne2Password, token} = this;
const authUrl = this.ghostPaths.url.api('authentication', 'password_reset');
this.flowErrors = '';
this.hasValidated.addObjects(['newPassword', 'ne2Password']); this.hasValidated.addObjects(['newPassword', 'ne2Password']);
try { try {
@ -52,27 +57,27 @@ export default Controller.extend(ValidationEngine, {
try { try {
let resp = yield this.ajax.put(authUrl, { let resp = yield this.ajax.put(authUrl, {
data: { data: {
password_reset: [credentials] password_reset: [{newPassword, ne2Password, token}]
} }
}); });
this.notifications.showAlert(resp.password_reset[0].message, {type: 'warn', delayed: true, key: 'password.reset'}); this.notifications.showAlert(resp.password_reset[0].message, {type: 'warn', delayed: true, key: 'password.reset'});
this.session.authenticate('authenticator:cookie', this.email, credentials.newPassword); this.session.authenticate('authenticator:cookie', email, newPassword);
return true; return true;
} catch (error) { } catch (error) {
this.notifications.showAPIError(error, {key: 'password.reset'}); this.notifications.showAPIError(error, {key: 'password.reset'});
} }
} catch (error) { } catch (error) {
if (this.get('errors.newPassword')) { if (this.errors.errorsFor('newPassword').length) {
this.set('flowErrors', this.get('errors.newPassword')[0].message); this.flowErrors = this.errors.errorsFor('newPassword')[0].message;
} }
if (this.get('errors.ne2Password')) { if (this.errors.errorsFor('ne2Password').length) {
this.set('flowErrors', this.get('errors.ne2Password')[0].message); this.flowErrors = this.errors.errorsFor('ne2Password')[0].message;
} }
if (error && this.get('errors.length') === 0) { if (error && this.errors.length === 0) {
throw error; throw error;
} }
} }
}).drop() }
}); }

View file

@ -1,8 +1,7 @@
import AboutModal from '../components/modals/settings/about'; import AboutModal from '../components/modals/settings/about';
import Controller from '@ember/controller';
import {action} from '@ember/object'; import {action} from '@ember/object';
import {inject as service} from '@ember/service'; import {inject as service} from '@ember/service';
/* eslint-disable ghost/ember/alias-model-in-controller */
import Controller from '@ember/controller';
export default class SettingsController extends Controller { export default class SettingsController extends Controller {
@service modals; @service modals;

View file

@ -1,38 +1,42 @@
<div class="gh-flow"> <div class="gh-flow">
<div class="gh-flow-content-wrap"> <div class="gh-flow-content-wrap">
<section class="gh-flow-content fade-in"> <section class="gh-flow-content fade-in">
<form id="reset" class="gh-signin" method="post" novalidate="novalidate" {{action "submit" on="submit"}}> <form id="reset" class="gh-signin" method="post" novalidate="novalidate" {{on "submit" (perform this.resetPasswordTask)}}>
<header> <header>
<div class="gh-site-icon" style={{site-icon-style}}></div> <div class="gh-site-icon" style={{site-icon-style}}></div>
<h1>Reset your password.</h1> <h1>Reset your password.</h1>
</header> </header>
<GhFormGroup @errors={{this.errors}} @hasValidated={{this.hasValidated}} @property="newPassword"> <GhFormGroup @errors={{this.errors}} @hasValidated={{this.hasValidated}} @property="newPassword">
<span class="gh-input-icon gh-icon-lock"> <span class="gh-input-icon gh-icon-lock">
<GhTextInput <input
@type="password" type="password"
@name="newpassword" name="newPassword"
@placeholder="New password" placeholder="New password"
@class="password reset-password" aria-label="New password"
@autocorrect="off" class="gh-input password reset-password"
@shouldFocus={{true}} autocorrect="off"
@value={{readonly this.newPassword}} value={{this.newPassword}}
@input={{action (mut this.newPassword) value="target.value"}} /> {{autofocus}}
{{on "input" this.handleInput}}
/>
</span> </span>
</GhFormGroup> </GhFormGroup>
<GhFormGroup @errors={{this.errors}} @hasValidated={{this.hasValidated}} @property="ne2Password"> <GhFormGroup @errors={{this.errors}} @hasValidated={{this.hasValidated}} @property="ne2Password">
<span class="gh-input-icon gh-icon-lock"> <span class="gh-input-icon gh-icon-lock">
<GhTextInput <input
@type="password" type="password"
@name="ne2password" name="ne2Password"
@placeholder="Confirm new password" placeholder="Confirm new password"
@class="password reset-password" aria-label="Confirm new password"
@autocorrect="off" class="gh-input password reset-password"
@value={{readonly this.ne2Password}} autocorrect="off"
@input={{action (mut this.ne2Password) value="target.value"}} /> value={{this.ne2Password}}
{{on "input" this.handleInput}}
/>
</span> </span>
</GhFormGroup> </GhFormGroup>
<GhTaskButton @buttonText="Save new password" @task={{this.resetPassword}} @class="gh-btn gh-btn-reset gh-btn-block gh-btn-icon" @type="submit" @autoWidth="false" /> <GhTaskButton @buttonText="Save new password" @task={{this.resetPasswordTask}} @class="gh-btn gh-btn-reset gh-btn-block gh-btn-icon" @type="submit" @autoWidth="false" />
</form> </form>
<p class="main-error">{{this.flowErrors}}&nbsp;</p> <p class="main-error">{{this.flowErrors}}&nbsp;</p>