Projet

Général

Profil

Paste
Télécharger (6,45 ko) Statistiques
| Branche: | Révision:

root / drupal7 / modules / user / user.js @ c7768a53

1
(function ($) {
2

    
3
/**
4
 * Attach handlers to evaluate the strength of any password fields and to check
5
 * that its confirmation is correct.
6
 */
7
Drupal.behaviors.password = {
8
  attach: function (context, settings) {
9
    var translate = settings.password;
10
    $('input.password-field', context).once('password', function () {
11
      var passwordInput = $(this);
12
      var innerWrapper = $(this).parent();
13
      var outerWrapper = $(this).parent().parent();
14

    
15
      // Add identifying class to password element parent.
16
      innerWrapper.addClass('password-parent');
17

    
18
      // Add the password confirmation layer.
19
      $('input.password-confirm', outerWrapper).parent().prepend('<div class="password-confirm">' + translate['confirmTitle'] + ' <span></span></div>').addClass('confirm-parent');
20
      var confirmInput = $('input.password-confirm', outerWrapper);
21
      var confirmResult = $('div.password-confirm', outerWrapper);
22
      var confirmChild = $('span', confirmResult);
23

    
24
      // Add the description box.
25
      var passwordMeter = '<div class="password-strength"><div class="password-strength-text" aria-live="assertive"></div><div class="password-strength-title">' + translate['strengthTitle'] + '</div><div class="password-indicator"><div class="indicator"></div></div></div>';
26
      $(confirmInput).parent().after('<div class="password-suggestions description"></div>');
27
      $(innerWrapper).prepend(passwordMeter);
28
      var passwordDescription = $('div.password-suggestions', outerWrapper).hide();
29

    
30
      // Check the password strength.
31
      var passwordCheck = function () {
32

    
33
        // Evaluate the password strength.
34
        var result = Drupal.evaluatePasswordStrength(passwordInput.val(), settings.password);
35

    
36
        // Update the suggestions for how to improve the password.
37
        if (passwordDescription.html() != result.message) {
38
          passwordDescription.html(result.message);
39
        }
40

    
41
        // Only show the description box if there is a weakness in the password.
42
        if (result.strength == 100) {
43
          passwordDescription.hide();
44
        }
45
        else {
46
          passwordDescription.show();
47
        }
48

    
49
        // Adjust the length of the strength indicator.
50
        $(innerWrapper).find('.indicator').css('width', result.strength + '%');
51

    
52
        // Update the strength indication text.
53
        $(innerWrapper).find('.password-strength-text').html(result.indicatorText);
54

    
55
        passwordCheckMatch();
56
      };
57

    
58
      // Check that password and confirmation inputs match.
59
      var passwordCheckMatch = function () {
60

    
61
        if (confirmInput.val()) {
62
          var success = passwordInput.val() === confirmInput.val();
63

    
64
          // Show the confirm result.
65
          confirmResult.css({ visibility: 'visible' });
66

    
67
          // Remove the previous styling if any exists.
68
          if (this.confirmClass) {
69
            confirmChild.removeClass(this.confirmClass);
70
          }
71

    
72
          // Fill in the success message and set the class accordingly.
73
          var confirmClass = success ? 'ok' : 'error';
74
          confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]).addClass(confirmClass);
75
          this.confirmClass = confirmClass;
76
        }
77
        else {
78
          confirmResult.css({ visibility: 'hidden' });
79
        }
80
      };
81

    
82
      // Monitor keyup and blur events.
83
      // Blur must be used because a mouse paste does not trigger keyup.
84
      passwordInput.keyup(passwordCheck).focus(passwordCheck).blur(passwordCheck);
85
      confirmInput.keyup(passwordCheckMatch).blur(passwordCheckMatch);
86
    });
87
  }
88
};
89

    
90
/**
91
 * Evaluate the strength of a user's password.
92
 *
93
 * Returns the estimated strength and the relevant output message.
94
 */
95
Drupal.evaluatePasswordStrength = function (password, translate) {
96
  password = $.trim(password);
97

    
98
  var weaknesses = 0, strength = 100, msg = [];
99

    
100
  var hasLowercase = /[a-z]+/.test(password);
101
  var hasUppercase = /[A-Z]+/.test(password);
102
  var hasNumbers = /[0-9]+/.test(password);
103
  var hasPunctuation = /[^a-zA-Z0-9]+/.test(password);
104

    
105
  // If there is a username edit box on the page, compare password to that, otherwise
106
  // use value from the database.
107
  var usernameBox = $('input.username');
108
  var username = (usernameBox.length > 0) ? usernameBox.val() : translate.username;
109

    
110
  // Lose 5 points for every character less than 6, plus a 30 point penalty.
111
  if (password.length < 6) {
112
    msg.push(translate.tooShort);
113
    strength -= ((6 - password.length) * 5) + 30;
114
  }
115

    
116
  // Count weaknesses.
117
  if (!hasLowercase) {
118
    msg.push(translate.addLowerCase);
119
    weaknesses++;
120
  }
121
  if (!hasUppercase) {
122
    msg.push(translate.addUpperCase);
123
    weaknesses++;
124
  }
125
  if (!hasNumbers) {
126
    msg.push(translate.addNumbers);
127
    weaknesses++;
128
  }
129
  if (!hasPunctuation) {
130
    msg.push(translate.addPunctuation);
131
    weaknesses++;
132
  }
133

    
134
  // Apply penalty for each weakness (balanced against length penalty).
135
  switch (weaknesses) {
136
    case 1:
137
      strength -= 12.5;
138
      break;
139

    
140
    case 2:
141
      strength -= 25;
142
      break;
143

    
144
    case 3:
145
      strength -= 40;
146
      break;
147

    
148
    case 4:
149
      strength -= 40;
150
      break;
151
  }
152

    
153
  // Check if password is the same as the username.
154
  if (password !== '' && password.toLowerCase() === username.toLowerCase()) {
155
    msg.push(translate.sameAsUsername);
156
    // Passwords the same as username are always very weak.
157
    strength = 5;
158
  }
159

    
160
  // Based on the strength, work out what text should be shown by the password strength meter.
161
  if (strength < 60) {
162
    indicatorText = translate.weak;
163
  } else if (strength < 70) {
164
    indicatorText = translate.fair;
165
  } else if (strength < 80) {
166
    indicatorText = translate.good;
167
  } else if (strength <= 100) {
168
    indicatorText = translate.strong;
169
  }
170

    
171
  // Assemble the final message.
172
  msg = translate.hasWeaknesses + '<ul><li>' + msg.join('</li><li>') + '</li></ul>';
173
  return { strength: strength, message: msg, indicatorText: indicatorText };
174

    
175
};
176

    
177
/**
178
 * Field instance settings screen: force the 'Display on registration form'
179
 * checkbox checked whenever 'Required' is checked.
180
 */
181
Drupal.behaviors.fieldUserRegistration = {
182
  attach: function (context, settings) {
183
    var $checkbox = $('form#field-ui-field-edit-form input#edit-instance-settings-user-register-form');
184

    
185
    if ($checkbox.length) {
186
      $('input#edit-instance-required', context).once('user-register-form-checkbox', function () {
187
        $(this).bind('change', function (e) {
188
          if ($(this).attr('checked')) {
189
            $checkbox.attr('checked', true);
190
          }
191
        });
192
      });
193

    
194
    }
195
  }
196
};
197

    
198
})(jQuery);