Implementing Skill Detail Section in SUSI Android App

SUSI Skills are rules that are defined in SUSI Skill Data repo which are basically the responses SUSI gives to the user queries. When a user queries something from the SUSI Android app, a query to SUSI Server is made which further fetches response from SUSI Skill Data and gives the response to the app. Similarly, when we need to list all skills, an API call is made to server to list all skills. The server then checks the SUSI Skill Data repo for the skills and then return all the required information to the app. Then the app displays all the information about the skill to user. User then can view details of each skill and then interact on the chat interface to use that skill. This process is similar to what SUSI Skill CMS does. The CMS is a skill wiki like interface to view all skills and then edit them. Though the app can not be currently used to edit the skills but it can be used to view them and try them on the chat interface. API Information For listing SUSI Skill groups, we have to call on /cms/getGroups.json This will give you all groups in SUSI model in which skills are present. Current response: { "session": {"identity": { "type": "host", "name": "14.139.194.24", "anonymous": true }}, "accepted": true, "groups": [ "Small Talk", "Entertainment", "Problem Solving", "Knowledge", "Assistants", "Shopping" ], "message": "Success: Fetched group list" } So, the groups object gives all the groups in which SUSI Skills are located. Next comes, fetching of skills. For that the endpoint is /cms/getGroups.json?group=GROUP_NAME Since we want all skills to be fetched, we call this api for every group. So, for example we will be calling http://api.susi.ai/cms/getSkillList.json?group=Entertainment for getting all skills in group “Entertainment”. Similarly for other groups as well. Sample response of skill: { "accepted": true, "model": "general", "group": "Shopping", "language": "en", "skills": {"amazon_shopping": { "image": "images/amazon_shopping.png", "author_url": "https://github.com/meriki", "examples": ["Buy a dress"], "developer_privacy_policy": null, "author": "Y S Ramya", "skill_name": "Shop At Amazon", "dynamic_content": true, "terms_of_use": null, "descriptions": "Searches items on Amazon.com for shopping", "skill_rating": null }}, "message": "Success: Fetched skill list", "session": {"identity": { "type": "host", "name": "14.139.194.24", "anonymous": true }} } It gives all details about skills: image author_url examples developer_privacy_policy author skill_name dynamic_content terms_of_use descriptions skill_rating Implementation in SUSI Android App Skill Detail Section UI of Google Assistant Skill Detail Section UI of SUSI SKill CMS Skill Detail Section UI of SUSI Android App The UI of skill detail section in SUSI Android App is the mixture of UI of Skill detail section in Google Assistant ap and SUSI Skill CMS. It displays details of skills in a beautiful manner with horizontal recyclerview used to display the examples. So, we have to display following details about the skill in Skill Detail Section: Skill Name Author Name Skill Image Try it Button Description Examples Rating Content type (Dynamic/Static) Terms of Use Developer’s Privacy policy Let’s see the implementation. 1. Whenever a skill Card View is clicked, showSkillDetailFragment()…

Continue ReadingImplementing Skill Detail Section in SUSI Android App

Link Preview Service from SUSI Server

 SUSI Webchat, SUSI Android app, SUSI iOS app are various SUSI clients which depend on response from SUSI Server. The most common response of SUSI Server is in form of links. Clients usually need to show the preview of the links to the user. This preview may include featured image, description and the title of the link.  Clients show this information by using various 3rd party APIs and libraries. We planned to create an API endpoint for this on SUSI Server to give the preview of the link. This service is called LinkPreviewService. String url = post.get("url", ""); if(url==null || url.isEmpty()){ jsonObject.put("message","URL Not given"); jsonObject.put("accepted",false); return new ServiceResponse(jsonObject); } This API Endpoint accept only 1 get parameter which is the URL whose preview is to be shown. Here we also check if no parameter or wrong URL parameter was sent. If that was the the case then we return an error message to the user. SourceContent sourceContent = TextCrawler.scrape(url,3); if (sourceContent.getImages() != null) jsonObject.put("image", sourceContent.getImages().get(0)); if (sourceContent.getDescription() != null) jsonObject.put("descriptionShort", sourceContent.getDescription()); if(sourceContent.getTitle()!=null)jsonObject.put("title", sourceContent.getTitle()); jsonObject.put("accepted",true); return new ServiceResponse(jsonObject); } The TextCrawler function accept two parameters. One is the url of the website which is to be scraped for the preview data and the other is depth. To get the images, description and title there are methods built in. Here we just call those methods and set them in our JSON Object. private String htmlDecode(String content) { return Jsoup.parse(content).text(); } Text Crawler is based on Jsoup. Jsoup is a java library that is used to scrape HTML pages. To get anything from Jsoup we need to decode the content of HTML to Text. public List<String> getImages(Document document, int imageQuantity) { Elements media = document.select("[src]"); while(var5.hasNext()) { Element srcElement = (Element)var5.next(); if(srcElement.tagName().equals("img")) { ((List)matches).add(srcElement.attr("abs:src")); } }  The getImages method takes the HTML document from the JSoup and find the image tags in that. We have given the imageQuantity parameter in the function, so accordingly it returns the src attribute of the first n images it find. This API Endpoint can be seen working on http://127.0.0.1:4000/susi/linkPreview.json?url=<ANY URL> A real working example of this endpoint would be http://api.susi.ai/susi/linkPreview.json?url=https://techcrunch.com/2017/07/23/dear-tech-dudes-stop-being-such-idiots-about-women/ Resources: Web Crawlers: https://www.promptcloud.com/data-scraping-vs-data-crawling/ JSoup: https://jsoup.org/ JSoup Api Docs: https://jsoup.org/apidocs/ Parsing HTML with JSoup: http://www.baeldung.com/java-with-jsoup

Continue ReadingLink Preview Service from SUSI Server

Fetching Images for RSS Responses in SUSI Web Chat

Initially, SUSI Web Chat rendered RSS action type responses like this: The response from the server initially only contained Title Description Link We needed to improvise the web search & RSS results display and also add images for the results. The web search & RSS results are now rendered as : How was this implemented? SUSI AI uses Yacy to fetchRSSs feeds. Firstly the server using the console process to return the RSS feeds from Yacy needs to be configured to return images too. "yacy":{ "example":"http://127.0.0.1:4000/susi/console.json?q=%22SELECT%20title,%20link%20FROM%20yacy%20WHERE%20query=%27java%27;%22", "url":"http://yacy.searchlab.eu/solr/select?wt=yjson&q=", "test":"java", "parser":"json", "path":"$.channels[0].items", "license":"" } In a console process, we provide the URL needed to fetch data from, the query parameter needed to be passed to the URL and the path to look for the answer in the API response. url = <url>   - the URL to the remote JSON service which will be used to retrieve information. It must contain a $query$ string. test = <parameter> - the parameter that will replace the $query$ string inside the given URL. It is required to test the service. Here the URL used is : http://yacy.searchlab.eu/solr/select?wt=yjson&q=QUERY To include images in RSS action responses, we need to parse the images also from the Yacy response. For this, we need to add `image` in the selection rule while calling the console process "process":[ { "type":"console", "expression":"SELECT title,description,link FROM yacy WHERE query='$1$';" } ] Now the response from the server for RSS action type will also include `image` along with title, description, and link. An example response for the query `Google` : { "title": "Terms of Service | Google Analytics \u2013 Google", "description": "Read Google Analytics terms of service.", "link": "http://www.google.com/analytics/terms/", "image": "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_116x41dp.png", } However, the results at times, do not contain images because there are none stored in the index. This may happen if the result comes from p2p transmission within Yacy where no images are transmitted. So in cases where images are not returned by the server, we use the link preview service to preview the link and fetch the image. The endpoint for previewing the link is : BASE_URL+'/susi/linkPreview.json?url=URL' On the client side, we first search the response for data objects with images in API actions. And the amongst the remaining data objects in answers[0].data, we preview the link to fetch image keeping a check on the count. This needs to be performed for processing the history cognitions too.To preview the remaining links in a loop, we cannot make ajax calls directly in a loop. To handle this, nested ajax calls are made using the function previewURLForImage() where we loop through the remaining links and on the success we decrement the count and call previewURLForImage() on the next link and on error we try previewURLForImage() on the next link without decrementing the count. success: function (rssResponse) { if(rssResponse.accepted){ respData.image = rssResponse.image; respData.descriptionShort = rssResponse.descriptionShort; receivedMessage.rssResults.push(respData); } if(receivedMessage.rssResults.length === count || j === remainingDataIndices.length - 1){ let message = ChatMessageUtils.getSUSIMessageData(receivedMessage, currentThreadID); ChatAppDispatcher.dispatch({ type: ActionTypes.CREATE_SUSI_MESSAGE, message }); } else{ j+=1; previewURLForImage(receivedMessage,currentThreadID, BASE_URL,data,count,remainingDataIndices,j); } }, And we store…

Continue ReadingFetching Images for RSS Responses in SUSI Web Chat

Implementing Text To Speech Settings in SUSI WebChat

SUSI Web Chat has Text to Speech (TTS) Feature where it gives voice replies for user queries. The Text to Speech functionality was added using Speech Synthesis Feature of the Web Speech API. The Text to Speech Settings were added to customise the speech output by controlling features like : Language Rate Pitch Let us visit SUSI Web Chat and try it out. First, ensure that the settings have SpeechOutput or SpeechOutputAlways enabled. Then click on the Mic button and ask a query. SUSI responds to your query with a voice reply. To control the Speech Output, visit Text To Speech Settings in the /settings route. First, let us look at the language settings. The drop down list for Language is populated when the app is initialised. speechSynthesis.onvoiceschanged function is triggered when the app loads initially. There we call speechSynthesis.getVoices() to get the voice list of all the languages currently supported by that particular browser. We store this in MessageStore using ActionTypes.INIT_TTS_VOICES action type. window.speechSynthesis.onvoiceschanged = function () { if (!MessageStore.getTTSInitStatus()) { var speechSynthesisVoices = speechSynthesis.getVoices(); Actions.getTTSLangText(speechSynthesisVoices); Actions.initialiseTTSVoices(speechSynthesisVoices); } }; We also get the translated text for every language present in the voice list for the text - `This is an example of speech synthesis` using google translate API. This is called initially for all the languages and is stored as translatedText attribute in the voice list for each element. This is later used when the user wants to listen to an example of speech output for a selected language, rate and pitch. https://translate.googleapis.com/translate_a/single?client=gtx&sl=en-US&tl=TARGET_LANGUAGE_CODE&dt=t&q=TEXT_TO_BE_TRANSLATED When the user visits the Text To Speech Settings, then the voice list stored in the MessageStore is retrieved and the drop down menu for Language is populated. The default language is fetched from UserPreferencesStore and the default language is accordingly highlighted in the dropdown. The list is parsed and populated as a drop down using populateVoiceList() function. let voiceMenu = voices.map((voice,index) => { if(voice.translatedText === null){ voice.translatedText = this.speechSynthesisExample; } langCodes.push(voice.lang); return( <MenuItem value={voice.lang} key={index} primaryText={voice.name+' ('+voice.lang+')'} /> ); }); The language selected using this dropdown is only used as the language for the speech output when the server doesn’t specify the language in its response and the browser language is undefined. We then create sliders using Material UI for adjusting speech rate and pitch. <h4 style={{'marginBottom':'0px'}}><Translate text="Speech Rate"/></h4> <Slider min={0.5} max={2} value={this.state.rate} onChange={this.handleRate} /> The range for the sliders is : Rate : 0.5 - 2 Pitch : 0 - 2 The default value for both rate and pitch is 1. We create a controlled slider saving the values in state and using onChange function to record change in values. The Reset buttons can be used to reset the rate and pitch values respectively to their default values. Once the language, rate and pitch values have been selected we can click on `Play a short demonstration of speech synthesis`  to listen to a voice reply with the chosen settings. { this.state.playExample && ( <VoicePlayer play={this.state.play} text={voiceOutput.voiceText} rate={this.state.rate} pitch={this.state.pitch} lang={this.state.ttsLanguage} onStart={this.onStart} onEnd={this.onEnd} /> ) }…

Continue ReadingImplementing Text To Speech Settings in SUSI WebChat

Implementing Change Password Feature in SUSI Android App using Custom Dialogs

Recently a new servlet was implemented on the SUSI Server about changing the password of the logged in user. This feature comes in handy to avoid unauthorized usage of the SUSI Account. Almost all the online platforms have this feature to change the password to avoid notorious user to unethical use someone else’s account. In SUSI Android app this new API was used with a nice UI to change the password of the user. The process is very simple and easy to grasp. This blog will try to cover the API information and implementation of the Change Password feature in the android client. API Information For changing the password of SUSI Account of the user, we have to call on  /aaa/changepassword.json We have to provide three parameters along with this api call: changepassword:  Email of user (type string) using which user is logged in. password:  Old password (type string with min length of 6) of the user. newpassword: New password (type string with min length of 6) of the user. access_token: An encrypted access_token indicating user is logged in. Sample Response (Success) { "session": {"identity": { "type": "email", "name": "YOUR_EMAIL_ADDRESS", "anonymous": false }}, "accepted": true, "message": "Your password has been changed!" } Error Response (Failure). This happens when user is not logged in: HTTP ERROR 401 Problem accessing /aaa/changepassword.json. Reason: Base user role not sufficient. Your base user role is 'ANONYMOUS', your user role is 'anonymous' Implementation in SUSI Android App The change password option is located in Settings Activity and displayed only when user is logged in. So, if a logged in user wants to change the password of his/her SUSI AI account, he/she can simply go to the Settings and click on the option. Clicking on the options open up a dialog box with 3 input layouts for: Current Password New Password Confirm New Password So, user can simply add these three inputs and click “Ok”. This will change the password of their account. Let’s see some code explanation. When user clicks on the “reset password” option from the settings, the showResetPasswordAlert() method is called which displays the dialog. And when user clicks on the “OK” button the resetPassword method() in the presenter is called passing input from the three input layout as parameters. settingsPresenter.resetPassword(password.editText?.text.toString(), newPassword.editText?.text.toString(), conPassword.editText?.text.toString()) fun showResetPasswordAlert() { val builder = AlertDialog.Builder(activity) val resetPasswordView = activity.layoutInflater.inflate(R.layout.alert_reset_password, null) password = resetPasswordView.findViewById(R.id.password) as TextInputLayout newPassword = resetPasswordView.findViewById(R.id.newpassword) as TextInputLayout conPassword = resetPasswordView.findViewById(R.id.confirmpassword) as TextInputLayout builder.setView(resetPasswordView) builder.setTitle(Constant.CHANGE_PASSWORD) .setCancelable(false) .setNegativeButton(Constant.CANCEL, null) .setPositiveButton(getString(R.string.ok), null) resetPasswordAlert = builder.create() resetPasswordAlert.show() setupPasswordWatcher() resetPasswordAlert.getButton(AlertDialog.BUTTON_POSITIVE)?.setOnClickListener { settingsPresenter.resetPassword(password.editText?.text.toString(), newPassword.editText?.text.toString(), conPassword.editText?.text.toString()) } } In the resetPassword method, all details about the passwords are checked like: If passwords are not empty. If passwords’ lengths are greater than 6. If new password and confirmation new password matches     When all the conditions are satisfied and all the inputs are valid, resetPassword() in model is called which makes network call to change password of the user. settingModel.resetPassword(password,newPassword,this) override fun resetPassword(password: String, newPassword: String, conPassword: String) { if (password.isEmpty()) { settingView?.invalidCredentials(true,…

Continue ReadingImplementing Change Password Feature in SUSI Android App using Custom Dialogs

Making GUI for SUSI Linux with PyGTK

SUSI Linux app provides access to SUSI on Linux distributions on desktop as well as hardware devices like Raspberry Pi. It started off as a headless client but we decided to add a minimalist GUI to SUSI Linux for performing login and configuring settings. Since, SUSI Linux is a Python App, it was desirable to use a GUI Framework compatible with Python. Many popular GUI frameworks now provide bindings for Python. Some popular available choices are: wxPython: wxPython is a Python GUI framework based on wxWidgets, a cross-platform GUI library written in C++. In addition to the standard dialogs, it includes a 2D path drawing API, dockable windows, support for many file formats and both text-editing and word-processing widgets. wxPython though mainly support Python 2 as programming language. PyQT: Qt is a multi-licensed cross-platform framework written in C++. Qt needs a commercial licence for use but if application is completely Open Source, community license can be used. Qt is an excellent choice for GUIs and many applications are based on it. PyGTK / PyGObject: PyGObject is a Python module that lets you write GUI applications in GTK+. It provides bindings to GObject, a cross platform C library. GTK+ applications are natively supported in most distros and you do not need to install any other development tools for developing with PyGTK. Comparing all these frameworks, PyGTK was found to meet our needs very well. To make UIs in PyGTK, you have a WYSIWYG (What you see is what you get) editor called Glade. Though you can design whole UI programmatically, it is always convenient to use an editor like Glade to simplify the creation and styling of widgets. To create a UI, you need to install Glade in your specific distribution. After that open glade, and add a Top Level container Window or AppWindow to your app. Once that is done, you may pick from the available Layout Managers. We are using BoxLayout Manager in SUSI Linux GUIs. Once that is done, add your widgets to the Application Window using Drag and Drop. Properties of widgets are available on the right panel. Edit your widget properties to give them meaningful IDs so we can address them later in our code. GTK also provides Signals for signaling about a events associated with the widgets. Open the Signals tab in the Widget properties pane. Then, you need to write name of the signal handler for the events associated with Widgets. A signal handler is a function that is fired upon the occurrence of the associated event. For example, we have signals like text_changed in Text Entry boxes, and clicked for Button. After completing the design of GUI, we can address the .glade file of the UI we just created in the Python code. We can do this using the following snippet. import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk builder = Gtk.Builder() builder.add_from_file("glade_files/signin.glade") You can reference each widget from the Glade file using its ID like below. email_field = builder.get_object("email_field") Now, to handle all the declared signals in…

Continue ReadingMaking GUI for SUSI Linux with PyGTK

Modifying SUSI Skills using SUSI Skill CMS

SUSI Skill CMS is a complete solution right from creating a skill to modifying the skill. The skills in SUSI are well synced with the remote repository and can be completely modified using the Edit Skill feature of SUSI Skill CMS. Here’s how to Modify a Skill. Sign Up/Login to the website using your credentials in skills.susi.ai Choose the SKill which you want to edit and click on the pencil icon. The following screen allows editing the skill. One can change the Group, Language, Skill Name, Image and the content as well. After making the changes the commit message can be added to Save the changes. To achieve the above steps we require the following API Endpoints of the SUSI Server. http://api.susi.ai/cms/getSkillMetadata.json - This gives us the meta data which populates the various Skill Content, Image, Author etc. http://api.susi.ai/cms/getAllLanguages.json - This gives us all the languages of a Skill Group. http://api.susi.ai/cms/getGroups.json - This gives us all the list of Skill Groups whether Knowledge, Entertainment, Smalltalk etc. Now since we have all the APIs in place we make the following AJAX calls to update the Skill Process. Since we are detecting changes in all the fields (Group Value, Skill Name, Language Value, Image Value, Commit Message, Content changes and the format of the content), the AJAX call can only be sent when there is a change in the PR and there is no null or undefined value in them. For that, we make various form validations. They are as follows. We first detect whether the User is in a logged in state. if (!cookies.get('loggedIn')) { notification.open({ message: 'Not logged In', description: 'Please login and then try to create/edit a skill', icon: <Icon type="close-circle" style={{ color: '#f44336' }} />, }); } We check whether the image uploaded matches the format of the Skill image to be stored which is ::image images/imageName.png if (!new RegExp(/images\/\w+\.\w+/g).test(this.state.imageUrl)) { notification.open({ message: 'Error Processing your Request', description: 'image must be in format of images/imageName.jpg', icon: <Icon type="close-circle" style={{ color: '#f44336' }} />, }); } We check if the commit message is not null and notify the user if he forgot to add a message. if (this.state.commitMessage === null) { notification.open({ message: 'Please make some changes to save the Skill', icon: <Icon type="close-circle" style={{ color: '#f44336' }} />, }); } We also check whether the old values of the skill are completely similar to the new ones, in this case, we do not send the request. if (toldValues===newValues { notification.open({ message: 'Please make some changes to save the Skill', icon: <Icon type="close-circle" style={{ color: '#f44336' }} />, }); } To check out the complete code, go to this link. Next, if the above validations are successful, we send a POST request to the server and show the notification to the user accordingly, whether the changes to the Skill Data have been updated or not. Here’s the AJAX call snippet. // create a form object let form = new FormData();        /* Append the following fields from…

Continue ReadingModifying SUSI Skills using SUSI Skill CMS

API to List All Users on SUSI.AI

In this blog, I discuss how the SUSI server helps in listing out all the users registered on it. The only role Susi server plays is, Whenever it receives a request at http://api.susi.ai/aaa/getUsers.json The server evaluate the parameters in the request, validates them and notify the user accordingly. API needs 2 parameters, out of which access-token is a necessary. 2nd parameter has to be one from the given list : Parameter Data type getPageCount boolean GetUserCount boolean Page integer On the basis of this 2nd parameter, server gets to know what does the client with given access-token is requesting. Server evaluates the access-token and validates that if the access token belongs to a user with user role atleast ADMIN, then the request is valid and proceed further with fetching the data in next step. Otherwise, server responds with error code “401” and error message “Base user role not sufficient”. It is advisable for clients that before redirecting users to admin panel or any other service, Please hit http://api.susi.ai/aaa/showAdminService.json And check that whether the user logged in is allowed to access the admin panel or not. The servlet /showAdminService.json is quite easy to understand for even those new to programming. Coming back to our topic, by now, server knows that this client is authorized to access the user list. But what all information does server needs to provide? In response to this request, server encodes following attributes in the JSON Array {which is part of JSON object} and sends it to user : Attribute Description Name Email-Id of the user Anonymous Is this user anonymous or not User Role User Role of the user Confirmed User has verified account or not Last Login IP Last IP from which login was requested Last Login Time Time when last login request was made Signup Time When did the user signed up First things first, check if enough parameters are provided or not. If not, respond with error stating “Bad Request. No parameter present”. Otherwise, server does a general iteration which has to be done irrespective of the 2nd parameter. First of all, get a list of all the authorized users using getAuthorizedClients method of Data Access Object class. This method picks up all the keys from authorized file {which are nothing but identification of clients from which requests are received}. Though it, skips those key which are host addresses (which can not be used to identify a user), it does includes all the email ids {which are obvious identification of users}. public static Collection<ClientIdentity> getAuthorizedClients() { ArrayList<ClientIdentity> i = new ArrayList<>(); for (String id: authorization.keys()) { if(id.contains("host")) continue; i.add(new ClientIdentity(id)); } return i; } In next steps, the collection is converted to suitable data types over which iterations are easy and can be converted to JSON objects and Arrays easily. After this, server evaluates which parameter is requested in the request. Let us pick each case one by one for simplicity. Client has requested number of pages in the request. Server finds the…

Continue ReadingAPI to List All Users on SUSI.AI

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