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 SUSI.AI User Password & Parameter extraction from Link

In this blog I will discuss how does Accounts handle the incoming request to reset the password. If a user forgets his/her password, They can use forgot password button on http://accounts.susi.ai and It’s implementation is quite straightforward. As soon as a user enter his/her e-mail id and hits RESET button, an ajax call is made which first checks if the user email id is registered with SUSI.AI or not. If not, a failure message is thrown to user. But if the user is found to be registered in the database, An email is sent to him/her which contains a 30 characters long token. On the server token is hashed against the user’s email id and a validity of 7 days is set to it. Let us have a look at the Reset Password link one receives. http://accounts.susi.ai/?token={30 characters long token} On clicking this link, what it does is that user is redirected to http://accounts.susi.ai with token as a request parameter. At the client side, A search is made which evaluates whether the URL has a token parameter or not. This was the overview. Since, http://accounts.susi.ai is based on ReactJS framework, it is not easy alike the native php functionality, but much more logical and systematic. Let us now take a closer look at how this parameter is searched for, token extracted and validated. As you can see http://accounts.susi.ai and http://accounts.susi.ai/?token={token}, Both redirect the user to the same URL. So the first task that needs to be accomplished is check if a parameter is passed in the URL or not. First import addUrlProps and UrlQueryParamTypes from react-url-query package and PropTypes from prop-types package. These will be required in further steps. Have a look at the code and then we will understand it’s working. const urlPropsQueryConfig = { token: { type: UrlQueryParamTypes.string }, }; class Login extends Component { static propTypes = { // URL props are automatically decoded and passed in based on the config token: PropTypes.string, // change handlers are automatically generated when given a config. // By default they update that single query parameter and maintain existing // values in the other parameters. onChangeToken: PropTypes.func, } static defaultProps = { token: "null", } Above in the first step, we have defined by what parameter should the Reset Password triggered. It means, if and only if the incoming parameter in the URL is token, we move to next step, otherwise normal http://accounts.susi.ai page should be rendered. Also we have defined the data type of the token parameter to be UrlQueryParamTypes.string. PropTypes are attributes in ReactJS similar to tags in HTML. So again, we have defined the data type. onChangeToken is a custom attribute which is fired whenever token parameter is modified. To declare default values, we have used defaultProps function. If token is not passed in the URL, by default it makes it null. This is still not the last step. Till now we have not yet checked if token is there or not. This is done in the componentDidMount…

Continue ReadingReset SUSI.AI User Password & Parameter extraction from Link

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