User
The User Aptitude provides the ability to retrieve a JWT for the current user, which can be used to identify an Olive Helps user to a 3rd party service.
jwt
Provides the ability to generate a JWT for the current user and only valid for the requesting Loop.
import { user } from '@oliveai/ldk';
user.jwt().then((token) => {
console.log(`User's JWT token: ${token}`);
});
An optional config object can be passed in. It is used to determine what optional claims to include in the JWT result.
import { user } from '@oliveai/ldk';
const config = { includeEmail: true };
user.jwt(config).then((token) => {
console.log(`User's JWT token: ${token}`);
});
jwtWithUserDetails
Provides the ability to generate a JWT for the current user as well as get additional information about the user, such as full name and organization details.
import { user } from '@oliveai/ldk';
// Config object can include any of these parameters.
// NOTE: email is included in the encoded JWT, all others are attached
// on the returned object.
const jwtWithUserDetailsConfig = {
includeEmail: true,
includeFullName: true,
includeOrganizationId: true,
includeOrganizationName: true,
};
user.jwtWithUserDetails(jwtWithUserDetailsConfig).then((returnObj) => {
console.log(`User's JWT token: ${returnObj.jwt}`);
console.log(`User's Full Name: ${returnObj.fullName}`);
console.log(`User's Organization ID: ${returnObj.organizationId}`);
console.log(`User's Organization Name: ${returnObj.organizationName}`);
console.log(`User's Email: ${returnObj.email}`);
});
Let's say you have a third party API that authenticates the user with a JWT for every request. Throughout the lifetime of our Loop, we'd like to periodically make calls to this API. This will require us to:
Retrieve the JWT
Refresh the JWT when it expires
Send the JWT in our API request
We will be using the buffer library from npm to assist reading the JWT.
import { user, network } from '@oliveai/ldk';
const apiUrl = 'http://127.0.0.1:8080/myTestApi';
const dashRegExp = new RegExp('-', 'g');
const underscoreRegExp = new RegExp('_', 'g');
let userJwt = null;
let jwtRefreshTimer = null;
function decodeJwt(encodedJwt) {
// A JWT is encoded in base-64 with .'s seperating each section
// header.payload.signature
const jwtParts = encodedJwt.split('.');
const encodedHeader = jwtParts[0];
const encodedPayload = jwtParts[1];
const encodedSignature = jwtParts[2];
const header = JSON.parse(atob(encodedHeader));
const payload = JSON.parse(atob(encodedPayload));
const signature = atob(encodedSignature);
const decodedJwt = { header, payload, signature };
return decodedJwt;
}
// The expiration time is stored in the payload under the exp field
// exp is the number of seconds since the Epoch
function getExpiration(jwt) {
const decoded = decodeJwt(jwt);
return decoded.payload.exp;
}
function clearJwtTimer() {
if (jwtRefreshTimer) {
clearTimeout(jwtRefreshTimer);
jwtRefreshTimer = null;
}
}
function updateJwtTimer(jwt) {
clearJwtTimer();
const expirationTime = getExpiration(jwt);
// Expiration time on the JWT is in seconds, not ms, so we must convert Date.now()
const timeLeft = expirationTime - Date.now() / 1000;
// Don't forget to convert seconds back to ms
jwtRefreshTimer = setTimeout(RefreshJwt, timeLeft * 1000);
}
function setUserJwt(jwt) {
userJwt = jwt;
return userJwt;
}
function RefreshJwt() {
return user.jwt().then(setUserJwt).then(updateJwtTimer);
}
function MyNetworkRequest() {
network
.httpRequest({
url: apiUrl,
method: 'GET',
headers: { Authorization: [`Bearer ${userJwt}`] },
})
.then((response) => console.log(response.statusCode))
.catch((error) => console.log(`Unable to connect: ${error}`));
}
RefreshJwt().then(MyNetworkRequest);
In order to use both the user and network aptitude, we'll need to setup our permissions within our package.json
.
{
...
"ldk": {
"permissions": {
"network": {
"urlDomains": [
{
"value": "127.0.0.1"
}
]
},
"user": {},
...
}
},
...
}
To use the User Aptitude, use the following permissions outline in your package.json
under the ldk
object.
Please see our Permissions page for more information.
...
"ldk": {
"permissions": {
"user": {
"optionalClaims": [
{
"value": "string"
},
...
]
},
...
}
},
...
Examples
The claims included in the JWT can be customized within the permissions object as well. Currently, email
, fullName
, organizationId
and organizationName
are supported.
{
"ldk": {
"permissions": {
"user": {
"optionalClaims": [
{
"value": "email"
},
{
"value": "fullName"
},
{
"value": "organizationId"
},
{
"value": "organizationName"
}
]
}
}
}
}
Last updated