LoginWidget jQuery-UI widget
The widget described here is an adaptation of the
LoginWidget (developed by Brice Gassman) from Dojo to jQuery-UI. It interacts with the same service
(= the CDSLogin service) and has the same functionnalities. Thus, it adds simple links to login, to logout, to register and to get the user preferences. The contents of the graphical user interface (GUI) is exactly the same ; there are juste some slight differences in its appearance. On the contrary to the Dojo version of the
LoginWidget, the interaction with the service is separated from the GUI. Thus it is possible to change the GUI if needed without changing anything in the widget code, just by calling the appropriate public
methods of the widget.
This widget is a true jQuery-UI widget which adds simple links to interact with the Login service of the CDS. It adapts its style in function of the choosen jQuery-UI theme. It has been built given the instructions of the following page:
jQuery-UI - Widget factory. Consequently, you must import the appopriate jQuery and jQuery files (javascript and css).
You can download it here:
CDSLoginWidget.tar.gz. The directory demos contains a demonstration page in which you will have to change the path of jquery.js, jquery-ui.js and jquery-ui.css.
Dependency
This widget has been tested jQuery 1.7 and jQuery-UI 1.8 and requires the following jQuery-UI widgets:
- jquery.ui.core.js
- jquery.ui.widget.js
- jquery.ui.position.js
- jquery.ui.dialog.js
- jquery.ui.tabs.js
- jquery.ui.button.js
Usage
You have to create simple DIV element in the place where you want to insert the CDSLoginWidget:
<div id="CDSLoginWidget"></div>
An then, the following javascript:
$(function(){
$('#CDSLoginWidget').loginWidget();
});
Here is what is created by default:
And finally, you can destroy the whole widget and come back at the original HTML item by calling the destroy function.
$('#CDSLoginWidget').loginWidget('destroy');
Options
At the creation of the menu, you can set the following options:
|
Description |
Possible values |
By default |
server |
URL to the CDSLogin server. |
Any URL. |
'http://cdsportal.u-strasbg.fr/CDSLogin/service' |
adminPage |
URL to the CDSLogin administration page. |
Any URL. |
'http://cdsportal.u-strasbg.fr/CDSLogin/admin.jsp' |
mode |
The widget mode. |
'simpleLink' or null |
null |
widgetClass |
An additional CSS class for the widget element. |
Class name or null |
null |
refreshFreq |
Frequency of the connection refresh. |
Time in ms |
1860000 31min |
errorTimer |
Time while an error is displayed. |
Time in ms |
3000 3s |
Example:
$('#CDSLoginWidget').loginWidget({
widgetClass: 'myClass',
refreshFreq: 600000 // Refresh the widget all 10 minutes.
});
By setting the option
mode to
simpleLink, nothing will appear in the DIV element (
#CDSLoginWidget in our example). Actually, in this case, the widget will be only a link to the CDS Login service. Thus, you can interact with the service through the widget thanks to its methods. So, it is also possible to use another GUI to interact with the CDS Login service.
Events
You can also customize the following events:
|
Description |
Arguments |
onlogin |
Event triggered when a user succeeds to log in the CDS. |
sessionId, isAnonymousSession, userData |
onloginfail |
Event triggered when user does not succeed to log in the CDS (user name or password invalid, or if the server is out of order) |
username, error, sessionId |
onlogout |
Event triggered when a user log out the CDS. |
sessionId, userData |
onrefresh |
Event triggered when the login widget has just refreshed. |
sessionId, isAnonymousSession, userData |
Example:
$('#CDSLoginWidget').loginWidget({
...,
onlogin: function(sessionId, anonymous, user){
console.log('INFO: '+user.username+' logged !');
console.log('SESSION ID = '+sessionId);
console.log('IS SESSION ANONYMOUS ? '+anonymous);
console.log('USER: '); console.log(user);
},
onloginfail: function(username, error, sessionId){
console.log('ERROR: Impossible to log in "'+username+'", because: '+error);
},
onlogout: function(sessionId, user){
console.log('INFO: '+user.username+' logged out !');
}
});
Methods
And you can use the following methods/functions to interact dynamically with the CDSLoginWidget:
Public methods
|
Description |
Parameters |
Returned value |
destroy() |
Destroys all DOM modifications done by this jQuery-UI widget. |
|
|
getUser() |
Gets all information about the current user. |
|
{ username: "...", email: "...", role: "..." } |
isAnonymousSession() |
Tells whether a CDSLogin user is connected. |
|
true/false |
refreshSession() |
Reactivates and retrieves all information about the current session. |
|
|
login(username, password, permanentConnection [,callback]) |
Logs in the specified user with the given password. |
username: String, password: String, permanentConnection: boolean |
|
logout([callback]) |
Logs out the current connected user. |
|
|
askForNewPassword(username [,callback]) |
Asks to the server to send an email to the specified user so that he can change its password. |
|
|
register(userData [,callback]) |
Creates a new CDSLogin user with the given data. |
userData: { username: "...", password: "...", email: "...", firstName: "...", lastName: "...", affiliation: "...", researchDomain: "...", isDataPublic: "yes"/"no" } |
|
getPreferences(resultCallback [,callback]) |
Gets all preferences of the current user. |
resultCallback: function(preferences: Object, serverResp: Object) |
{ user: { preferences: {...} } |
updatePreferences(pref [,callback]) |
Updates the preferences of the current user with the given ones. |
pref: Object |
|
changePassword(oldPwd, newPwd [,callback]) |
Changes the password of the current connected user. |
oldPwd: String, newPwd: String |
|
prettyNames(usernames [,callback]) |
Gets the "pretty names" of the given list of users. |
usernames: String (coma separated list) |
|
Some of these methods may have a last parameter named:
callback. It must be a function which will be called at the end of the query server. Its parameters are always the same:
- success: true/false => Indicates whether the query and the function have succeeded.
- errorMsg: String or null => If not null, it is the error message returned by the server or the function itself.
- data: Object or null => The response of the server.
Example:
var widgetDiv = $('#CDSLoginWidget');
// Try to log in:
widgetDiv.loginWidget('login', 'myName', 'myPwd', false, function(success, errorMsg, resp){
if (success){
// Get the user data:
var userData = widgetDiv.loginWidget('getUser');
// Get the preferences:
widgetDiv.loginWidget('preferences', function(pref, resp){
var userPreferences = pref;
// Do what you want with them !
});
// Change the password:
widgetDiv.loginWidget('changePassword', 'myPwd', 'myNewPwd', function(success2, errorMsg2, resp2){
alert('Password '+(success2 ? 'changed !' : ('not changed, because: '+errorMsg2+' !')));
});
}else{
// Create the user:
widgetDiv.register({ username: 'myName', password: 'myNewPwd', email: 'myName@foo.fr', isDataPublic: 'no'}, function(success2, errorMsg2, resp2){
alert('Registration '+(success2 ? 'succeeded' : ('failed, because: '+errorMsg2))+' !');
});
});
// Logs out:
widgetDiv.loginWidget('logout');
Private methods
The following methods can be used only into the widget definition or from the provided GUI.
|
Description |
Parameters |
Returned value |
_queryServer(command, data [, callback]) |
Sends a query to the CDSLogin server in order to execute the given command with the given parameters. |
command: String, data: Object |
|
_encodeParameter(param) |
Encodes the given parameter in order to send it to the CDSLogin server by jQuery.ajax. |
param: String |
String |
_encodeParameters(params) |
Encodes the values of the given object in order to send it to the CDSLogin server by jQuery.ajax. |
params: Object |
Object |
_isSuccess(serverResp) |
Tells whether the commands executed on the CDSLogin server is successful or not, in function of its response. |
serverResp: Object |
true/false |
_getErrorMsg(serverResp) |
Extracts the error message from the given CDSLogin server response. If there is no error, 'null' is returned. |
serverResp: Object |
String |
_callCallback(callback, serverResp) |
Executes the given callback (if any) and sets its parameters thanks to the given CDSLogin server response, by using _isSuccess(...) and _getErrorMsg(...). |
callback: function(success: boolean, errorMsg: String, serverResp: Object) |
|
_encrypt(str, salt) |
Encrypts the given string with the given salt by using the BCrypt algorithm. |
str: String, salt: String |
String |
Security
Password
Passwords are encrypted with BCrypt by the widget before be sent to the CDSLogin server. BCrypt is an hashing algorithm based on
Blowfish. The javascript version of this algorithm used in this widget has been got at:
http://code.google.com/p/javascript-bcrypt/. It has been slightly modified in order to add the function
encodeSalt but also to change the character encoding to adapt it the server one: US-ASCII.
The character encoding US-ASCII raises a little problem of security: all accents or Unicode characters not contained in US-ASCII are replaced by
? (ascii code: 63). Thus, 2 passwords may be encrypted in the same way if the only different characters are accents. For instance:
'mdpCrypté',
'mdpCryptà',
'mdpCryptù' and
'mdpCrypt?' will be all correct !
On the CDSLogin server all passwords are stored and checked in their encrypted version. So the CDSLoginWidget has only to send any password already encrypted. However, this encrypted password may be caught by anyone who spies on the connection between the client and the CDSLogin server. To avoid this problem, the encrypted password is also encrypted.
Here are the steps followed by the CDSLoginWidget when a user is logging in:
- Ask the salt specific to the user to the CDSLogin server => userSalt
- encPwd1 = BCrypt.hashpw(userMdp, userSalt)
- Compute a second salt specific to the current session => sessionSalt = BCrypt.encodeSalt(sessionId)
- encPwd2 = BCrypt.hashpw(encPwd1, sessionSalt)
- Send the password endPwd2 in the data sent to the CDSLogin server with the command login.
However, when registering or changing password, the password must be encrypted only one time so that the server can store the encrypted password.
- Ask the salt specific to the user to the CDSLogin server => userSalt
- encPwd = BCrypt.hashpw(userMdp, userSalt)
- Send the password endPwd in the data sent to the CDSLogin server with the command createUser or changePassword.
NOTE: only the new passwords MUST be encrypted ONLY one time. So for the command
changePassword, the old password is encrypted as for the
login command.
IMPORTANT/TODO: The current version of the CDSLoginWidget DOES NOT ENCRYPT password However all the code for that is already written...but commented. Once the server will be ready to manage that passwords management, the following lines must be UN-commented: 444-453 and 466-473 (in login(...)), 514-516 and 521-524 (in register(...)), 587-590 and 594-597 (in changePassword(...)).
Version
Version: 1.0 (15th March 2012)
Download: CDSLoginWidget.tar.gz (all sources are included)
Author: Grégory Mantelet (CDS)