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 3rd party services.
API
Example
Permissions

jwt

Provides the ability to generate a JWT for the current user and only valid for the requesting Loop.
1
import { user } from '@oliveai/ldk';
2
3
user.jwt().then((token) => {
4
console.log(`User's JWT token: ${token}`);
5
});
Copied!
An optional config object can be passed in. It is used to determine what optional claims to include in the JWT result.
1
import { user } from '@oliveai/ldk';
2
3
const config = { includeEmail: true };
4
5
user.jwt(config).then((token) => {
6
console.log(`User's JWT token: ${token}`);
7
});
Copied!
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.
1
import { user, network } from '@oliveai/ldk';
2
3
// We're going to use the buffer npm package to make it easy to decode the jwt
4
// This can be installed with `npm i buffer`
5
import { Buffer } from 'buffer';
6
7
const apiUrl = 'http://127.0.0.1:8080/myTestApi';
8
9
const dashRegExp = new RegExp('-', 'g');
10
const underscoreRegExp = new RegExp('_', 'g');
11
12
let userJwt = null;
13
let jwtRefreshTimer = null;
14
15
function atob(b64EncodedString) {
16
// RFC 4648 substitues - for + and _ for / to be url and filesystem safe
17
const replaced = b64EncodedString.replace(dashRegExp, '+').replace(underscoreRegExp, '/');
18
const decoded = Buffer.from(replaced, 'base64').toString();
19
return decoded;
20
}
21
22
function decodeJwt(encodedJwt) {
23
// A JWT is encoded in base-64 with .'s seperating each section
24
// header.payload.signature
25
const jwtParts = encodedJwt.split('.');
26
const encodedHeader = jwtParts[0];
27
const encodedPayload = jwtParts[1];
28
const encodedSignature = jwtParts[2];
29
const header = JSON.parse(atob(encodedHeader));
30
const payload = JSON.parse(atob(encodedPayload));
31
const signature = atob(encodedSignature);
32
const decodedJwt = { header, payload, signature };
33
return decodedJwt;
34
}
35
36
// The expiration time is stored in the payload under the exp field
37
// exp is the number of seconds since the Epoch
38
function getExpiration(jwt) {
39
const decoded = decodeJwt(jwt);
40
return decoded.payload.exp;
41
}
42
43
function clearJwtTimer() {
44
if (jwtRefreshTimer) {
45
clearTimeout(jwtRefreshTimer);
46
jwtRefreshTimer = null;
47
}
48
}
49
50
function updateJwtTimer(jwt) {
51
clearJwtTimer();
52
const expirationTime = getExpiration(jwt);
53
54
// Expiration time on the JWT is in seconds, not ms, so we must convert Date.now()
55
const timeLeft = expirationTime - Date.now() / 1000;
56
57
// Don't forget to convert seconds back to ms
58
jwtRefreshTimer = setTimeout(RefreshJwt, timeLeft * 1000);
59
}
60
61
function setUserJwt(jwt) {
62
userJwt = jwt;
63
return userJwt;
64
}
65
66
function RefreshJwt() {
67
return user.jwt().then(setUserJwt).then(updateJwtTimer);
68
}
69
70
function MyNetworkRequest() {
71
network
72
.httpRequest({
73
url: apiUrl,
74
method: 'GET',
75
headers: { Authorization: [`Bearer ${userJwt}`] },
76
})
77
.then((response) => console.log(response.statusCode))
78
.catch((error) => console.log(`Unable to connect: ${error}`));
79
}
80
81
RefreshJwt().then(MyNetworkRequest);
Copied!
In order to use both the user and network aptitude, we'll need to setup our permissions within our package.json.
1
{
2
...
3
"ldk": {
4
"permissions": {
5
"network": {
6
"urlDomains": [
7
{
8
"value": "127.0.0.1"
9
}
10
]
11
},
12
"user": {},
13
...
14
}
15
},
16
...
17
}
Copied!
To use the User aptitude, use the following permissions outline in your package.json under the ldk object.
1
...
2
"ldk": {
3
"permissions": {
4
"user": {
5
"optionalClaims": [
6
{
7
"value": "string"
8
},
9
...
10
]
11
},
12
...
13
}
14
},
15
...
Copied!

Examples

The claims included in the JWT can be customized within the permissions object as well.
Currently, only "email" is only supported.
1
{
2
"ldk": {
3
"permissions": {
4
"user": {
5
"optionalClaims": [
6
{
7
"value": "email"
8
}
9
]
10
}
11
}
12
}
13
}
Copied!
Last modified 28d ago
Copy link