Change Password for SUSI Accounts Using Access Token and Email-ID

In this blog, I discuss how the SUSI server synchronizes with SUSI Accounts and SUSI webchat for users to Change Password. When a user logs in, the clients store the email id of the user along with the access token in cookies. These are stored once the client gets a positive login response from the server. Both of these are required at the time of making the final call. Web clients store the email id and access token in the following way. cookies.set('loggedIn', loggedIn, { path: '/', maxAge: time }); cookies.set('emailId', email, { path: '/', maxAge: time }); First, the client has to ask the user to enter their current password. A javascript test is used to validate that at least 6 characters must be entered by the user. A similar test is run on the new password. But while confirming the password, client checks whether the user has entered the same password as new password or not. These are just the basics. In next stage (which is achieved only when all the above conditions are met), client encodes the email id (which it gets from cookies), current password, new password and the access token (which it again extracts from cookies). Now, Client just has to make an ajax request to the server. The response is processed and sent back to the client. Let us now look at PasswordChange Servlet. The base user role is defined as USER. Initial steps of the servlet are to extract the values form the request it receives. The values extracted from the request are in turn used to make a client’s identity. Before that, server checks if current and new password have same values or not. If not, then server returns a JSON response to user stating, “Your current password and new password matches”. Otherwise, it will continue its control flow as it is. Look at the code snippet below: if(password.equals(newpassword)){ result.put("message", "Your current password and new password matches"); result.put("accepted", false); return new ServiceResponse(result); } The reader here may think that they have discovered a hack. But they have not. Why? Because this is just the first step. In later stages, the hash of passwords are used to match to see whether the passwords match or not. To obtain a proper client identity, first a Client credentials object is made with support from the email id which is received in ‘changepassword’ attribute. Using the ClientCredentials object made above, an object of Authentication class is made. This object uses a method defined in its class to return a valid client identity. Using the client identity, value of password hash is extracted from the database along with the salt used to hash the password. If any error is encountered while extracting the client’s password hash value and/or salt value, an error is thrown towards the client, with a message stating “invalid credentials”. ClientCredential pwcredential = new ClientCredential(ClientCredential.Type.passwd_login, useremail); Authentication authentication = DAO.getAuthentication(pwcredential); ClientCredential emailcred = new ClientCredential(ClientCredential.Type.passwd_login, authentication.getIdentity().getName()); ClientIdentity identity = authentication.getIdentity(); String passwordHash; String salt;…

Continue ReadingChange Password for SUSI Accounts Using Access Token and Email-ID

Reset Password for SUSI Accounts Using Verification Link

In this blog, I will discuss how the SUSI server interprets the verification link sent to your email id to reset SUSI account password. The email one receives to reset password looks like this :   http://api.susi.ai/apps/resetpass/index.html?token={30 character long token} *Original link contains a token of length of 30 characters. The link has been tampered for security purpose. Taking a close look at the reset link, one would find it easy to decode. It simply contains path to an application on current SUSI Accounts hosting. Name of the application is “resetpass” for Reset Password. But what about the token in the link? As soon as a user clicks on the link, the app is called and token is passed as a GET parameter. The app in background makes a call to the server where the token is evaluated for whether the token is hashed against some user’s email id and has not expired yet. Below is code of first step the client does which is to make a simple ajax call on Ready state. $(document).ready(function() { var passerr = false, confirmerr = false, tokenerr = false; // get password parameters var regex; var urltoken = getParameter('token'); $.ajax( "/aaa/recoverpassword.json", { data: { getParameters: true, token: urltoken }, dataType: 'json', success: function (response) { regex = response.regex; var regexTooltip = response.regexTooltip; $('#pass').tooltip({'trigger':'focus', 'placement': 'left', 'title': regexTooltip}); $('#status-box').text(response.message); tokenerr = false; }, error: function (xhr, ajaxOptions, thrownError) { $('#status-box').text(thrownError); $('#status-box').addClass("error"); $('#pass').prop( "disabled", true ); $('#confirmpass').prop( "disabled", true ); $('#resetbut').prop( "disabled", true ); tokenerr = true; }, }); As you can see the call is made to /aaa/recoverypassword.json end point with token as the request parameter. Now, the client has to just evaluate the JSON response and render the message for user accordingly. If this request returns an error then the error message is shown and the entries are disabled to enter the password. Otherwise, user email id is shown with green text and user can now enter new password and confirm it. In next step, client simply evaluates the password and sends a query to server to reset it. Let us now look at how server functions and processes such requests. //check if a token is already present if (call.get("getParameters", false)) { if (call.get("token", null) != null && !call.get("token", null).isEmpty()) { ClientCredential credentialcheck = new ClientCredential(ClientCredential.Type.resetpass_token, call.get("token", null)); if (DAO.passwordreset.has(credentialcheck.toString())) { Authentication authentication = new Authentication(credentialcheck, DAO.passwordreset); if (authentication.checkExpireTime()) { String passwordPattern = DAO.getConfig("users.password.regex", "^(?=.*\\d).{6,64}$"); String passwordPatternTooltip = DAO.getConfig("users.password.regex.tooltip", "Enter a combination of atleast six characters"); result.put("message", "Email ID: " + authentication.getIdentity().getName()); result.put("regex", passwordPattern); result.put("regexTooltip", passwordPatternTooltip); result.put("accepted", true); return new ServiceResponse(result); } authentication.delete(); throw new APIException(422, "Expired token"); } throw new APIException(422, "Invalid token"); } else { throw new APIException(422, "No token specified"); } } In the above code snippet, server evaluates the received token on the basis of three parameters. First it checks whether the token is provided or not. If not, it throws APIException with error code 422 and a message “No token specified”. If it passes the check, next it checks…

Continue ReadingReset Password for SUSI Accounts Using Verification Link