Authentication
setup to use authentication with the kindly sdk, you can initialize the sdk by adding an argument to the start method here's an example of how to set the authtokencallback using the start method kindlysdk start(botkey string, market string, authtokencallback ( chatid string, promise promise\<string>) > void) kindlysdk start(botkey "bot key", market "your market") { chatid, promise in // generate jwt token // on success, call promise fulfill("jwt token") // on error promise reject(error) } inside the authtokencallback closure, you can generate a jwt token and fulfill the promise with the token on success if there is an error, you can reject the promise with the appropriate error additionally, there is another way to set the authtokencallback using the kindlysdk config getauthtoken property here's an example of how to do it kindlysdk start(botkey "bot key", market "your market") kindlysdk config getauthtoken = { chatid, promise in // generate jwt token // on success, call promise fulfill("jwt token") // on error promise reject(error) } in this example, you set the botkey directly in the start method then, you assign a closure to the kindlysdk config getauthtoken property inside the closure, you can generate the jwt token and fulfill the promise with the token you can also reject the promise with an error if needed remember to replace bot key with your actual bot key manually save authentication token if you need to manually save an authentication token (for example, if you retrieve it from another source) let success = kindlysdk saveauthtoken("your jwt token") the method returns a boolean indicating whether the token was successfully saved to the keychain identity providers that issue more than one token the kindly platform verifies an authenticated chat in one of three ways a jwt your own backend signs, a jwt from your identity provider (optionally paired with an access token), or an opaque bearer token validated by introspection the first is the single string case above for the other two, fulfil the promise with a kindlyauthcredentials instead kindlysdk start(botkey string, market string, authcredentialscallback ( chatid string, promise promise\<kindlyauthcredentials>) > void) kindlysdk start(botkey "bot key", market "your market") { chatid, promise in promise fulfill( kindlyauthcredentials( idtoken idtoken, accesstoken accesstoken, issuer "https //idp example com/", expiresatunixseconds expiresat ) ) } field sent as when you need it idtoken authorization bearer , when set the oidc id token, if your provider issues one for introspection this is the opaque token itself accesstoken x access token next to a different id token, or authorization bearer when it is the only token you have dual token provider setups, and providers that issue no id token at all ignored by the kindly jwt strategy in its companion form issuer x auth issuer bots with more than one provider configured, and any opaque token expiresat not sent opaque tokens, where there is no exp claim for the sdk to read every field is optional, but at least one of idtoken / accesstoken has to be set credentials carrying neither cannot authenticate anything, and the chat stays anonymous which token becomes the bearer authorization is mandatory on kindly's auth route, so whichever token you have goes there idtoken first, falling back to accesstoken a provider that returns only an access token is a normal, supported case rather than a workaround that access token becomes the bearer, and kindly verifies it by whichever strategy the bot is configured for three read only accessors say what the sdk will actually send credentials bearertoken // idtoken ?? accesstoken, first non empty nil if neither is set credentials hastoken // bearertoken != nil, the real "can this authenticate?" check credentials companionaccesstoken // the value that will be sent as x access token, or nil companionaccesstoken is the access token in its companion role only it is nil when the access token is itself the bearer, and nil when it merely duplicates the id token kindly verifies the companion against the id token's at hash , so sending a duplicate would fail an auth that would otherwise have succeeded the sdk drops it for you x access token and x auth issuer are read on auth/chat , message and trigger only a single jwt integration never needs this type, so keep returning a string the credentials callback can also be set after start() kindlysdk config getauthcredentials = { chatid, promise in / âĻ / } getauthcredentials takes precedence over getauthtoken when both are set credentials can also be saved directly, the same way a token can let success = kindlysdk saveauthcredentials( kindlyauthcredentials(idtoken "your id token", accesstoken "your access token") ) token refresh the sdk refreshes credentials on its own, 30 seconds before they expire expiry can come from three places, and whichever is earliest wins expires at returned by the backend when it bound the credentials expiresat you supplied on kindlyauthcredentials the exp claim of the bearer token, when it is a jwt that is the id token when you supplied one, and the access token when it is the only token you have if none of the three is known the credentials are treated as non expiring and never proactively refreshed that is correct for a jwt with no exp claim, but it is a trap for an opaque token there is no claim to read, so supply expiresat or the sdk will keep using it until the backend rejects it re authenticating mid session expiry is handled for you these two are for when the identity itself changes, which the sdk cannot detect kindlysdk authenticate() // user signed in, or switched account kindlysdk deauthenticate() // user signed out authenticate() asks your callback for fresh credentials and re binds them to the chat that is already open, keeping the conversation and its history deauthenticate() unbinds the identity on the backend and clears the stored credentials the chat carries on anonymously with its history intact use endchat() instead when the conversation itself should end it is safe to call when the chat is already anonymous both return a promise\<void>