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:
parent
ef0178cd06
commit
717e89113c
4 changed files with 73 additions and 60 deletions
|
@ -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
|
||||||
|
|
|
@ -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()
|
}
|
||||||
});
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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}} </p>
|
<p class="main-error">{{this.flowErrors}} </p>
|
||||||
|
|
Loading…
Add table
Reference in a new issue