1
|
|
|
/*! |
2
|
|
|
* @name ElkArte Forum |
3
|
|
|
* @copyright ElkArte Forum contributors |
4
|
|
|
* @license BSD http://opensource.org/licenses/BSD-3-Clause |
5
|
|
|
* |
6
|
|
|
* This file contains code covered by: |
7
|
|
|
* copyright: 2011 Simple Machines (http://www.simplemachines.org) |
8
|
|
|
* license: BSD, See included LICENSE.TXT for terms and conditions. |
9
|
|
|
* |
10
|
|
|
* @version 1.1 |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* This file contains javascript associated with the registration screen |
15
|
|
|
*/ |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Elk Registration class |
19
|
|
|
* |
20
|
|
|
* @param {String} formID name of the registration form |
21
|
|
|
* @param {Number} passwordDifficultyLevel |
22
|
|
|
* @param {Array.} regTextStrings |
23
|
|
|
*/ |
24
|
|
|
function elkRegister(formID, passwordDifficultyLevel, regTextStrings) |
25
|
|
|
{ |
26
|
|
|
this.verificationFields = []; |
27
|
|
|
this.verificationFieldLength = 0; |
28
|
|
|
this.textStrings = regTextStrings ? regTextStrings : []; |
29
|
|
|
this.passwordLevel = passwordDifficultyLevel ? passwordDifficultyLevel : 0; |
30
|
|
|
this.displayChanged = false; |
31
|
|
|
|
32
|
|
|
// Setup all the fields! |
33
|
|
|
this.autoSetup(formID); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
// This is a field which requires some form of verification check. |
37
|
|
|
elkRegister.prototype.addVerificationField = function(fieldType, fieldID) |
38
|
|
|
{ |
39
|
|
|
// Check the field exists. |
40
|
|
|
if (!document.getElementById(fieldID)) |
41
|
|
|
return; |
42
|
|
|
|
43
|
|
|
// Get the handles. |
44
|
|
|
var inputHandle = document.getElementById(fieldID), |
45
|
|
|
imageHandle = document.getElementById(fieldID + '_img') ? document.getElementById(fieldID + '_img') : false, |
46
|
|
|
divHandle = document.getElementById(fieldID + '_div') ? document.getElementById(fieldID + '_div') : false; |
47
|
|
|
|
48
|
|
|
// What is the event handler? |
49
|
|
|
var eventHandler = false; |
50
|
|
|
if (fieldType === 'pwmain') |
51
|
|
|
eventHandler = 'refreshMainPassword'; |
52
|
|
|
else if (fieldType === 'pwverify') |
53
|
|
|
eventHandler = 'refreshVerifyPassword'; |
54
|
|
|
else if (fieldType === 'username') |
55
|
|
|
eventHandler = 'refreshUsername'; |
56
|
|
|
else if (fieldType === 'displayname') |
57
|
|
|
eventHandler = 'refreshDisplayname'; |
58
|
|
|
else if (fieldType === 'reserved') |
59
|
|
|
eventHandler = 'refreshMainPassword'; |
60
|
|
|
|
61
|
|
|
// Store this field. |
62
|
|
|
var vFieldIndex = fieldType === 'reserved' ? fieldType + this.verificationFieldLength : fieldType; |
63
|
|
|
this.verificationFields[vFieldIndex] = new Array(6); |
64
|
|
|
this.verificationFields[vFieldIndex][0] = fieldID; |
65
|
|
|
this.verificationFields[vFieldIndex][1] = inputHandle; |
66
|
|
|
this.verificationFields[vFieldIndex][2] = imageHandle; |
67
|
|
|
this.verificationFields[vFieldIndex][3] = divHandle; |
68
|
|
|
this.verificationFields[vFieldIndex][4] = fieldType; |
69
|
|
|
this.verificationFields[vFieldIndex][5] = inputHandle.className; |
70
|
|
|
|
71
|
|
|
// Keep a count to it! |
72
|
|
|
this.verificationFieldLength++; |
73
|
|
|
|
74
|
|
|
// Step to it! |
75
|
|
|
if (eventHandler) |
76
|
|
|
{ |
77
|
|
|
var _self = this; |
78
|
|
|
createEventListener(inputHandle); |
79
|
|
|
inputHandle.addEventListener('keyup', function(event) {_self[eventHandler].call(_self, event);}, false); |
80
|
|
|
this[eventHandler](); |
81
|
|
|
|
82
|
|
|
// Username will auto check on blur! |
83
|
|
|
inputHandle.addEventListener('blur', function(event) {_self.autoCheckUsername.call(_self, event);}, false); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
// Make the div visible! |
87
|
|
|
if (divHandle) |
88
|
|
|
divHandle.style.display = 'inline'; |
89
|
|
|
}; |
90
|
|
|
|
91
|
|
|
// A button to trigger a username search |
92
|
|
|
elkRegister.prototype.addUsernameSearchTrigger = function(elementID) |
93
|
|
|
{ |
94
|
|
|
var buttonHandle = document.getElementById(elementID), |
95
|
|
|
_self = this; |
96
|
|
|
|
97
|
|
|
// Attach the event to this element. |
98
|
|
|
createEventListener(buttonHandle); |
99
|
|
|
buttonHandle.addEventListener('click', function(event) {_self.checkUsername.call(_self, event);}, false); |
100
|
|
|
}; |
101
|
|
|
|
102
|
|
|
// This function will automatically pick up all the necessary verification fields and initialise their visual status. |
103
|
|
|
elkRegister.prototype.autoSetup = function(formID) |
104
|
|
|
{ |
105
|
|
|
if (!document.getElementById(formID)) |
106
|
|
|
return false; |
107
|
|
|
|
108
|
|
|
var curElement, |
109
|
|
|
curType; |
110
|
|
|
|
111
|
|
|
for (var i = 0, n = document.getElementById(formID).elements.length; i < n; i++) |
112
|
|
|
{ |
113
|
|
|
curElement = document.getElementById(formID).elements[i]; |
114
|
|
|
|
115
|
|
|
// Does the ID contain the keyword 'autov'? |
116
|
|
|
if (curElement.id.indexOf('autov') !== -1 && (curElement.type === 'text' || curElement.type === 'password')) |
117
|
|
|
{ |
118
|
|
|
// This is probably it - but does it contain a field type? |
119
|
|
|
curType = 0; |
120
|
|
|
|
121
|
|
|
// Username can only be done with XML. |
122
|
|
|
if (curElement.id.indexOf('username') !== -1) |
123
|
|
|
curType = 'username'; |
124
|
|
|
else if (curElement.id.indexOf('displayname') !== -1) |
125
|
|
|
curType = 'displayname'; |
126
|
|
|
else if (curElement.id.indexOf('pwmain') !== -1) |
127
|
|
|
curType = 'pwmain'; |
128
|
|
|
else if (curElement.id.indexOf('pwverify') !== -1) |
129
|
|
|
curType = 'pwverify'; |
130
|
|
|
// This means this field is reserved and cannot be contained in the password! |
131
|
|
|
else if (curElement.id.indexOf('reserve') !== -1) |
132
|
|
|
curType = 'reserved'; |
133
|
|
|
|
134
|
|
|
// If we're happy let's add this element! |
135
|
|
|
if (curType) |
136
|
|
|
this.addVerificationField(curType, curElement.id); |
137
|
|
|
|
138
|
|
|
// If this is the username do we also have a button to find the user? |
139
|
|
|
if (curType === 'username' && document.getElementById(curElement.id + '_link')) |
140
|
|
|
this.addUsernameSearchTrigger(curElement.id + '_link'); |
141
|
|
|
} |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
return true; |
145
|
|
|
}; |
146
|
|
|
|
147
|
|
|
// What is the password state? |
148
|
|
|
elkRegister.prototype.refreshMainPassword = function(called_from_verify) |
149
|
|
|
{ |
150
|
|
|
if (!this.verificationFields.pwmain) |
151
|
|
|
return false; |
152
|
|
|
|
153
|
|
|
var curPass = this.verificationFields.pwmain[1].value, |
154
|
|
|
stringIndex = ''; |
155
|
|
|
|
156
|
|
|
// Is it a valid length? |
157
|
|
|
if ((curPass.length < 8 && this.passwordLevel >= 1) || curPass.length < 4) |
158
|
|
|
stringIndex = 'password_short'; |
159
|
|
|
|
160
|
|
|
// More than basic? |
161
|
|
|
if (this.passwordLevel >= 1) |
162
|
|
|
{ |
163
|
|
|
// If there is a username check it's not in the password! |
164
|
|
|
if (this.verificationFields.username && this.verificationFields.username[1].value && curPass.indexOf(this.verificationFields.username[1].value) !== -1) |
165
|
|
|
stringIndex = 'password_reserved'; |
166
|
|
|
|
167
|
|
|
// Any reserved fields? |
168
|
|
|
for (var i in this.verificationFields) |
|
|
|
|
169
|
|
|
{ |
170
|
|
|
if (this.verificationFields[i][4] === 'reserved' && this.verificationFields[i][1].value && curPass.indexOf(this.verificationFields[i][1].value) !== -1) |
171
|
|
|
stringIndex = 'password_reserved'; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
// Finally - is it hard and as such requiring mixed cases and numbers? |
175
|
|
|
if (this.passwordLevel > 1) |
176
|
|
|
{ |
177
|
|
|
if (curPass === curPass.toLowerCase()) |
178
|
|
|
stringIndex = 'password_numbercase'; |
179
|
|
|
|
180
|
|
|
if (!curPass.match(/(\D\d|\d\D)/)) |
181
|
|
|
stringIndex = 'password_numbercase'; |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
var isValid = stringIndex === ''; |
186
|
|
|
if (stringIndex === '') |
187
|
|
|
stringIndex = 'password_valid'; |
188
|
|
|
|
189
|
|
|
// Set the image. |
190
|
|
|
this.setVerificationImage(this.verificationFields.pwmain[2], isValid, this.textStrings[stringIndex] ? this.textStrings[stringIndex] : ''); |
191
|
|
|
this.verificationFields.pwmain[1].className = this.verificationFields.pwmain[5] + ' ' + (isValid ? 'valid_input' : 'invalid_input'); |
192
|
|
|
|
193
|
|
|
// As this has changed the verification one may have too! |
194
|
|
|
if (this.verificationFields.pwverify && !called_from_verify) |
195
|
|
|
this.refreshVerifyPassword(); |
196
|
|
|
|
197
|
|
|
return isValid; |
198
|
|
|
}; |
199
|
|
|
|
200
|
|
|
// Check that the verification password matches the main one! |
201
|
|
|
elkRegister.prototype.refreshVerifyPassword = function() |
202
|
|
|
{ |
203
|
|
|
// Can't do anything without something to check again! |
204
|
|
|
if (!this.verificationFields.pwmain) |
205
|
|
|
return false; |
206
|
|
|
|
207
|
|
|
// Check and set valid status! |
208
|
|
|
var isValid = this.verificationFields.pwmain[1].value === this.verificationFields.pwverify[1].value && this.refreshMainPassword(true), |
209
|
|
|
alt = this.textStrings[isValid === 1 ? 'password_valid' : 'password_no_match'] ? this.textStrings[isValid === 1 ? 'password_valid' : 'password_no_match'] : ''; |
210
|
|
|
|
211
|
|
|
this.setVerificationImage(this.verificationFields.pwverify[2], isValid, alt); |
212
|
|
|
this.verificationFields.pwverify[1].className = this.verificationFields.pwverify[5] + ' ' + (isValid ? 'valid_input' : 'invalid_input'); |
213
|
|
|
|
214
|
|
|
return true; |
215
|
|
|
}; |
216
|
|
|
|
217
|
|
|
// If the username is changed just revert the status of whether it's valid! |
218
|
|
|
elkRegister.prototype.refreshUsername = function() |
219
|
|
|
{ |
220
|
|
|
if (!this.verificationFields.username) |
221
|
|
|
return false; |
222
|
|
|
|
223
|
|
|
if (typeof this.verificationFields.displayname !== 'undefined' && this.displayChanged === false) |
224
|
|
|
{ |
225
|
|
|
this.verificationFields.displayname[1].value = this.verificationFields.username[1].value; |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
// Restore the class name. |
229
|
|
|
if (this.verificationFields.username[1].className) |
230
|
|
|
this.verificationFields.username[1].className = this.verificationFields.username[5]; |
231
|
|
|
|
232
|
|
|
// Check the image is correct. |
233
|
|
|
var alt = this.textStrings.username_check ? this.textStrings.username_check : ''; |
234
|
|
|
this.setVerificationImage(this.verificationFields.username[2], 'check', alt); |
235
|
|
|
|
236
|
|
|
// Check the password is still OK. |
237
|
|
|
this.refreshMainPassword(); |
238
|
|
|
|
239
|
|
|
return true; |
240
|
|
|
}; |
241
|
|
|
|
242
|
|
|
// If the displayname is changed just revert the status of whether it's valid! |
243
|
|
|
elkRegister.prototype.refreshDisplayname = function(e) |
244
|
|
|
{ |
245
|
|
|
if (!this.verificationFields.displayname) |
246
|
|
|
return false; |
247
|
|
|
|
248
|
|
|
if (typeof e !== 'undefined') |
249
|
|
|
{ |
250
|
|
|
if (!(e.altKey || e.ctrlKey || e.shiftKey) && e.which > 48) |
251
|
|
|
{ |
252
|
|
|
this.displayChanged = true; |
253
|
|
|
} |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
// Restore the class name. |
257
|
|
|
if (this.verificationFields.displayname[1].className) |
258
|
|
|
this.verificationFields.displayname[1].className = this.verificationFields.displayname[5]; |
259
|
|
|
|
260
|
|
|
// Check the image is correct. |
261
|
|
|
var alt = this.textStrings.username_check ? this.textStrings.username_check : ''; |
262
|
|
|
this.setVerificationImage(this.verificationFields.displayname[2], 'check', alt); |
263
|
|
|
|
264
|
|
|
// Check the password is still OK. |
265
|
|
|
this.refreshMainPassword(); |
266
|
|
|
|
267
|
|
|
return true; |
268
|
|
|
}; |
269
|
|
|
|
270
|
|
|
// This is a pass through function that ensures we don't do any of the AJAX notification stuff. |
271
|
|
|
elkRegister.prototype.autoCheckUsername = function() |
272
|
|
|
{ |
273
|
|
|
this.checkUsername(true); |
274
|
|
|
}; |
275
|
|
|
|
276
|
|
|
// Check whether the username exists? |
277
|
|
|
elkRegister.prototype.checkUsername = function(is_auto) |
278
|
|
|
{ |
279
|
|
|
if (!this.verificationFields.username) |
280
|
|
|
return false; |
281
|
|
|
|
282
|
|
|
// Get the username and do nothing without one! |
283
|
|
|
var curUsername = this.verificationFields.username[1].value; |
284
|
|
|
var curDisplayname = typeof this.verificationFields.displayname !== 'undefined' ? this.verificationFields.displayname[1].value : ''; |
285
|
|
|
|
286
|
|
|
if (!curUsername && !curDisplayname) |
287
|
|
|
return false; |
288
|
|
|
|
289
|
|
|
|
290
|
|
|
if (!is_auto) |
291
|
|
|
ajax_indicator(true); |
292
|
|
|
|
293
|
|
|
// Request a search on that username. |
294
|
|
|
var checkName = curUsername.php_urlencode(); |
295
|
|
|
sendXMLDocument.call(this, elk_prepareScriptUrl(elk_scripturl) + 'action=register;sa=usernamecheck;xml;username=' + checkName, null, this.checkUsernameCallback); |
|
|
|
|
296
|
|
|
if (curDisplayname) |
297
|
|
|
{ |
298
|
|
|
var checkDisplay = curDisplayname.php_urlencode(); |
299
|
|
|
sendXMLDocument.call(this, elk_prepareScriptUrl(elk_scripturl) + 'action=register;sa=usernamecheck;xml;username=' + checkDisplay, null, this.checkDisplaynameCallback); |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
return true; |
303
|
|
|
}; |
304
|
|
|
|
305
|
|
|
// Callback for getting the username data. |
306
|
|
|
elkRegister.prototype.checkUsernameCallback = function(XMLDoc) |
307
|
|
|
{ |
308
|
|
|
var isValid = true; |
309
|
|
|
|
310
|
|
|
if (XMLDoc.getElementsByTagName("username")) |
311
|
|
|
isValid = parseInt(XMLDoc.getElementsByTagName("username")[0].getAttribute("valid")); |
312
|
|
|
|
313
|
|
|
// What to alt? |
314
|
|
|
var alt = this.textStrings[isValid === 1 ? 'username_valid' : 'username_invalid'] ? this.textStrings[isValid === 1 ? 'username_valid' : 'username_invalid'] : ''; |
315
|
|
|
|
316
|
|
|
this.verificationFields.username[1].className = this.verificationFields.username[5] + ' ' + (isValid === 1 ? 'valid_input' : 'invalid_input'); |
317
|
|
|
this.setVerificationImage(this.verificationFields.username[2], isValid === 1, alt); |
318
|
|
|
|
319
|
|
|
ajax_indicator(false); |
320
|
|
|
}; |
321
|
|
|
|
322
|
|
|
// Callback for getting the displayname data. |
323
|
|
|
elkRegister.prototype.checkDisplaynameCallback = function(XMLDoc) |
324
|
|
|
{ |
325
|
|
|
var isValid = true; |
326
|
|
|
|
327
|
|
|
if (XMLDoc.getElementsByTagName("username")) |
328
|
|
|
isValid = parseInt(XMLDoc.getElementsByTagName("username")[0].getAttribute("valid")); |
329
|
|
|
|
330
|
|
|
// What to alt? |
331
|
|
|
var alt = this.textStrings[isValid === 1 ? 'username_valid' : 'username_invalid'] ? this.textStrings[isValid === 1 ? 'username_valid' : 'username_invalid'] : ''; |
332
|
|
|
|
333
|
|
|
this.verificationFields.displayname[1].className = this.verificationFields.displayname[5] + ' ' + (isValid === 1 ? 'valid_input' : 'invalid_input'); |
334
|
|
|
this.setVerificationImage(this.verificationFields.displayname[2], isValid === 1, alt); |
335
|
|
|
|
336
|
|
|
ajax_indicator(false); |
337
|
|
|
}; |
338
|
|
|
|
339
|
|
|
// Set the image to be the correct type. |
340
|
|
|
elkRegister.prototype.setVerificationImage = function(imageHandle, imageIcon, alt) |
341
|
|
|
{ |
342
|
|
|
if (!imageHandle) |
343
|
|
|
return false; |
344
|
|
|
|
345
|
|
|
if (!alt) |
346
|
|
|
alt = '*'; |
347
|
|
|
|
348
|
|
|
var curClass = imageIcon ? (imageIcon === 'check' ? 'i-help' : 'i-check') : 'i-warn'; |
349
|
|
|
|
350
|
|
|
imageHandle.alt = alt; |
351
|
|
|
imageHandle.title = alt; |
352
|
|
|
imageHandle.className = 'icon ' + curClass; |
353
|
|
|
|
354
|
|
|
return true; |
355
|
|
|
}; |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* Sets up the form fields based on the chosen authentication method, openID or password |
359
|
|
|
*/ |
360
|
|
|
function updateAuthMethod() |
361
|
|
|
{ |
362
|
|
|
var currentAuthMethod, |
363
|
|
|
currentForm; |
364
|
|
|
|
365
|
|
|
// What authentication method is being used? |
366
|
|
|
if (!document.getElementById('auth_openid') || !document.getElementById('auth_openid').checked) |
367
|
|
|
currentAuthMethod = 'passwd'; |
368
|
|
|
else |
369
|
|
|
currentAuthMethod = 'openid'; |
370
|
|
|
|
371
|
|
|
// No openID? |
372
|
|
|
if (!document.getElementById('auth_openid')) |
373
|
|
|
return true; |
374
|
|
|
|
375
|
|
|
currentForm = document.getElementById('auth_openid').form.id; |
376
|
|
|
|
377
|
|
|
document.forms[currentForm].openid_url.disabled = currentAuthMethod !== 'openid'; |
378
|
|
|
document.forms[currentForm].elk_autov_pwmain.disabled = currentAuthMethod !== 'passwd'; |
379
|
|
|
document.forms[currentForm].elk_autov_pwverify.disabled = currentAuthMethod !== 'passwd'; |
380
|
|
|
document.getElementById('elk_autov_pwmain_div').style.display = currentAuthMethod === 'passwd' ? 'inline' : 'none'; |
381
|
|
|
document.getElementById('elk_autov_pwverify_div').style.display = currentAuthMethod === 'passwd' ? 'inline' : 'none'; |
382
|
|
|
|
383
|
|
|
if (currentAuthMethod === 'passwd') |
384
|
|
|
{ |
385
|
|
|
verificationHandle.refreshMainPassword(); |
|
|
|
|
386
|
|
|
verificationHandle.refreshVerifyPassword(); |
387
|
|
|
document.forms[currentForm].openid_url.style.backgroundColor = ''; |
388
|
|
|
document.getElementById('password1_group').style.display = 'block'; |
389
|
|
|
document.getElementById('password2_group').style.display = 'block'; |
390
|
|
|
document.getElementById('openid_group').style.display = 'none'; |
391
|
|
|
} |
392
|
|
|
else |
393
|
|
|
{ |
394
|
|
|
document.forms[currentForm].elk_autov_pwmain.style.backgroundColor = ''; |
395
|
|
|
document.forms[currentForm].elk_autov_pwverify.style.backgroundColor = ''; |
396
|
|
|
document.forms[currentForm].openid_url.style.backgroundColor = '#FFF0F0'; |
397
|
|
|
document.getElementById('password1_group').style.display = 'none'; |
398
|
|
|
document.getElementById('password2_group').style.display = 'none'; |
399
|
|
|
document.getElementById('openid_group').style.display = 'block'; |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
return true; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* Used when the admin registers a new member, enable or disables the email activation |
407
|
|
|
*/ |
408
|
|
|
function onCheckChange() |
409
|
|
|
{ |
410
|
|
|
if (document.forms.postForm.emailActivate.checked || document.forms.postForm.password.value === '') |
411
|
|
|
{ |
412
|
|
|
document.forms.postForm.emailPassword.disabled = true; |
413
|
|
|
document.forms.postForm.emailPassword.checked = true; |
414
|
|
|
} |
415
|
|
|
else |
416
|
|
|
document.forms.postForm.emailPassword.disabled = false; |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
(function($) { |
420
|
|
|
$(document).ready(function() { |
421
|
|
|
$('#agreement_lang').change(function() { |
422
|
|
|
$.ajax({ |
423
|
|
|
type: "POST", |
424
|
|
|
url: elk_scripturl + "?action=jslocale;sa=agreement;xml;api=json", |
|
|
|
|
425
|
|
|
data: {lang: $(this).val()}, |
426
|
|
|
beforeSend: ajax_indicator(true) |
427
|
|
|
}) |
428
|
|
|
.done(function(request) { |
429
|
|
|
if (request != '') |
|
|
|
|
430
|
|
|
{ |
431
|
|
|
$('#agreement_box').html(request.agreement); |
432
|
|
|
$('#privacypol_box').html(request.privacypol); |
433
|
|
|
} |
434
|
|
|
}) |
435
|
|
|
.fail(function(request) { |
|
|
|
|
436
|
|
|
// Maybe reload with language attribute? |
437
|
|
|
}) |
438
|
|
|
.always(function() { |
439
|
|
|
// turn off the indicator |
440
|
|
|
ajax_indicator(false); |
441
|
|
|
}) |
|
|
|
|
442
|
|
|
}); |
443
|
|
|
}); |
444
|
|
|
})(jQuery); |
445
|
|
|
|
When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically: