Settings: Admin User Tab

closes #2422

- updated to use new change password method
- have all save settings use notifications
- create assetUrl helper for creating asset paths with subdir's properly
 prefixed
- move all url based helpers onto a url object in ghost-paths
This commit is contained in:
Harry Wolff 2014-07-13 00:01:26 -04:00
parent 0122ecd593
commit 45ccad58f9
11 changed files with 96 additions and 67 deletions

View File

@ -2,7 +2,7 @@ var DebugController = Ember.Controller.extend(Ember.Evented, {
uploadButtonText: 'Import',
exportPath: function () {
return this.get('ghostPaths').apiUrl('db') +
return this.get('ghostPaths.url').api('db') +
'?access_token=' + this.get('session.access_token');
}.property(),
@ -15,7 +15,7 @@ var DebugController = Ember.Controller.extend(Ember.Evented, {
formData.append('importfile', file);
ic.ajax.request(this.get('ghostPaths').apiUrl('db'), {
ic.ajax.request(this.get('ghostPaths.url').api('db'), {
type: 'POST',
data: formData,
dataType: 'json',
@ -35,7 +35,7 @@ var DebugController = Ember.Controller.extend(Ember.Evented, {
exportData: function () {
var self = this;
ic.ajax.request(this.get('ghostPaths').apiUrl('db'), {
ic.ajax.request(this.get('ghostPaths.url').api('db'), {
type: 'GET'
}).then(function () {
self.notifications.showSuccess('Data exported successfully.');
@ -47,7 +47,7 @@ var DebugController = Ember.Controller.extend(Ember.Evented, {
sendTestEmail: function () {
var self = this;
ic.ajax.request(this.get('ghostPaths').apiUrl('mail', 'test'), {
ic.ajax.request(this.get('ghostPaths.url').api('mail', 'test'), {
type: 'POST'
}).then(function () {
self.notifications.showSuccess('Check your email for the test message:');

View File

@ -17,7 +17,7 @@ var ForgottenController = Ember.Controller.extend(ValidationEngine, {
this.toggleProperty('submitting');
this.validate({ format: false }).then(function () {
ajax({
url: self.get('ghostPaths').apiUrl('authentication', 'passwordreset'),
url: self.get('ghostPaths.url').api('authentication', 'passwordreset'),
type: 'POST',
data: {
passwordreset: [{

View File

@ -3,7 +3,7 @@ var DeleteAllController = Ember.Controller.extend({
confirmAccept: function () {
var self = this;
ic.ajax.request(this.get('ghostPaths').apiUrl('db'), {
ic.ajax.request(this.get('ghostPaths.url').api('db'), {
type: 'DELETE'
}).then(function () {
self.notifications.showSuccess('All content deleted from database.');

View File

@ -21,7 +21,7 @@ var ResetController = Ember.Controller.extend(ValidationEngine, {
this.toggleProperty('submitting');
this.validate({format: false}).then(function () {
ajax({
url: self.get('ghostPaths').apiUrl('authentication', 'passwordreset'),
url: self.get('ghostPaths.url').api('authentication', 'passwordreset'),
type: 'PUT',
data: {
passwordreset: [{

View File

@ -1,14 +1,18 @@
/*global alert */
var SettingsUserController = Ember.ObjectController.extend({
user: Ember.computed.alias('model'),
email: Ember.computed.readOnly('user.email'),
coverDefault: '/shared/img/user-cover.png',
coverDefault: function () {
return this.get('ghostPaths.url').asset('/shared/img/user-cover.png');
}.property('ghostPaths'),
userDefault: function () {
return this.get('ghostPaths.url').asset('/shared/img/user-image.png');
}.property('ghostPaths'),
cover: function () {
// @TODO: add {{asset}} subdir path
var cover = this.get('user.cover');
if (typeof cover !== 'string') {
cover = this.get('coverDefault');
@ -21,13 +25,11 @@ var SettingsUserController = Ember.ObjectController.extend({
}.property('user.name'),
image: function () {
// @TODO: add {{asset}} subdir path
return 'background-image: url(' + this.getWithDefault('user.image', '/shared/img/user-image.png') + ')';
}.property('user.image'),
return 'background-image: url(' + this.get('imageUrl') + ')';
}.property('imageUrl'),
imageUrl: function () {
// @TODO: add {{asset}} subdir path
return this.getWithDefault('user.image', '/shared/img/user-image.png');
return this.get('user.image') || this.get('userDefault');
}.property('user.image'),
last_login: function () {
@ -70,38 +72,45 @@ var SettingsUserController = Ember.ObjectController.extend({
self.notifications.closePassive();
alert('@TODO: Saving user...');
user.validate({format: false}).then(function () {
user.save().then(function (model) {
self.notifications.closePassive();
self.notifications.showSuccess('Settings successfully saved.');
if (user.validate().get('isValid')) {
user.save().then(function (response) {
alert('Done saving' + JSON.stringify(response));
}, function () {
alert('Error saving.');
return model;
}).catch(function (errors) {
self.notifications.closePassive();
self.notifications.showErrors(errors);
});
} else {
alert('Errors found! ' + JSON.stringify(user.get('errors')));
}
}, function (errors) {
self.notifications.showErrors(errors);
});
},
password: function () {
alert('@TODO: Changing password...');
var user = this.get('user'),
passwordProperties = this.getProperties('password', 'newPassword', 'ne2Password');
self = this;
if (user.get('isPasswordValid')) {
user.saveNewPassword().then(function (model) {
if (user.validatePassword(passwordProperties).get('passwordIsValid')) {
user.saveNewPassword(passwordProperties).then(function () {
alert('Success!');
// Clear properties from view
this.setProperties({
user.setProperties({
'password': '',
'newpassword': '',
'ne2password': ''
'newPassword': '',
'ne2Password': ''
});
}.bind(this), function (errors) {
alert('Errors ' + JSON.stringify(errors));
self.notifications.closePassive();
self.notifications.showSuccess('Password updated.');
return model;
}).catch(function (errors) {
self.notifications.closePassive();
self.notifications.showAPIError(errors);
});
} else {
alert('Errors found! ' + JSON.stringify(user.get('passwordErrors')));
self.notifications.showErrors(user.get('passwordValidationErrors'));
}
}
}

View File

@ -21,7 +21,7 @@ var SetupController = Ember.ObjectController.extend(ValidationEngine, {
this.toggleProperty('submitting');
this.validate({ format: false }).then(function () {
ajax({
url: self.get('ghostPaths').apiUrl('authentication', 'setup'),
url: self.get('ghostPaths.url').api('authentication', 'setup'),
type: 'POST',
data: {
setup: [{

View File

@ -21,7 +21,7 @@ var SignupController = Ember.ObjectController.extend(ValidationEngine, {
this.toggleProperty('submitting');
this.validate({ format: false }).then(function () {
ajax({
url: self.get('ghostPaths').apiUrl('authentication', 'invitation'),
url: self.get('ghostPaths.url').api('authentication', 'invitation'),
type: 'POST',
dataType: 'json',
data: {

View File

@ -12,7 +12,7 @@ var SlugGenerator = Ember.Object.extend({
return Ember.RSVP.resolve('');
}
url = this.get('ghostPaths').apiUrl('slugs', 'post', encodeURIComponent(textToSlugify));
url = this.get('ghostPaths.url').api('slugs', 'post', encodeURIComponent(textToSlugify));
return ic.ajax.request(url, {
type: 'GET'

View File

@ -6,7 +6,6 @@ var User = DS.Model.extend(NProgressSaveMixin, ValidationEngine, {
uuid: DS.attr('string'),
name: DS.attr('string'),
slug: DS.attr('string'),
password: DS.attr('string'),
email: DS.attr('string'),
image: DS.attr('string'),
cover: DS.attr('string'),
@ -24,11 +23,17 @@ var User = DS.Model.extend(NProgressSaveMixin, ValidationEngine, {
updated_at: DS.attr('moment-date'),
updated_by: DS.attr('number'),
saveNewPassword: function (password) {
var url = this.get('ghostPaths').adminUrl('changepw');
saveNewPassword: function () {
var url = this.get('ghostPaths.url').api('users', 'password');
return ic.ajax.request(url, {
type: 'POST',
data: password
type: 'PUT',
data: {
password: [{
'oldPassword': this.get('password'),
'newPassword': this.get('newPassword'),
'ne2Password': this.get('ne2Password')
}]
}
});
},
@ -37,26 +42,28 @@ var User = DS.Model.extend(NProgressSaveMixin, ValidationEngine, {
userData.email = this.get('email');
return ic.ajax.request(this.get('ghostPaths').apiUrl('users'), {
return ic.ajax.request(this.get('ghostPaths.url').api('users'), {
type: 'POST',
data: JSON.stringify({users: [userData]}),
contentType: 'application/json'
});
},
passwordValidationErrors: function (password) {
passwordValidationErrors: function () {
var validationErrors = [];
if (!validator.equals(password.newPassword, password.ne2Password)) {
validationErrors.push('Your new passwords do not match');
if (!validator.equals(this.get('newPassword'), this.get('ne2Password'))) {
validationErrors.push({message: 'Your new passwords do not match'});
}
if (!validator.isLength(password.newPassword, 8)) {
validationErrors.push('Your password is not long enough. It must be at least 8 characters long.');
if (!validator.isLength(this.get('newPassword'), 8)) {
validationErrors.push({message: 'Your password is not long enough. It must be at least 8 characters long.'});
}
return validationErrors;
}
}.property('password', 'newPassword', 'ne2Password'),
isPasswordValid: Ember.computed.empty('passwordValidationErrors.[]')
});

View File

@ -3,14 +3,15 @@
<h2 class="hidden">Your Profile</h2>
<div class="settings-header-inner">
<button class="button-back">Back</button>
<button class="button-back">Back</button>
<section class="page-actions page-actions-alt">
{{#link-to "settings.users" class="button has-icon users-back" tagName="button"}}<i class="icon-chevron-left"></i>Users{{/link-to}}
</section>
<section class="page-actions">
{{!-- {{#gh-popover-button popoverName="user-actions-menu" tagName="a" classNames="button only-has-icon user-actions-cog" title="User Actions"}}
<i class="icon-settings"></i>
<span class="hidden">User Settings</span>
@ -108,17 +109,17 @@
<div class="form-group">
<label for="user-password-old">Old Password</label>
{{input value=password type="password" id="user-password-old"}}
{{input value=user.password type="password" id="user-password-old"}}
</div>
<div class="form-group">
<label for="user-password-new">New Password</label>
{{input value=newPassword type="password" id="user-password-new"}}
{{input value=user.newPassword type="password" id="user-password-new"}}
</div>
<div class="form-group">
<label for="user-new-password-verification">Verify Password</label>
{{input value=ne2Password type="password" id="user-new-password-verification"}}
{{input value=user.ne2Password type="password" id="user-new-password-verification"}}
</div>
<div class="form-group">
<button type="button" class="button-delete button-change-password" {{action "password"}}>Change Password</button>

View File

@ -9,25 +9,37 @@ var makeRoute = function (root, args) {
return route;
};
function ghostPaths() {
var path = window.location.pathname,
subdir = path.substr(0, path.search('/ghost/'));
subdir = path.substr(0, path.search('/ghost/')),
adminRoot = subdir + '/ghost',
apiRoot = subdir + '/ghost/api/v0.1';
function assetUrl(src) {
return subdir + src;
}
return {
subdir: subdir,
blogRoot: subdir + '/',
adminRoot: subdir + '/ghost',
apiRoot: subdir + '/ghost/api/v0.1',
userImage: subdir + '/assets/img/user-image.png',
errorImageSrc: subdir + '/ghost/img/404-ghost@2x.png',
errorImageSrcSet: subdir + '/ghost/img/404-ghost.png 1x, ' + subdir + '/ghost/img/404-ghost@2x.png 2x',
adminRoot: adminRoot,
apiRoot: apiRoot,
userImage: assetUrl('/assets/img/user-image.png'),
errorImageSrc: assetUrl('/ghost/img/404-ghost@2x.png'),
errorImageSrcSet: assetUrl('/ghost/img/404-ghost.png') + ' 1x, ' +
assetUrl('/ghost/img/404-ghost@2x.png') + ' 2x',
adminUrl: function () {
return makeRoute(this.adminRoot, arguments);
},
url: {
admin: function () {
return makeRoute(adminRoot, arguments);
},
apiUrl: function () {
return makeRoute(this.apiRoot, arguments);
api: function () {
return makeRoute(apiRoot, arguments);
},
asset: assetUrl
}
};
}