forked from aptible/dashboard.aptible.com
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
User Settings SSH, profile and admin pages
* User can add/delete ssh keys (/settings/ssh) * User can change password, email (/settings/admin) * User can change name (/settings/profile) * Styles match dashboard * Customized ssh-key adapter's buildURL for DELETEs fixes aptible#66 fixes aptible#69
- Loading branch information
Showing
24 changed files
with
1,104 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import AuthAdapter from './auth'; | ||
import buildURLWithPrefixMap from '../utils/build-url-with-prefix-map'; | ||
import Ember from 'ember'; | ||
|
||
export default AuthAdapter.extend({ | ||
buildURL: buildURLWithPrefixMap({ | ||
'users': 'user.id' | ||
}), | ||
|
||
// To delete an ssh-key, the adapter should send a DELETE to /ssh_keys/:id, | ||
// but it POSTs to /users/:user_id/ssh_keys. | ||
// Override deleteRecord to remove the "/users/:user_id" from the | ||
// url for a DELETE. | ||
deleteRecord: function(store, type, record){ | ||
var id = Ember.get(record, 'id'); | ||
var userId = Ember.get(record, 'user.id'); | ||
|
||
var url = this.buildURL(type.typeKey, id, record); | ||
|
||
if (userId) { | ||
url = url.replace("/users/" + userId, ""); | ||
} | ||
|
||
return this.ajax(url, "DELETE"); | ||
}, | ||
|
||
// In URLs and JSON payloads, use "ssh_keys" instead of "sshKeys" | ||
pathForType: function(type){ | ||
return Ember.String.pluralize( Ember.String.decamelize(type) ); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import DS from 'ember-data'; | ||
|
||
export default DS.Model.extend({ | ||
name: DS.attr('string'), | ||
sshPublicKey: DS.attr('string'), | ||
publicKeyFingerprint: DS.attr('string'), | ||
|
||
user: DS.belongsTo('user', {async:true}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Ember from 'ember'; | ||
|
||
var and = Ember.computed.and; | ||
|
||
export default Ember.Controller.extend({ | ||
isSavingPassword: and('changingPassword', | ||
'session.currentUser.isSaving'), | ||
isSavingEmail: and('changingEmail', | ||
'session.currentUser.isSaving') | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import Ember from 'ember'; | ||
|
||
export default Ember.Route.extend({ | ||
actions: { | ||
changePassword: function(){ | ||
var controller = this.controller; | ||
|
||
// Changing password is a 2-step process. We show the | ||
// "enter current password" input after clicking the button once | ||
if (!controller.get('changingPassword')) { | ||
controller.set('changingPassword', true); | ||
return; | ||
} | ||
|
||
controller.set('passwordError', null); | ||
|
||
var user = this.session.get('currentUser'); | ||
user.save().then(function(){ | ||
controller.set('changingPassword', false); | ||
user.set('passwordConfirmation', null); | ||
user.set('currentPassword', null); | ||
|
||
// TODO this will leave the user in a dirty state. | ||
user.set('password', null); | ||
}).catch(function(e){ | ||
var message = e.responseJSON ? e.responseJSON.message : e.message; | ||
if (!message) { message = 'Unknown error'; } | ||
controller.set('passwordError',message); | ||
}); | ||
}, | ||
|
||
changeEmail: function(){ | ||
var controller = this.controller; | ||
|
||
// Changing email is a 2-step process. We show the | ||
// "enter current password" input after clicking the button once | ||
if (!controller.get('changingEmail')) { | ||
controller.set('changingEmail', true); | ||
return; | ||
} | ||
|
||
controller.set('emailError', null); | ||
|
||
var user = this.session.get('currentUser'); | ||
user.save().catch(function(e){ | ||
var message = e.responseJSON ? e.responseJSON.message : e.message; | ||
if (!message) { message = 'Unknown error'; } | ||
controller.set('emailError',message); | ||
}).finally(function(){ | ||
|
||
// Clears the current password input | ||
user.set('currentPassword', null); | ||
|
||
controller.set('changingEmail', false); | ||
}); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<div class="panel-group"> | ||
<div class="panel panel-default"> | ||
<div class="panel-heading"><h3>Change Your Password</h3></div> | ||
<div class="panel-body"> | ||
{{#if passwordError}} | ||
<div class="alert alert-warning"> | ||
{{passwordError}} | ||
</div> | ||
{{/if}} | ||
<form action=""> | ||
<div class="form-group"> | ||
<label for="password">New password</label> | ||
{{input type="password" | ||
class="form-control" placholder="New password" | ||
value=session.currentUser.password name="password"}} | ||
</div> | ||
<div class="form-group"> | ||
<label for="confirm-password">Confirm new password</label> | ||
{{input type="password" | ||
class="form-control" placholder="New password" | ||
value=session.currentUser.passwordConfirmation | ||
name="confirm-password"}} | ||
</div> | ||
{{#if changingPassword}} | ||
<div class="form-group"> | ||
<label for="current-password">Current password</label> | ||
{{input type="password" | ||
class="form-control" placholder="Current password" | ||
value=session.currentUser.currentPassword | ||
name="current-password"}} | ||
</div> | ||
{{/if}} | ||
<div class="form-group"> | ||
<button {{action 'changePassword'}} | ||
{{bind-attr disabled=session.currentUser.isSaving}} | ||
class="btn btn-primary" type="submit"> | ||
|
||
{{#if isSavingPassword}} | ||
Saving | ||
{{else}} | ||
Change password | ||
{{/if}} | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
<div class="panel panel-default"> | ||
<div class="panel-heading"><h3>Change Your Email</h3></div> | ||
<div class="panel-body"> | ||
{{#if emailError}} | ||
<div class="alert alert-warning"> | ||
{{emailError}} | ||
</div> | ||
{{/if}} | ||
<form> | ||
<div class="form-group"> | ||
<label for="email">Email</label> | ||
{{input type="email" | ||
class="form-control" placeholder="Email" | ||
value=session.currentUser.email name="email"}} | ||
</div> | ||
{{#if changingEmail}} | ||
<div class="form-group"> | ||
<label for="password">Please enter your current password</label> | ||
{{input type="password" | ||
class="form-control" placeholder="Current password" | ||
value=session.currentUser.currentPassword | ||
name="current-password"}} | ||
</div> | ||
{{/if}} | ||
<div class="form-group"> | ||
<button {{action 'changeEmail'}} class="btn btn-primary" type="submit"> | ||
{{#if isSavingEmail}} | ||
Saving | ||
{{else}} | ||
Change email | ||
{{/if}} | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import Ember from 'ember'; | ||
|
||
export default Ember.Route.extend({ | ||
redirect: function(){ | ||
this.replaceWith('settings.profile'); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import Ember from 'ember'; | ||
|
||
export default Ember.Route.extend({ | ||
setupController: function(controller){ | ||
var user = this.session.get('currentUser'); | ||
|
||
controller.set('userName', user.get('name')); | ||
}, | ||
|
||
actions: { | ||
submit: function(newName){ | ||
var user = this.session.get('currentUser'); | ||
user.set('name', newName); | ||
user.save(); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<div class="panel-group"> | ||
<div class="panel panel-default"> | ||
<div class="panel-heading"><h3>Your Profile</h3></div> | ||
<div class="panel-body"> | ||
<form action=""> | ||
<div class="form-group clearfix update-gravatar"> | ||
<label class="block">Profile Picture</label> | ||
<div class="gravatar lg"> | ||
{{gravatar-image email=session.currentUser.email}} | ||
</div> | ||
|
||
<div class="input-group update-gravatar-info"> | ||
<h5> | ||
Use <a href="https://en.gravatar.com/">Gravatar</a> to update your profile picture. | ||
</h5> | ||
<h6> | ||
Your gravatar email is <strong class='email'>{{session.currentUser.email}}</strong> | ||
</h6> | ||
<div> | ||
<a class="btn btn-xs btn-default" href="https://en.gravatar.com/" target="_blank">Change</a> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group"> | ||
<label for="name">Name</label> | ||
|
||
{{input value=userName name="name" class="form-control"}} | ||
</div> | ||
|
||
<div class="form-group"> | ||
<button {{action "submit" userName}} | ||
{{bind-attr disabled=session.currentUser.isSaving}} | ||
class="btn btn-primary" type="submit"> | ||
{{#if session.currentUser.isSaving}} | ||
Saving | ||
{{else}} | ||
Update profile | ||
{{/if}} | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import Ember from 'ember'; | ||
|
||
export default Ember.Controller.extend({ | ||
error: null, | ||
newKey: null, | ||
|
||
// do not show the key that the user is in the progress of creating | ||
validKeys: function(){ | ||
return this.get('model').filter(function(key){ | ||
return key.get('isLoaded') && !key.get('isDirty'); | ||
}); | ||
}.property('[email protected]', '[email protected]') | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import Ember from 'ember'; | ||
|
||
export default Ember.Route.extend({ | ||
model: function(){ | ||
var user = this.session.get('currentUser'); | ||
|
||
return user.get('sshKeys'); | ||
}, | ||
|
||
setupController: function(controller, model){ | ||
controller.set('model', model); | ||
}, | ||
|
||
actions: { | ||
addKey: function(){ | ||
this.controller.set('newKey', this.store.createRecord('ssh-key', { | ||
user: this.session.get('currentUser') | ||
})); | ||
}, | ||
|
||
cancelSaveKey: function(){ | ||
this.controller.get('newKey').deleteRecord(); | ||
this.controller.set('newKey', null); | ||
this.controller.set('error', null); | ||
}, | ||
|
||
saveKey: function(){ | ||
var controller = this.controller; | ||
|
||
if (controller.get('newKey.isSaving')) { return; } | ||
|
||
var key = this.controller.get('newKey'); | ||
|
||
key.save().then(function(){ | ||
controller.set('error', null); // clear error | ||
controller.set('newKey', null); // clear key | ||
}).catch(function(e){ | ||
controller.set('error', e.message); | ||
}); | ||
}, | ||
|
||
deleteKey: function(key){ | ||
var controller = this.controller; | ||
|
||
key.destroyRecord().then(function(){ | ||
controller.set('error', null); | ||
}).catch(function(){ | ||
controller.set('error', 'There was an error deleting this key.'); | ||
key.rollback(); | ||
}); | ||
} | ||
} | ||
}); |
Oops, something went wrong.