commit:476c970903c4f3d29a8da3fa7c6f6f237745a8b7
author:Chip Black
committer:Chip Black
date:Thu Feb 26 03:55:59 2015 -0600
parents:8955f58c951da1402f5eb76bc2a7982548e970f4
Add new account center and account recovery frontends
diff --git a/www/css/blerg.css b/www/css/blerg.css
line changes: +26/-2
index ae67fcb..14dc591
--- a/www/css/blerg.css
+++ b/www/css/blerg.css
@@ -167,7 +167,11 @@ h1, h2, h3 {
 }
 
 .blerg-main h2 {
-	margin: 8pt 0;
+	margin: 40px 0 10px 0;
+}
+
+.blerg-main h2:first-child {
+    margin: 0 0 10px 0;
 }
 
 .blerg-post {
@@ -490,7 +494,8 @@ h1, h2, h3 {
 	margin: 0;
 }
 
-.blerg-dialog .onyx-groupbox {
+.blerg-dialog .onyx-groupbox,
+.blerg-form .onyx-groupbox {
 	margin: 8px 0;
 }
 
@@ -514,6 +519,25 @@ h1, h2, h3 {
 	font-weight: bold;
 }
 
+.onyx-input-decorator.recovery {
+    min-height: 22px;
+    vertical-align: top;
+    margin-right: 1em;
+}
+
+.onyx-button.recovery {
+    background-color: orange;
+    font-size: 16px;
+    font-weight: bold;
+    min-height: 40px;
+}
+
+p.recovery {
+    background-color: orange;
+    font-size: 20px;
+    padding: 6px;
+}
+
 table.help td {
 	padding: 2pt 8pt;
 }

diff --git a/www/jssrc/blerg/AccountCenter.js b/www/jssrc/blerg/AccountCenter.js
line changes: +51/-0
index 0000000..80db769
--- /dev/null
+++ b/www/jssrc/blerg/AccountCenter.js
@@ -0,0 +1,51 @@
+enyo.kind({
+    name: "blerg.AccountCenter",
+    components: [
+        {tag: 'h2', content: "Change Password"},
+        {kind: "blerg.PasswdForm"},
+        {tag: 'h2', content: "Generate recovery link"},
+        {content: "A recovery link is a URL that will allow you to reset the password on your account. Whoever has this link will be able to gain control of your account. This link should be kept in a safe place like an encrypted password manager or a physical piece of paper locked in a safe. The link will expire after one year or the next password change (either via a recovery link or by changing it manually above). To indicate that you understand this, please copy <code>blërg</code> into the textbox below.", tag: 'p', allowHtml: true},
+        {tag: 'p', components: [
+            {kind: 'onyx.InputDecorator', classes: "recovery", components: [
+                {kind: 'onyx.Input', name: "recoveryVerifier"}
+            ]},
+            {kind: 'onyx.Button', content: "Generate", classes: "recovery", onclick: "generateRecoveryLink"}
+        ]},
+        {tag: 'p', name: 'recoveryLinkOutput', classes: 'recovery'}
+    ],
+    statics: {
+        locationDetect: function(l) {
+            var m = l.hash.match(/^#\/account$/);
+            if (m) {
+                return {
+                    kind: 'blerg.AccountCenter'
+                };
+            }
+        }
+    },
+    create: function() {
+        this.inherited(arguments);
+        this.bubble('onSetTitle', {section: 'Account Center'});
+    },
+    generateRecoveryLink: function(inSender, inEvent) {
+        if (this.$.recoveryVerifier.getValue() != 'blërg') {
+            this.$.recoveryLinkOutput.setContent('Please read the text above');
+            return;
+        }
+
+        var req = new enyo.Ajax({
+            url: '/aux/recovery/new',
+            handleAs: 'text'
+        });
+
+        req.response(this, function(inSender, inResponse) {
+            this.$.recoveryLinkOutput.setContent(inResponse);
+        });
+
+        req.error(this, function(inSender, inResponse) {
+            this.$.recoveryLinkOutput.setContent('Failed: ' + req.xhrResponse.status);
+        });
+
+        req.go();
+    }
+});

diff --git a/www/jssrc/blerg/Blerg.js b/www/jssrc/blerg/Blerg.js
line changes: +1/-1
index 80037c4..4a95114
--- a/www/jssrc/blerg/Blerg.js
+++ b/www/jssrc/blerg/Blerg.js
@@ -5,7 +5,7 @@ enyo.kind({
     name: "blerg.Blerg",
     kind: "Control",
     lastHash: null,
-    pathHandlers: [ blerg.User, blerg.Tag, blerg.Feed, blerg.ExternalURLPost, blerg.Welcome ],
+    pathHandlers: [ blerg.User, blerg.Tag, blerg.Feed, blerg.ExternalURLPost, blerg.Welcome, blerg.AccountCenter, blerg.Recovery ],
     handlers: {
         onStartSignup: "showSignupDialog",
         onTryLogin: "tryLogin",

diff --git a/www/jssrc/blerg/Controls.js b/www/jssrc/blerg/Controls.js
line changes: +1/-1
index eb3275c..abd43ea
--- a/www/jssrc/blerg/Controls.js
+++ b/www/jssrc/blerg/Controls.js
@@ -34,7 +34,7 @@ enyo.kind({
                 {kind: "blerg.Link", content: "Logout", onNavigate: "logoutClicked"},
                 {tag: null, content: "."},
                 {tag: "br"},
-                {kind: "blerg.Link", content: "Change Password", onNavigate: "changePasswordClicked"},
+                {kind: "blerg.Link", content: "Account Center", href: '/#/account'},
                 {tag: null, content: "."}
             ]},
             {classes: "blerg-controls-toolbar", components: [

diff --git a/www/jssrc/blerg/PasswdDialog.js b/www/jssrc/blerg/PasswdDialog.js
line changes: +0/-72
index 449ef37..0000000
--- a/www/jssrc/blerg/PasswdDialog.js
+++ /dev/null
@@ -1,72 +0,0 @@
-enyo.kind({
-    name: "blerg.PasswdDialog",
-    kind: "onyx.Popup",
-    classes: "blerg-dialog",
-    autoDismiss: true,
-    centered: true,
-    floating: true,
-    modal: true,
-    components: [
-        {tag: "h2", content: "Change Password"},
-        {name: "spinner", kind: "OldSchoolSpinner", showing: false, style: "position: absolute; top: 8px; right: 8px;"},
-        {kind: "onyx.Groupbox", components: [
-            {kind: "onyx.InputDecorator", components: [
-                {name: "oldpassword", kind: "onyx.Input", placeholder: "Old Password", type: "password"}
-            ]}
-        ]},
-        {kind: "onyx.Groupbox", components: [
-            {kind: "onyx.InputDecorator", components: [
-                {name: "password1", kind: "onyx.Input", placeholder: "New Password", type: "password"}
-            ]},
-            {kind: "onyx.InputDecorator", components: [
-                {name: "password2", kind: "onyx.Input", placeholder: "New Password (again)", type: "password"}
-            ]}
-        ]},
-        {name: "changePasswordError", tag: "p", showing: false, classes: "blerg-error", content: "I couldn't change your password. Are you sure you have the right old password?"},
-        {name: "passwordMatchError", tag: "p", showing: false, classes: "blerg-error", content: "Your new passwords don't match."},
-        {name: "changeButton", kind: "onyx.Button", content: "Change", onclick: "changeClick", classes: "onyx.affirmative"},
-        {kind: "onyx.Button", content: "Cancel", onclick: "cancelClick", classes: "onyx-negative"},
-        {name: "api", kind: "blerg.API",
-         onPasswordChangeSuccessful: "passwordChangeSuccessful",
-         onPasswordChangeFailed: "passwordChangeFailed"}
-    ],
-    hideErrors: function() {
-        this.$.changePasswordError.hide();
-        this.$.passwordMatchError.hide();
-    },
-    changeClick: function() {
-        this.hideErrors();
-        if (this.$.oldpassword.getValue() == '') {
-            this.$.changePasswordError.show();
-            return;
-        }
-        if (this.$.password1.getValue() != this.$.password2.getValue()) {
-            this.$.passwordMatchError.show();
-            return;
-        }
-        this.$.changeButton.setDisabled(true);
-        this.$.spinner.show();
-        this.$.spinner.start();
-        this.$.api.changePassword(this.$.oldpassword.getValue(), this.$.password1.getValue());
-    },
-    cancelClick: function() {
-        this.hide();
-    },
-    passwordChangeSuccessful: function(inSender, inEvent) {
-        this.$.oldpassword.setValue('');
-        this.$.password1.setValue('');
-        this.$.password2.setValue('');
-        this.$.changeButton.setDisabled(false);
-        this.$.spinner.hide();
-        this.$.spinner.stop();
-        this.cancelClick();
-        alert("Password Changed Successfully");
-    },
-    passwordChangeFailed: function(inSender, inEvent) {
-        this.$.changeButton.setDisabled(false);
-        this.$.spinner.hide();
-        this.$.spinner.stop();
-        this.hideErrors();
-        this.$.changePasswordError.show();
-    }
-});

diff --git a/www/jssrc/blerg/PasswdForm.js b/www/jssrc/blerg/PasswdForm.js
line changes: +61/-0
index 0000000..39ec889
--- /dev/null
+++ b/www/jssrc/blerg/PasswdForm.js
@@ -0,0 +1,61 @@
+enyo.kind({
+    name: "blerg.PasswdForm",
+    classes: "blerg-form",
+    components: [
+        {kind: "onyx.Groupbox", components: [
+            {kind: "onyx.InputDecorator", components: [
+                {name: "oldpassword", kind: "onyx.Input", placeholder: "Old Password", type: "password"}
+            ]}
+        ]},
+        {kind: "onyx.Groupbox", components: [
+            {kind: "onyx.InputDecorator", components: [
+                {name: "password1", kind: "onyx.Input", placeholder: "New Password", type: "password"}
+            ]},
+            {kind: "onyx.InputDecorator", components: [
+                {name: "password2", kind: "onyx.Input", placeholder: "New Password (again)", type: "password"}
+            ]}
+        ]},
+        {name: "changePasswordError", tag: "p", showing: false, classes: "blerg-error", content: "I couldn't change your password. Are you sure you have the right old password?"},
+        {name: "passwordMatchError", tag: "p", showing: false, classes: "blerg-error", content: "Your new passwords don't match."},
+        {name: "changeButton", kind: "onyx.Button", content: "Change", onclick: "changeClick", classes: "onyx.affirmative"},
+        {name: "spinner", kind: "OldSchoolSpinner", showing: false},
+        {name: "api", kind: "blerg.API",
+         onPasswordChangeSuccessful: "passwordChangeSuccessful",
+         onPasswordChangeFailed: "passwordChangeFailed"}
+    ],
+    hideErrors: function() {
+        this.$.changePasswordError.hide();
+        this.$.passwordMatchError.hide();
+    },
+    changeClick: function() {
+        this.hideErrors();
+        if (this.$.oldpassword.getValue() == '') {
+            this.$.changePasswordError.show();
+            return;
+        }
+        if (this.$.password1.getValue() != this.$.password2.getValue()) {
+            this.$.passwordMatchError.show();
+            return;
+        }
+        this.$.changeButton.setDisabled(true);
+        this.$.spinner.show();
+        this.$.spinner.start();
+        this.$.api.changePassword(this.$.oldpassword.getValue(), this.$.password1.getValue());
+    },
+    passwordChangeSuccessful: function(inSender, inEvent) {
+        this.$.oldpassword.setValue('');
+        this.$.password1.setValue('');
+        this.$.password2.setValue('');
+        this.$.changeButton.setDisabled(false);
+        this.$.spinner.hide();
+        this.$.spinner.stop();
+        alert("Password Changed Successfully");
+    },
+    passwordChangeFailed: function(inSender, inEvent) {
+        this.$.changeButton.setDisabled(false);
+        this.$.spinner.hide();
+        this.$.spinner.stop();
+        this.hideErrors();
+        this.$.changePasswordError.show();
+    }
+});

diff --git a/www/jssrc/blerg/Recovery.js b/www/jssrc/blerg/Recovery.js
line changes: +57/-0
index 0000000..c3efbad
--- /dev/null
+++ b/www/jssrc/blerg/Recovery.js
@@ -0,0 +1,57 @@
+enyo.kind({
+    name: "blerg.Recovery",
+    components: [
+        {tag: 'h2', content: "Reset Your Password"},
+        {tag: 'p', components: [
+            {kind: 'onyx.InputDecorator', classes: "recovery", components: [
+                {kind: 'onyx.Input', name: "newPassword"}
+            ]},
+            {kind: 'onyx.Button', content: "Set", onclick: "submitRecovery", classes: "recovery"}
+        ]}
+    ],
+    statics: {
+        locationDetect: function(l) {
+            var m = l.hash.match(/^#\/recovery\//);
+            if (m) {
+                return {
+                    kind: 'blerg.Recovery'
+                };
+            }
+        }
+    },
+    create: function() {
+        this.inherited(arguments);
+        this.bubble('onSetTitle', {section: 'Reset Password'});
+    },
+    submitRecovery: function(inSender, inEvent) {
+        var m = location.hash.match(new RegExp('^#/recovery/(.*)$'));
+        if (!m) {
+            alert('Validation failed');
+            return;
+        }
+
+        var req = new enyo.Ajax({
+            url: '/aux/recovery/validate',
+            method: 'POST',
+            postBody: {
+                data: m[1],
+                password: this.$.newPassword.getValue()
+            }
+        });
+
+        req.response(this, function(inSender, inResponse) {
+            if (inResponse.status == 'success') {
+                alert('Password changed successfully');
+                location = '/';
+            } else {
+                alert('Password change failed');
+            }
+        });
+
+        req.error(this, function(inSender, inResponse) {
+            alert('Password change failed');
+        });
+
+        req.go();
+    }
+});

diff --git a/www/jssrc/blerg/Title.js b/www/jssrc/blerg/Title.js
line changes: +2/-1
index 17d62a2..27356d8
--- a/www/jssrc/blerg/Title.js
+++ b/www/jssrc/blerg/Title.js
@@ -9,7 +9,7 @@ enyo.kind({
         onSetTitle: "setTitle"
     },
     components: [
-        {kind: "Image", classes: "logo", src: "images/blerglogo.png", attributes: {width: 125, height: 122}},
+        {kind: "Image", classes: "logo", src: "/images/blerglogo.png", attributes: {width: 125, height: 122}},
         {tag: "h1", components: [
             {kind: "blerg.Link", href: "/#/", content: "Blërg!"}
         ]},
@@ -19,6 +19,7 @@ enyo.kind({
     ],
     create: function() {
         this.inherited(arguments);
+        this.sectionChanged();
     },
     sectionChanged: function() {
         this.$.section.setContent(this.section);

diff --git a/www/jssrc/blerg/package.js b/www/jssrc/blerg/package.js
line changes: +3/-1
index 3192d42..8ebe123
--- a/www/jssrc/blerg/package.js
+++ b/www/jssrc/blerg/package.js
@@ -9,12 +9,14 @@ enyo.depends(
     'Help.js',
     'Main.js',
     'SignupDialog.js',
-    'PasswdDialog.js',
+    'PasswdForm.js',
     'Welcome.js',
     'Pager.js',
     'User.js',
     'Tag.js',
     'Feed.js',
+    'AccountCenter.js',
+    'Recovery.js',
     'ExternalURLPost.js',
     'Blerg.js'
 );