plugins/yubikey/yubikey.js
changeset 0 9d2c4f04a0d0
child 6 4f85ab095cc8
equal deleted inserted replaced
-1:000000000000 0:9d2c4f04a0d0
       
     1 // sample OTP:
       
     2 // ttttvvvvvvcurikvhjcvnlnbecbkubjvuittbifhndhn
       
     3 // charset: cbdefghijklnrtuv
       
     4 
       
     5 var yk_interval = false;
       
     6 
       
     7 var YK_SEC_NORMAL_USERNAME = 1;
       
     8 var YK_SEC_NORMAL_PASSWORD = 2;
       
     9 var YK_SEC_ELEV_USERNAME = 4;
       
    10 var YK_SEC_ELEV_PASSWORD = 8;
       
    11 
       
    12 var yubikey_otp_current = false;
       
    13 
       
    14 function yk_mb_init(fieldid, statid)
       
    15 {
       
    16   load_component(['messagebox', 'fadefilter', 'flyin', 'jquery', 'jquery-ui', 'l10n']);
       
    17   var mp = miniPrompt(yk_mb_construct);
       
    18   if ( typeof(fieldid) == 'function' )
       
    19   {
       
    20     var input = mp.getElementsByTagName('input')[0];
       
    21     input.submit_func = fieldid;
       
    22   }
       
    23   else if ( fieldid && statid )
       
    24   {
       
    25     var input = mp.getElementsByTagName('input')[0];
       
    26     input.yk_field_id = fieldid;
       
    27     input.yk_status_id = statid;
       
    28   }
       
    29 }
       
    30 
       
    31 function yk_mb_construct(mp)
       
    32 {
       
    33   mp.innerHTML = '';
       
    34   mp.style.textAlign = 'center';
       
    35   mp.innerHTML = '<h3>' + $lang.get('yubiauth_msg_please_touch_key') + '</h3>';
       
    36   var ta = document.createElement('input');
       
    37   ta.submitted = false;
       
    38   $(ta)
       
    39     .css('background-color', 'transparent')
       
    40     .css('border-width', '0px')
       
    41     .css('color', '#fff')
       
    42     .css('font-size', '1px')
       
    43     .css('padding', '0')
       
    44     .attr('size', '1')
       
    45     .keyup(function(e)
       
    46       {
       
    47         if ( e.keyCode == 27 )
       
    48         {
       
    49           window.clearInterval(yk_interval);
       
    50           miniPromptDestroy(this);
       
    51         }
       
    52         else if ( this.value.length == 44 && !this.submitted )
       
    53         {
       
    54           this.submitted = true;
       
    55           yk_handle_submit(this);
       
    56         }
       
    57         e.preventDefault();
       
    58         e.stopPropagation();
       
    59       });
       
    60   mp.appendChild(ta);
       
    61   setTimeout(function()
       
    62     {
       
    63       window.yk_interval = setInterval(function()
       
    64         {
       
    65           ta.focus();
       
    66         }, 50);
       
    67     }, 750);
       
    68   var info = document.createElement('p');
       
    69   info.innerHTML = $lang.get('yubiauth_msg_close_instructions');
       
    70   mp.appendChild(info);
       
    71 }
       
    72 
       
    73 function yk_handle_submit(ta)
       
    74 {
       
    75   if ( !ta.value.match(/^[cbdefghijklnrtuv]{44}$/) )
       
    76   {
       
    77     setTimeout(function()
       
    78       {
       
    79         yk_mb_construct(ta.parentNode);
       
    80       }, 1000);
       
    81     ta.previousSibling.innerHTML = $lang.get('yubiauth_msg_invalid_chars');
       
    82     return false;
       
    83   }
       
    84   
       
    85   window.clearInterval(yk_interval);
       
    86   
       
    87   if ( ta.yk_field_id && ta.yk_status_id )
       
    88   {
       
    89     var field = document.getElementById(ta.yk_field_id);
       
    90     var status = document.getElementById(ta.yk_status_id);
       
    91     if ( $(status).hasClass('empty') || $(status).hasClass('rmpending') )
       
    92     {
       
    93       $(status).next('a')
       
    94         .text($lang.get('yubiauth_ctl_btn_change_key'))
       
    95         .addClass('abutton_green')
       
    96         .after(' <a class="abutton abutton_red yubikey_enroll" href="#yk_clear" onclick="yk_clear(\'' + ta.yk_field_id + '\', \'' + ta.yk_status_id + '\'); return false;">'
       
    97                + $lang.get('yubiauth_ctl_btn_clear') +
       
    98                '</a>');
       
    99     }
       
   100     $(status).removeClass('empty').removeClass('enrolled').removeClass('rmpending').addClass('savepending').html($lang.get('yubiauth_ctl_status_enrolled_pending'));
       
   101     field.value = ta.value;
       
   102     miniPromptDestroy(ta);
       
   103     return true;
       
   104   }
       
   105   else if ( ta.submit_func )
       
   106   {
       
   107     ta.submit_func(ta);
       
   108   }
       
   109   else
       
   110   {
       
   111     miniPromptDestroy(ta);
       
   112   }
       
   113 }
       
   114 
       
   115 function yk_login_validate_reqs(ta)
       
   116 {
       
   117   ta.parentNode.removeChild(ta.nextSibling);
       
   118   yubikey_otp_current = ta.value;
       
   119   
       
   120   ta.previousSibling.innerHTML = $lang.get('yubiauth_msg_validating_otp');
       
   121   
       
   122   ajaxPost(makeUrlNS('Special', 'Yubikey'), 'get_flags=' + ta.value.substr(0, 12), function(ajax)
       
   123     {
       
   124       if ( ajax.readyState == 4 && ajax.status == 200 )
       
   125       {
       
   126         miniPromptDestroy(ta);
       
   127         if ( !check_json_response(ajax.responseText) )
       
   128         {
       
   129           handle_invalid_json(ajax.responseText);
       
   130           return false;
       
   131         }
       
   132         ta.previousSibling.innerHTML = $lang.get('yubiauth_msg_otp_valid');
       
   133         var response = parseJSON(ajax.responseText);
       
   134         if ( response.mode == 'error' )
       
   135         {
       
   136           alert('Yubikey server-side processing error: \n' + response.error);
       
   137           return false;
       
   138         }
       
   139         if ( logindata )
       
   140         {
       
   141           if ( logindata.mb_object )
       
   142           {
       
   143             // login window is open
       
   144             if ( user_level == USER_LEVEL_GUEST )
       
   145             {
       
   146               var show_username = response.flags & YK_SEC_NORMAL_USERNAME;
       
   147               var show_password = response.flags & YK_SEC_NORMAL_PASSWORD;
       
   148             }
       
   149             else
       
   150             {
       
   151               var show_username = response.flags & YK_SEC_ELEV_USERNAME;
       
   152               var show_password = response.flags & YK_SEC_ELEV_PASSWORD;
       
   153             }
       
   154             if ( !show_username )
       
   155               $('#ajax_login_field_username').parent('td').hide().prev().hide();
       
   156             if ( !show_password )
       
   157               $('#ajax_login_field_password').parent('td').hide().prev().hide();
       
   158             
       
   159             var can_submit = true;
       
   160             if ( show_username && !$('#ajax_login_field_username').attr('value') )
       
   161             {
       
   162               $('#ajax_login_field_password').focus();
       
   163               can_submit = false;
       
   164             }
       
   165             if ( show_password && !$('#ajax_login_field_password').attr('value') )
       
   166             {
       
   167               if ( can_submit )
       
   168               {
       
   169                 $('#ajax_login_field_password').focus();
       
   170               }
       
   171               can_submit = false;
       
   172             }
       
   173             
       
   174             if ( can_submit )
       
   175             {
       
   176               $('#messageBoxButtons input:button:first').click();
       
   177             }
       
   178           }
       
   179         }
       
   180       }
       
   181     });
       
   182 }
       
   183 
       
   184 function yk_clear(field_id, status_id)
       
   185 {
       
   186   var field = document.getElementById(field_id);
       
   187   var status = document.getElementById(status_id);
       
   188   
       
   189   var was_pending = $(field).hasClass('wasempty');
       
   190   
       
   191   $(field).attr('value', '');
       
   192   $(status)
       
   193     .removeClass('savepending')
       
   194     .removeClass('enrolled')
       
   195     .addClass( was_pending ? 'empty' : 'rmpending' )
       
   196     .text( was_pending ? $lang.get('yubiauth_ctl_status_empty') : $lang.get('yubiauth_ctl_status_remove_pending') )
       
   197     .next('a')
       
   198       .text($lang.get('yubiauth_ctl_btn_enroll'))
       
   199       .removeClass('abutton_green')
       
   200     .next('a')
       
   201       .remove();
       
   202 }
       
   203 
       
   204 addOnloadHook(function()
       
   205   {
       
   206     attachHook('login_build_form', 'yk_login_dlg_hook(table);');
       
   207     attachHook('login_build_userinfo', 'if ( window.yubikey_otp_current ) userinfo.yubikey_otp = window.yubikey_otp_current;');
       
   208     load_component(['expander', 'jquery', 'jquery-ui']);
       
   209   });
       
   210 
       
   211 function yk_login_dlg_hook(table)
       
   212 {
       
   213   window.yubikey_otp_current = false;
       
   214   var tr = document.createElement('tr');
       
   215   var td = document.createElement('td');
       
   216   $(td)
       
   217     .attr('colspan', '2')
       
   218     .css('text-align', 'center')
       
   219     .css('font-size', 'smaller')
       
   220     .css('font-weight', 'bold')
       
   221     .html('<a href="#" onclick="yk_mb_init(yk_login_validate_reqs); return false;" style="color: #6fa202">' + $lang.get('yubiauth_btn_enter_otp') + '</a>');
       
   222   $('a', td).blur(function(e)
       
   223     {
       
   224       $('#messageBoxButtons input:button:first').focus();
       
   225       $('#ajax_login_field_captcha').focus();
       
   226     });
       
   227   tr.appendChild(td);
       
   228   table.appendChild(tr);
       
   229 }
       
   230