Modified yubifields in forms to show the OTP prefix; modified some strings
authorDan
Fri, 18 Dec 2009 19:29:33 -0500
changeset 35 03d6287d4a8b
parent 34 6e947fa21237
child 36 f2aa4bc50d2f
Modified yubifields in forms to show the OTP prefix; modified some strings
plugins/Yubikey.php
plugins/yubikey/corelib.php
plugins/yubikey/usercp.php
plugins/yubikey/yubikey.css
plugins/yubikey/yubikey.js
--- a/plugins/Yubikey.php	Fri Dec 18 19:28:57 2009 -0500
+++ b/plugins/Yubikey.php	Fri Dec 18 19:29:33 2009 -0500
@@ -5,7 +5,7 @@
   "Plugin URI"   : "http://enanocms.org/plugin/yubikey",
   "Description"  : "Allows authentication to Enano via Yubico's Yubikey, a one-time password device.",
   "Author"       : "Dan Fuhry",
-  "Version"      : "1.1.6",
+  "Version"      : "1.1.7",
   "Author URI"   : "http://enanocms.org/",
   "Auth plugin"  : true
 }
@@ -147,11 +147,11 @@
         field_keys_title: 'Enrolled Yubikeys:',
         field_keys_hint: 'Enroll a Yubikey to allow it to log into your account.',
         field_keys_maximum: 'You can enroll up to %max% Yubikeys.',
-        field_normal_flags: 'When logging in:',
-        field_elev_flags: 'When performing sensitive operations:',
-        field_flags_keyonly: 'Only require my Yubikey',
-        field_flags_username: 'Require a username',
-        field_flags_userandpw: 'Require a username and password',
+        field_normal_flags: 'When logging in, ask me for:',
+        field_elev_flags: 'When performing sensitive operations, require:',
+        field_flags_keyonly: 'Just my Yubikey',
+        field_flags_username: 'My Yubikey and username',
+        field_flags_userandpw: 'My <acronym title="Two factor authentication">Yubikey, username and password</acronym>',
         field_allow_plain_login: 'Allow me to log in without my Yubikey',
         field_allow_plain_login_hint: 'If this option is turned off, you will be unable to access your account if all of your enrolled Yubikeys become lost or broken. However, turning this option off provides greater security.',
         err_double_enrollment: 'One of the Yubikeys you tried to enroll is already enrolled on another account on this website. A single Yubikey can only be associated with one account at a time.',
--- a/plugins/yubikey/corelib.php	Fri Dec 18 19:28:57 2009 -0500
+++ b/plugins/yubikey/corelib.php	Fri Dec 18 19:29:33 2009 -0500
@@ -28,6 +28,12 @@
     $atext = $lang->get('yubiauth_ctl_btn_enroll');
     $classadd = '';
   }
+  
+  $html .= ' <span class="yubikey_pubkey">';
+  if ( !empty($value) )
+    $html .= htmlspecialchars(substr($value, 0, 12));
+  $html .= '</span> ';
+  
   $html .= ' <a class="abutton' . $classadd . ' yubikey_enroll" onclick="yk_mb_init(\'yubifield' . $fid . '\', \'yubistat' . $fid . '\'); return false;" href="#enroll">' . $atext . '</a>';
   if ( $value )
   {
@@ -35,6 +41,7 @@
              . $lang->get('yubiauth_ctl_btn_clear') .
              '</a>';
   }
+  
   return $html;
 }
 
--- a/plugins/yubikey/usercp.php	Fri Dec 18 19:28:57 2009 -0500
+++ b/plugins/yubikey/usercp.php	Fri Dec 18 19:29:33 2009 -0500
@@ -105,12 +105,33 @@
       $db->_die();
     list($password_hmac) = $db->fetchrow_num();
     
-    $session->register_session($session->user_id, $session->username, $password_hmac, USER_LEVEL_MEMBER, false);
+    @$session->register_session($session->user_id, $session->username, $password_hmac, USER_LEVEL_MEMBER, false);
     $session->logout(USER_LEVEL_CHPREF);
     
     // redirect back to normal CP
-    @ob_end_clean();
-    redirect(makeUrlNS('Special', 'Preferences'), $lang->get('yubiucp_msg_save_title'), $lang->get('yubiucp_msg_save_body'), 3);
+    // if OB-ing isn't enabled, require a JS redirect (hey, not many other options...)
+    if ( @ob_get_contents() )
+    {
+      @ob_end_clean();
+      redirect(makeUrlNS('Special', 'Preferences'), $lang->get('yubiucp_msg_save_title'), $lang->get('yubiucp_msg_save_body'), 3);
+    }
+    else
+    {
+      echo '<h3>' . $lang->get('yubiucp_msg_save_title') . '</h3>';
+      echo '<p>' . $lang->get('yubiucp_msg_save_body') . '</p>';
+      // not much choice here, i'm resorting to javascript because the user CP always
+      // sends headers :-/
+      echo '<script type="text/javascript">
+        addOnloadHook(function()
+        {' .
+        // note: $_COOKIE['sid'] has just been assigned by $session->register_session() - so it's safe to use here.
+        '
+          createCookie(\'sid\', \'' . $_COOKIE['sid'] . '\');
+          window.location = makeUrlNS(\'Special\', \'Preferences\');
+        });
+      </script>';
+      return true;
+    }
   }
   else
   {
--- a/plugins/yubikey/yubikey.css	Fri Dec 18 19:28:57 2009 -0500
+++ b/plugins/yubikey/yubikey.css	Fri Dec 18 19:29:33 2009 -0500
@@ -22,6 +22,11 @@
   font-size: smaller;
 }
 
+span.yubikey_pubkey {
+  font-size: smaller;
+  color: #666;
+}
+
 tr.yk_alt1 td {
   background-color: #f8f8f8;
 }
--- a/plugins/yubikey/yubikey.js	Fri Dec 18 19:28:57 2009 -0500
+++ b/plugins/yubikey/yubikey.js	Fri Dec 18 19:29:33 2009 -0500
@@ -56,12 +56,8 @@
           window.clearInterval(yk_interval);
           miniPromptDestroy(this);
         }
-        else if ( this.value.length == 44 && !this.submitted )
-        {
-          this.submitted = true;
-          yk_handle_submit(this);
-        }
-        else if ( e.keyCode == 13 && this.value.length != 44 )
+        // 0.3: submit only upon a keycode 13
+        else if ( e.keyCode == 13 )
         {
           this.submitted = true;
           yk_handle_submit(this);
@@ -97,6 +93,7 @@
 {
   if ( ta.value.length > 44 || !ta.value.match(/^[cbdefghijklnrtuv]+$/) )
   {
+    // report "invalid characters"
     setTimeout(function()
       {
         var parent = ta.parentNode;
@@ -127,7 +124,10 @@
     var status = document.getElementById(ta.yk_status_id);
     if ( $(status).hasClass('empty') || $(status).hasClass('rmpending') )
     {
-      $(status).next('a')
+      $(status)
+      .next('span.yubikey_pubkey')
+        .text(ta.value.substr(0, 12))
+      .next('a.yubikey_enroll')
         .text($lang.get('yubiauth_ctl_btn_change_key'))
         .addClass('abutton_green')
         .after(' <a class="abutton abutton_red yubikey_enroll" href="#yk_clear" onclick="yk_clear(\'' + ta.yk_field_id + '\', \'' + ta.yk_status_id + '\'); return false;">'
@@ -135,6 +135,7 @@
                '</a>');
     }
     $(status).removeClass('empty').removeClass('enrolled').removeClass('rmpending').addClass('savepending').html($lang.get('yubiauth_ctl_status_enrolled_pending'));
+    $(status).next('span.yubikey_pubkey').text(ta.value.substr(0, 12));
     field.value = ta.value;
     miniPromptDestroy(ta);
     return true;
@@ -163,8 +164,35 @@
       // login window is open
       if ( user_level == USER_LEVEL_GUEST )
       {
-        var show_username = window.yk_user_flags & YK_SEC_NORMAL_USERNAME;
-        var show_password = window.yk_user_flags & YK_SEC_NORMAL_PASSWORD;
+        // for guests, get the user's yubikey auth flags
+        // we're still ok to submit, so make sure twofactor isn't enabled
+        // as we are a guest, we have to get the flags for the user from the server
+        var ajax = ajaxMakeXHR();
+        var uri = makeUrlNS('Special', 'Yubikey', 'get_flags=' + ta.value.substr(0, 12));
+        var flags = 0;
+        try
+        {
+          ajax.open('GET', uri, false);
+          ajax.send(null);
+          
+          if ( ajax.readyState == 4 && ajax.status == 200 )
+          {
+            // we got it
+            var response = String(ajax.responseText + '');
+            if ( check_json_response(response) )
+            {
+              response = parseJSON(response);
+              flags = response.flags || 0;
+            }
+          }
+        }
+        catch ( e )
+        {
+          ajaxLoginSetStatus(AJAX_STATUS_ERROR);
+          return false;
+        }
+        var show_username = flags & YK_SEC_NORMAL_USERNAME;
+        var show_password = flags & YK_SEC_NORMAL_PASSWORD;
       }
       else
       {
@@ -179,13 +207,25 @@
       var can_submit = true;
       if ( show_username && !$('#ajax_login_field_username').attr('value') )
       {
-        $('#ajax_login_field_password').focus();
+        $('#ajax_login_field_username').focus();
+        
+        if ( !show_password )
+          $('#ajax_login_field_username').keyup(function(e)
+            {
+              // assign press of Enter in username field to submit
+              if ( e.keyCode == 13 )
+              {
+                $('#messageBoxButtons input:button:first').click();
+              }
+            });
+        
         can_submit = false;
       }
       if ( show_password && !$('#ajax_login_field_password').attr('value') )
       {
         if ( can_submit )
         {
+          // can_submit only true if show_username false
           $('#ajax_login_field_password').focus();
         }
         can_submit = false;
@@ -212,6 +252,8 @@
     .removeClass('enrolled')
     .addClass( was_pending ? 'empty' : 'rmpending' )
     .text( was_pending ? $lang.get('yubiauth_ctl_status_empty') : $lang.get('yubiauth_ctl_status_remove_pending') )
+    .next('span.yubikey_pubkey')
+      .text('')
     .next('a')
       .text($lang.get('yubiauth_ctl_btn_enroll'))
       .removeClass('abutton_green')