# Authentication The messenger widget has 3 levels of authentication: 1. Anonymous identity 2. Claimed identity 3. Verified identity The minimum required level of user identification to start a conversation is determined by a setting on Dixa's agent interface (by an admin). The default level is set to `anonymous`. ### Anonymous identity This is the default state of the messenger. The user is not identified and the messenger will not be able to provide any information about the user to the agent. The user will be able to start a conversation only if the minimum identification level is set to `anonymous`. ### Claimed identity This is the state when the user has identified themselves but we haven't verified their claim. If the minimum identification level is set to `claimed` in the settings page, then the user can identify themselves upon attempting to start a new conversation. This will open a form where the user can provide their name and email. The user will be able to start a conversation only if the minimum identification level is set to `anonymous` or `claimed`. At this level, the agent will be able to see the user's name and email. ### Verified identity This is the state in which the user's identity has been verified. This happens by you informing the messenger of the user's identity upon initialization of the widget. In this case, the user will be able to start a conversation if the minimum identification level is set to `anonymous`, `claimed` or `verified`. At this level, the agent will be able to see the user's name and email and will be notified that the user can be trusted to be who they say they are. ### Usage If you have the required information about a user (let's say the user is logged into your platform) you can provide the necessary information to the messenger so that it can be used for identification purposes. By default, messenger assumes a user is `anonymous` unless either you identify the user programmatically at the `init` phase, or the user identifies themselves in the messenger. To take advantage of this feature you can pass the user info as an attribute on the options object that you pass to the [`init` method](/docs/dixamessenger/web/interfaces/initpayload). Example: ```ts // verified user identity _dixa_.invoke('init', { messengerToken: '', userIdentity: { type: 'verified', payload: { type: 'jwe', token: 'SomeJWEToken', // this is a JWT token that contains the user info }, }, }); // Claim the user identity _dixa_.invoke('init', { messengerToken: '', userIdentity: { type: 'claimed', name: userProfile.name, // assuming that you have a userProfile object that contains user info email: userProfile.email, }, }); ``` It's also possible to update the user identity after the widget has been initialized by calling the `setUserIdentity` command. Example: ```ts // verified user identity _dixa_.invoke('setUserIdentity', { type: 'verified', payload: { type: 'jwe', token: 'SomeJWEToken' }, }); ``` Note that at this point you can only promote the user identity to a higher level, but not demote it. You can't for example go from `verified` state to `claimed`. Also note that if you pass an invalid email address, the messenger will not allow the user to start a conversation. You can listen to the `on-backend-error` [event](/docs/dixamessenger/web/events) to be notified of this. ### Generating a JWE token As shown in the example above, for a verified user, we need to generate a JWE token. The steps to generate it are: 1. Generate the JWE using the key (CEK) from the messenger settings (Dixa -> Settings -> Messenger -> Authentication). You can either use an autogenerated key or use your own and encode it. In case you want to generate your own key, it must be represented as the base64url encoding of the value’s big endian representation as an octet sequence of 64 bytes 2. Once you have the key from the settings you can use it to generate a JWE with the required payload, in json format. The following claims are recognized: - `email`: (required) The email of the user - `name`: (required) The name of the user - `iat`: (required) Issued at, identifies the time at which the JWT was issued - `jti`: (required) JWT ID, it provides a unique identifier for the JWT, it should be randomly generated to prevent collisions. - `external_id`: (optional) External identifier for the user. It will be persisted on the dixa user. 1. The token must be encrypted using direct use of the shared symmetric key, using the encryption algorithm A256CBC-HS512 (AES256 with CBC mode and HMAC-SHA512) Example for generating a JWE: Typescript ```typescript import * as jose from 'jose'; const key = '...'; // This is the key generated in Dixa settings page const secret = jose.base64url.decode(key); // Define the payload data const payload = { // A token unique to this object. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7 jti: '123e4567-e89b-12d3-a456-426614174000', // the time at which the JWT was issued iat: 1516239022, email: 'example@email.com', name: 'John Doe', external_id: 'cb3f0475-40b0-46d5-af29-e68a8e2e992d', }; const generatedJWEPromise = new jose.EncryptJWT(payload) .setProtectedHeader({ alg: 'dir', enc: 'A256CBC-HS512' }) .encrypt(secret); // Log the JWE to the console generatedJWEPromise .then((JWE) => console.log('Generated JWE:', JWE)) .catch(() => console.log('failed')); ``` Java (via nimbus-jose-jwt library) ```java import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.DirectEncrypter; import java.util.Base64; import java.util.HashMap; import java.util.Map; String key = "..."; // This is the key generated in Dixa settings page byte[] secret = Base64.getUrlDecoder().decode(key); JWEHeader header = new JWEHeader(JWEAlgorithm.DIR, EncryptionMethod.A256CBC_HS512); Map claims = new HashMap<>(); claims.put("email", "example@email.com"); claims.put("name","John Doe"); claims.put("iat",1516239022); claims.put("jti","123e4567-e89b-12d3-a456-426614174000"); Payload payload = new Payload(claims); JWEObject jwe = new JWEObject(header, payload); jwe.encrypt(new DirectEncrypter(secret)); String output = jwe.serialize(); System.out.println("Generated JWE:" + output); ```