-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPre-request-Script.js
More file actions
255 lines (236 loc) · 11.1 KB
/
Pre-request-Script.js
File metadata and controls
255 lines (236 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
// This script will request a new token when no token present yet or refresh when the token is expired
// 2022-05-09 Version 1.0
// 2022-12-16 Version 1.1 updated with Scopes
// 2023-03-20 Version 1.2
//
// The script is designed to be placed on Collection level in the Pre-request Script,
// if placed or used on other level adjust the script accordingly as all parameters are used in the Environment Scope
// It will check variables present in Environment Scope, read if present and create if not present
// access_token, this will be used by the Collection / Authorization and all requests will be configured to "Inherit auth from parent"
// refresh_token,
// expires_in, in milliseconds
// refresh_time, the time the token was refreshed
// Configure manually in the Authorization Tab of the Collection the following parameters:
// Access Token = Available Tokens,
// use {{access_token}} in the next field,
// Header Prefix = Bearer
//
// Flow of the script:
// In case the token is expired and we have a refresh token it will refresh the access token
// If the refresh fails it will request both a new refresh and access token
// In case the token is expired and we have no refresh token it will request both a new refresh and access token
// In all other cases we will use the availible access_token,
// If that fails with unauthorized manually empty the environment variable access_token and refresh_token!
//
// https://learning.postman.com/docs/sending-requests/variables/
// Remark: sendRequest is an asynchronous call in JavaScript
//
let currentAccess_token = "";
let currentRefresh_token = "";
let currentExpires_in = 0;
let tokenDate = new Date(2000,0,1); // Set to Januari 2000
let currentRefresh_time = tokenDate; // Set to Januari 2000
let currentToken_age = 0;
// Access Token is received after first request, however due to tenant refresh it could be invalid.
if ( pm.environment.has("access_token") ) {
currentAccess_token = pm.environment.get("access_token");
if ( currentAccess_token && currentAccess_token.length > 0 ) {
console.log(`Access Token found in Environment: ${currentAccess_token}`);
} else {
currentAccess_token = "";
console.log(`Access Token found empty in Environment.`);
}
} else {
currentAccess_token = "";
console.log(`Access Token not found in Environment and newly added.`);
pm.environment.set("access_token", "");
}
// Refresh Token is received after first request, however due to tenant refresh it could be invalid.
if ( pm.environment.has("refresh_token") ) {
currentRefresh_token = pm.environment.get("refresh_token");
if ( currentRefresh_token && currentRefresh_token.length > 0 ) {
console.log(`Refresh Token found in Environment: ${currentRefresh_token}`);
} else {
currentRefresh_token = "";
console.log(`Refresh Token found empty in Environment.`);
}
} else {
currentRefresh_token = "";
pm.environment.set("refresh_token", "");
console.log(`Refresh Token not found in Environment and newly added.`);
}
// Expires time in milliseconds is received after first request, however due to tenant refresh it could be invalid.
if ( pm.environment.has("expires_in") ) {
currentExpires_in = pm.environment.get("expires_in");
if ( currentExpires_in && currentExpires_in > 0 ) {
console.log(`Expires in found in Environment: ${currentExpires_in}`);
} else {
currentExpires_in = 0;
console.log(`Expires in found empty in Environment.`);
}
} else {
currentExpires_in = 0;
pm.environment.set("expires_in", 0);
console.log(`Expires in not found in Environment and newly added.`);
}
// Refresh time (date type) is received after first request, however due to tenant refresh it could be invalid.
if ( pm.environment.has("refresh_time") ) {
currentRefresh_time = Date.parse(pm.environment.get("refresh_time"));
if ( currentRefresh_time && currentRefresh_time > 0 ) {
console.log(`Refresh time found in Environment: ${currentRefresh_time}`);
} else {
currentRefresh_time = tokenDate;
console.log(`Refresh time found empty in Environment.`);
}
} else {
currentRefresh_time = tokenDate;
pm.environment.set("refresh_time", tokenDate );
console.log(`Refresh time not found in Environment and newly added.`);
}
pm.expect(pm.environment.has('ci')).to.be.true;
pm.expect(pm.environment.has('cs')).to.be.true;
pm.expect(pm.environment.has('pu')).to.be.true;
pm.expect(pm.environment.has('ot')).to.be.true;
pm.expect(pm.environment.has('saak')).to.be.true;
pm.expect(pm.environment.has('sask')).to.be.true;
pm.expect(pm.environment.has('scopes')).to.be.true; // 2022-12-16
let auth_url = pm.environment.get('pu') + pm.environment.get('ot');
console.log(`Authentication URL: ${auth_url}`);
let clientId = pm.environment.get('ci');
console.log(`clientId: ${clientId}`);
let clientSecret = pm.environment.get('cs');
console.log(`clientSecret: ${clientSecret}`);
let userName = pm.environment.get('saak');
console.log(`Username: ${userName}`);
let userPassword = pm.environment.get('sask');
console.log(`Password: ${userPassword}`);
//2022-12-16.sn use comma for multiple scopes, cast it as string first and replace any quotes, commas, or []
let scopesList = pm.environment.get('scopes') + ""; // Cast it as string
console.log(`Scopes: ${scopesList}`);
// replace , between the different scopes with a space
let scopes = (scopesList).replace(/,/g," ");
console.log(`Scopes: ${scopes}`);
// remove any [, ], and "
scopes = (scopes).replace(/[\"\[\]]/g,"");
console.log(`Scopes: ${scopes}`);
//2022-12-16.en
// Constructing the request for refreshing a token
let authorizationToken = 'Bearer ' + currentAccess_token;
console.log(`authorizationToken: ${authorizationToken}`);
let refreshTokenRequest = {
url: auth_url,
method: 'POST',
header: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: {
mode: 'urlencoded',
urlencoded: [
{ key: 'refresh_token', value: currentRefresh_token },
{ key: 'client_id', value: clientId },
{ key: 'client_secret', value: clientSecret },
{ key: 'grant_type', value: 'refresh_token' }
]
}
};
// Constructing the request for a new token
let getTokenRequest = {
url: auth_url,
method: 'POST',
header: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: {
mode: 'urlencoded',
urlencoded: [
{ key: 'grant_type', value: 'password' },
{ key: 'client_id', value: clientId },
{ key: 'client_secret', value: clientSecret },
{ key: 'username', value: userName },
{ key: 'password', value: userPassword },
{ key: 'scope', value: scopes } // 2022-12-16
]
}
};
// If age of current token >= the expiry time including 60 seconds for safety then refresh the token in case a refresh_token is present
// If no token is present then the currentRefresh_time was set to 2000-01-01, currentExpires_in was set to 0 and currentRefresh_token was set empty
currentToken_age = ( ( new Date() - currentRefresh_time ) + 60000 );
console.log(`Current Token is ${currentToken_age} milliseconds old`);
if ( currentToken_age >= currentExpires_in ) {
console.log('Current Token is expired or not valid.');
if (currentRefresh_token.length > 0 ) {
console.log('Token is expired and a refresh token is present, trying to refresh token first.');
pm.sendRequest(refreshTokenRequest, function (err, res) {
// Use the access_token received to set the environment and in the local variables
currentAccess_token = res.json().access_token
if (currentAccess_token) {
pm.environment.set("access_token", currentAccess_token );
console.log(`New access_token after refresh: ${currentAccess_token}`);
// Set the refresh_time to now
pm.environment.set("refresh_time", new Date());
currentRefresh_time = new Date();
// Set the currentExpires_in variable to the time given in the response if it exists
if(res.json().expires_in){
currentExpires_in = res.json().expires_in * 1000;
} else {
currentExpires_in = 0;
}
pm.environment.set("expires_in", currentExpires_in);
console.log(`New access_token after refresh expires in : ${currentExpires_in}`);
console.log('Refreshing token finished');
} else {
console.log('Refreshing token failed, request a new access_token and refresh_token.');
pm.sendRequest(getTokenRequest, function (err, res) {
// Use the access_token received to set the environment and in the local variables
currentAccess_token = res.json().access_token
pm.environment.set("access_token", currentAccess_token );
console.log(`New access_token: ${currentAccess_token}`);
// Use the refresh_token received to set the environment
currentRefresh_token = res.json().refresh_token
pm.environment.set("refresh_token", currentRefresh_token );
console.log(`New refresh_token: ${currentRefresh_token}`);
// Set the refresh_time to now
pm.environment.set("refresh_time", new Date());
currentRefresh_time = new Date();
// Set the currentExpires_in variable to the time given in the response if it exists
if(res.json().expires_in){
currentExpires_in = res.json().expires_in * 1000;
} else {
currentExpires_in = 0;
}
pm.environment.set("expires_in", currentExpires_in);
console.log(`Expires in : ${currentExpires_in}`);
console.log('Getting new token finished.');
});
}
});
} else {
console.log('No refresh_token found, new access_token needed, sendRequest for new token.');
pm.sendRequest(getTokenRequest, function (err, res) {
// Use the access_token received to set the environment and in the local variables
currentAccess_token = res.json().access_token
pm.environment.set("access_token", currentAccess_token );
console.log(`New access_token: ${currentAccess_token}`);
// Use the refresh_token received to set the environment
currentRefresh_token = res.json().refresh_token
pm.environment.set("refresh_token", currentRefresh_token );
console.log(`New refresh_token: ${currentRefresh_token}`);
// Set the refresh_time to now
pm.environment.set("refresh_time", new Date());
currentRefresh_time = new Date();
// Set the currentExpires_in variable to the time given in the response if it exists
if(res.json().expires_in){
currentExpires_in = res.json().expires_in * 1000;
} else {
currentExpires_in = 0;
}
pm.environment.set("expires_in", currentExpires_in);
console.log(`Expires in : ${currentExpires_in}`);
console.log('Getting new token finished.');
});
}
} else {
console.log(`Existing access_token is used, else manually empty the environment variable access_token and refresh_token!`);
}