feat: Set an account's password
This commit is contained in:
13 files changed
+203
-3
No files matched your search
@@ -9,4 +9,27 @@ export default class AccountModel extends GeneratedAccountModel {
|
||||
*/
|
||||
@fragment('fragment-account-attributes', { defaultValue: {} }) attributes;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Save account password via the `set-password` method.
|
||||
* See serializer and adapter for more information.
|
||||
* @param {object} options
|
||||
* @param {object} options.adapterOptions
|
||||
* @return {Promise}
|
||||
*/
|
||||
savePassword(options={ adapterOptions: {} }) {
|
||||
const defaultAdapterOptions = {
|
||||
method: 'set-password',
|
||||
serializePassword: true
|
||||
};
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
...defaultAdapterOptions,
|
||||
...options.adapterOptions
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import ApplicationSerializer from './application';
|
||||
import { get } from '@ember/object';
|
||||
|
||||
export default class AccountSerializer extends ApplicationSerializer {
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* If `adapterOptions.serializePassword` is true, the serialization should
|
||||
* include **password** and the version.
|
||||
* @override
|
||||
* @param {Snapshot} snapshot
|
||||
* @return {object}
|
||||
*/
|
||||
serialize(snapshot) {
|
||||
const serializePassword = get(snapshot, 'adapterOptions.serializePassword');
|
||||
let serialized = super.serialize(...arguments);
|
||||
if (serializePassword) serialized = this.serializeWithPassword(snapshot);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a payload containing only password.
|
||||
* @param {Snapshot} snapshot
|
||||
* @return {object}
|
||||
*/
|
||||
serializeWithPassword(snapshot) {
|
||||
return {
|
||||
version: snapshot.attr('version'),
|
||||
password: snapshot.attr('attributes').attr('password'),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/account';
|
||||
@@ -0,0 +1,23 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Serializer | account', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let serializer = store.serializerFor('account');
|
||||
|
||||
assert.ok(serializer);
|
||||
});
|
||||
|
||||
test('it serializes records', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let record = store.createRecord('account', {});
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
<Rose::Form
|
||||
@onSubmit={{@submit}}
|
||||
@cancel={{@cancel}}
|
||||
@disabled={{@model.isSaving}}
|
||||
@error={{@model.errors.base}}
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name="password"
|
||||
@type="password"
|
||||
@value={{@model.attributes.password}}
|
||||
@label={{t "form.label.password"}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
autocomplete="new-password"
|
||||
as |field|>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@submitText={{t "actions.save"}}
|
||||
@cancelText={{t "actions.cancel"}} />
|
||||
|
||||
</Rose::Form>
|
||||
@@ -74,7 +74,9 @@ Router.map(function () {
|
||||
this.route('auth-methods', function() {
|
||||
this.route('auth-method', { path: ':auth_method_id' }, function() {
|
||||
this.route('accounts', function() {
|
||||
this.route('account', { path: ':account_id' }, function() {});
|
||||
this.route('account', { path: ':account_id' }, function() {
|
||||
this.route('settings');
|
||||
});
|
||||
this.route('new');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodAccountsAccountSettingsRoute extends Route {
|
||||
|
||||
// =services
|
||||
|
||||
@service intl;
|
||||
@service notify;
|
||||
|
||||
// =actions
|
||||
|
||||
/**
|
||||
* Save password for current account.
|
||||
* @param {AccountModel} account
|
||||
*/
|
||||
@action
|
||||
async savePassword(account) {
|
||||
try {
|
||||
await account.savePassword();
|
||||
await this.replaceWith('scopes.scope.auth-methods.auth-method.accounts.account.settings');
|
||||
this.notify.success(
|
||||
this.intl.t('notify.save-success')
|
||||
);
|
||||
} catch (error) {
|
||||
// TODO: replace with translated strings
|
||||
this.notify.error(error.message, { closeAfter: null });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to hosts as if nothing ever happened.
|
||||
*/
|
||||
@action
|
||||
cancel() {
|
||||
this.replaceWith('scopes.scope.auth-methods.auth-method.accounts.account');
|
||||
}
|
||||
}
|
||||
+3
@@ -2,4 +2,7 @@
|
||||
<nav.link @route='scopes.scope.auth-methods.auth-method.accounts.account.index'>
|
||||
{{t 'titles.details'}}
|
||||
</nav.link>
|
||||
<nav.link @route='scopes.scope.auth-methods.auth-method.accounts.account.settings'>
|
||||
{{t 'titles.settings'}}
|
||||
</nav.link>
|
||||
</Rose::Nav::Tabs>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<p>{{t 'descriptions.account-settings-overview'}}</p>
|
||||
|
||||
<Form::Account::Password::Settings
|
||||
@model={{@model}}
|
||||
@submit={{route-action "savePassword" @model}}
|
||||
@cancel={{route-action "cancel" @model}}
|
||||
/>
|
||||
@@ -63,11 +63,12 @@ export default function() {
|
||||
const method = idMethod.split(':')[1];
|
||||
const account = accounts.find(id);
|
||||
const updatedAttrs = {
|
||||
version: attrs.version
|
||||
version: attrs.version,
|
||||
attributes: {}
|
||||
};
|
||||
// Set new password
|
||||
if (method === 'set-password') {
|
||||
updatedAttrs.password = accounts.attributes.password;
|
||||
updatedAttrs.attributes.password = attrs.password;
|
||||
}
|
||||
return account.update(updatedAttrs);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Component | form/account/password/settings', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function(assert) {
|
||||
this.submit = () => {};
|
||||
this.cancel = () => {};
|
||||
this.model = { type: 'password' };
|
||||
|
||||
await render(hbs`
|
||||
<Form::Account::Password::Settings
|
||||
@model={{this.model}}
|
||||
@submit={{this.submit}}
|
||||
@cancel={{this.cancel}}
|
||||
/>`);
|
||||
|
||||
assert.ok(find('form'));
|
||||
});
|
||||
});
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Route | scopes/scope/auth-methods/auth-method/accounts/account/settings', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.owner.lookup('route:scopes/scope/auth-methods/auth-method/accounts/account/settings');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
@@ -133,6 +133,7 @@ descriptions:
|
||||
group-members-welcome: Users belonging to this group appear here.
|
||||
no-available-users: No users are available to add to this group.
|
||||
auth-method-accounts-welcome: No accounts are available in this auth method.
|
||||
account-settings-overview: Set the password for current account.
|
||||
states:
|
||||
info: Info
|
||||
success: Success
|
||||
|
||||
Reference in new issue
Block a user