@oneidentity/safeguard 1.0.5 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,7 +47,7 @@ A simple code example for calling the Safeguard API for authentication through t
47
47
  // Browser Example
48
48
  SafeguardJs.connectRsts('safeguard.sample.corp', `${window.location.protocol}//${window.location.host}${window.location.pathname}`)
49
49
  .then((connection) => {
50
- connection.invoke(SafeguardJs.Services.CORE, SafeguardJs.HttpMethods.GET, 'v3/Me')
50
+ connection.invoke(SafeguardJs.Services.CORE, SafeguardJs.HttpMethods.GET, 'v4/Me')
51
51
  .then((results) => {
52
52
  console.log(results);
53
53
  });
@@ -197,7 +197,7 @@ Sample can be found <a href="samples\Browser\Promises\AnonymousExample">here</a>
197
197
  // Browser Example
198
198
  SafeguardJs.connectAnonymous('safeguard.sample.corp', saveConnectionCallback)
199
199
  .then((connection) => {
200
- connection.invoke(SafeguardJs.Services.NOTIFICATION, SafeguardJs.HttpMethods.GET, 'v3/Status')
200
+ connection.invoke(SafeguardJs.Services.NOTIFICATION, SafeguardJs.HttpMethods.GET, 'v4/Status')
201
201
  .then((results) => {
202
202
  console.log(results);
203
203
  });
@@ -211,7 +211,7 @@ Sample can be found <a href="samples\Node.JS\anonymousExample.js">here</a>.
211
211
  let localStorage = new require('src/LocalStorage').LocalStorage;
212
212
  SafeguardJs.addCAFromFile(caFile);
213
213
  let connection = await SafeguardJs.connectAnonymous(hostName, null, localStorage);
214
- let result = await connection.invoke(SafeguardJs.Services.NOTIFICATION, SafeguardJs.HttpMethods.GET, 'v3/Status');
214
+ let result = await connection.invoke(SafeguardJs.Services.NOTIFICATION, SafeguardJs.HttpMethods.GET, 'v4/Status');
215
215
  console.log(result);
216
216
  ```
217
217
 
@@ -270,10 +270,10 @@ let password = 'MyNewUser123';
270
270
 
271
271
  SafeguardJs.connectRsts('safeguard.sample.corp', `${window.location.protocol}//${window.location.host}${window.location.pathname}`)
272
272
  .then((connection) => {
273
- connection.invoke(SafeguardJs.Services.CORE, SafeguardJs.HttpMethods.POST, 'v3/Users', user)
273
+ connection.invoke(SafeguardJs.Services.CORE, SafeguardJs.HttpMethods.POST, 'v4/Users', user)
274
274
  .then((results) => {
275
275
  let newUser = JSON.parse(results);
276
- connection.invoke(SafeguardJs.Services.CORE, SafeguardJs.HttpMethods.PUT, `v3/Users/${newUser.Id}/Password`, `"${password}"`);
276
+ connection.invoke(SafeguardJs.Services.CORE, SafeguardJs.HttpMethods.PUT, `v4/Users/${newUser.Id}/Password`, `"${password}"`);
277
277
  });
278
278
  });
279
279
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneidentity/safeguard",
3
- "version": "1.0.5",
3
+ "version": "7.4.0",
4
4
  "description": "One Identity Safeguard JavaScript SDK",
5
5
  "main": "src/safeguard.js",
6
6
  "browser": {
@@ -34,7 +34,8 @@
34
34
  "dependencies": {
35
35
  "@microsoft/signalr": "^5.0.4",
36
36
  "axios": "^0.21.1",
37
- "ssl-root-cas": "^1.3.1"
37
+ "ssl-root-cas": "^1.3.1",
38
+ "crypto-js": "~4.1.1"
38
39
  },
39
40
  "devDependencies": {
40
41
  "browserify": "^17.0.0",
@@ -14,7 +14,12 @@ class SessionStorage {
14
14
  SessionStorageKeys = {
15
15
  ACCESSTOKEN: 'AccessToken',
16
16
  USERTOKEN: 'UserToken',
17
- HOSTNAME: 'HostName'
17
+ HOSTNAME: 'HostName',
18
+ CODEVERIFIER: 'CodeVerifier',
19
+ RANDOMSTATE: 'RandomState',
20
+ CODE: 'Code',
21
+ STATE: 'State',
22
+ NEWLOGIN: 'NewLogin'
18
23
  }
19
24
 
20
25
  /**
@@ -25,6 +30,38 @@ class SessionStorage {
25
30
  return sessionStorage.getItem(this.SessionStorageKeys.ACCESSTOKEN);
26
31
  }
27
32
 
33
+ /**
34
+ * Gets the access pkce code from storage.
35
+ * @returns {string} The pkce code.
36
+ */
37
+ getCode() {
38
+ return sessionStorage.getItem(this.SessionStorageKeys.CODE);
39
+ }
40
+
41
+ /**
42
+ * Gets the access pkce code verifier from storage.
43
+ * @returns {string} The pkce verifier code.
44
+ */
45
+ getCodeVerifier() {
46
+ return sessionStorage.getItem(this.SessionStorageKeys.CODEVERIFIER);
47
+ }
48
+
49
+ /**
50
+ * Gets the access random state from storage.
51
+ * @returns {string} The random state.
52
+ */
53
+ getRandomState() {
54
+ return sessionStorage.getItem(this.SessionStorageKeys.RANDOMSTATE);
55
+ }
56
+
57
+ /**
58
+ * Gets the access pkce state from storage.
59
+ * @returns {string} The pkce state.
60
+ */
61
+ getState() {
62
+ return sessionStorage.getItem(this.SessionStorageKeys.STATE);
63
+ }
64
+
28
65
  /**
29
66
  * Gets the user token from storage.
30
67
  * @returns {string} The user token.
@@ -41,6 +78,14 @@ class SessionStorage {
41
78
  return sessionStorage.getItem(this.SessionStorageKeys.HOSTNAME);
42
79
  }
43
80
 
81
+ /**
82
+ * Gets the new login flag from storage.
83
+ * @returns {string} The new login flag.
84
+ */
85
+ getNewLogin(){
86
+ return sessionStorage.getItem(this.SessionStorageKeys.NEWLOGIN);
87
+ }
88
+
44
89
  /**
45
90
  * Writes the access token to storage.
46
91
  */
@@ -48,6 +93,34 @@ class SessionStorage {
48
93
  sessionStorage.setItem(this.SessionStorageKeys.ACCESSTOKEN, accessToken);
49
94
  }
50
95
 
96
+ /**
97
+ * Writes the access pkce code to storage.
98
+ */
99
+ setCode(code) {
100
+ sessionStorage.setItem(this.SessionStorageKeys.CODE, code);
101
+ }
102
+
103
+ /**
104
+ * Writes the access pkce code verifier to storage.
105
+ */
106
+ setCodeVerifier(codeVerifier) {
107
+ sessionStorage.setItem(this.SessionStorageKeys.CODEVERIFIER, codeVerifier);
108
+ }
109
+
110
+ /**
111
+ * Writes the access random state to storage.
112
+ */
113
+ setRandomState(state) {
114
+ sessionStorage.setItem(this.SessionStorageKeys.RANDOMSTATE, state);
115
+ }
116
+
117
+ /**
118
+ * Writes the access pkce state to storage.
119
+ */
120
+ setState(state) {
121
+ sessionStorage.setItem(this.SessionStorageKeys.STATE, state);
122
+ }
123
+
51
124
  /**
52
125
  * Writes the user token to storage.
53
126
  */
@@ -62,28 +135,35 @@ class SessionStorage {
62
135
  sessionStorage.setItem(this.SessionStorageKeys.HOSTNAME, hostName);
63
136
  }
64
137
 
138
+ /**
139
+ * Writes the new login flag to storage.
140
+ */
141
+ setNewLogin(newLogin) {
142
+ sessionStorage.setItem(this.SessionStorageKeys.NEWLOGIN, newLogin);
143
+ }
144
+
145
+ /**
146
+ * Clears code and state from storage.
147
+ */
148
+ clearPKCEStorage() {
149
+ sessionStorage.removeItem(this.SessionStorageKeys.CODE);
150
+ sessionStorage.removeItem(this.SessionStorageKeys.STATE);
151
+ sessionStorage.removeItem(this.SessionStorageKeys.CODEVERIFIER);
152
+ sessionStorage.removeItem(this.SessionStorageKeys.RANDOMSTATE);
153
+ }
154
+
65
155
  /**
66
156
  * Clears all values from storage.
67
157
  */
68
158
  clearStorage() {
69
- let userToken = this.getUserToken();
70
- let accessToken = this.getAccessToken();
71
- let sessionHostName = this.getHostName();
72
-
73
- if (userToken)
74
- {
75
- this.setUserToken('');
76
- }
77
-
78
- if (accessToken)
79
- {
80
- this.setAccessToken('');
81
- }
82
-
83
- if (sessionHostName)
84
- {
85
- this.setHostName('');
86
- }
159
+ sessionStorage.removeItem(this.SessionStorageKeys.USERTOKEN);
160
+ sessionStorage.removeItem(this.SessionStorageKeys.ACCESSTOKEN);
161
+ sessionStorage.removeItem(this.SessionStorageKeys.HOSTNAME);
162
+ sessionStorage.removeItem(this.SessionStorageKeys.CODE);
163
+ sessionStorage.removeItem(this.SessionStorageKeys.CODEVERIFIER);
164
+ sessionStorage.removeItem(this.SessionStorageKeys.STATE);
165
+ sessionStorage.removeItem(this.SessionStorageKeys.RANDOMSTATE);
166
+ sessionStorage.removeItem(this.SessionStorageKeys.NEWLOGIN);
87
167
  }
88
168
  }
89
169
 
package/src/safeguard.js CHANGED
@@ -4,6 +4,7 @@ const AXIOS = require('axios');
4
4
  const HTTPS = require('https');
5
5
  const LS = require('./LocalStorage');
6
6
  const SS = require('./SessionStorage');
7
+ const CryptoJS = require('crypto-js');
7
8
 
8
9
  /**
9
10
  * SafeguardJs
@@ -77,6 +78,30 @@ const SafeguardJs = {
77
78
  }
78
79
  },
79
80
 
81
+ /**
82
+ * (Internal) Saves the access token to storage.
83
+ *
84
+ * @param {string} data String representation of JSON object returned from the
85
+ * Safeguard appliance containing the access token.
86
+ */
87
+ _saveAccessToken: (err, data) => {
88
+ if (err) {
89
+ throw new Error('Failed to save access token.');
90
+ }
91
+
92
+ try {
93
+ let obj = JSON.parse(data);
94
+ if (obj.success) {
95
+ SafeguardJs.Storage.setAccessToken(obj.access_token);
96
+ } else {
97
+ throw new Error('Failed to save access token.');
98
+ }
99
+ }
100
+ catch(ex) {
101
+ throw new Error('Failed to save access token.');
102
+ }
103
+ },
104
+
80
105
  /**
81
106
  * (Internal) Executes an HTTP request.
82
107
  *
@@ -181,50 +206,34 @@ const SafeguardJs = {
181
206
  },
182
207
 
183
208
  /**
184
- * (Internal) Gets the provider id for a given provider.
209
+ * (Internal) Gets the provider scope for a given provider.
185
210
  *
186
211
  * @param {string} hostName (Required) The name or ip of the safeguard appliance.
187
212
  * @param {string} defaultProvider (Required) The id of the default provider.
188
213
  * @param {string} provider (Optional) The name or id of the provider to use. Default is local.
189
214
  */
190
- _getProviderId: async (hostName, defaultProvider, provider) => {
215
+ _getProviderScope: async (hostName, defaultProvider, provider) => {
191
216
  if (provider == null || provider === "" || provider.toUpperCase() == "LOCAL" || provider.toUpperCase() == "CERTIFICATE") {
192
217
  return defaultProvider;
193
218
  }
194
-
195
- let headers = {
196
- "accept": "application/json",
197
- "content-type": "application/x-www-form-urlencoded"
198
- }
199
-
200
- let bodyData = {
201
- "RelayState" : ""
202
- };
203
219
 
204
- let result = null;
220
+ let results = null;
205
221
 
206
- try
207
- {
208
- result = await SafeguardJs._executePromise(`https://${hostName}/RSTS/UserLogin/LoginController?response_type=token&redirect_uri=urn:InstalledApplication&loginRequestStep=1`, SafeguardJs.HttpMethods.POST, bodyData, 'json', headers);
209
- result = JSON.parse(result);
222
+ try {
223
+ results = await SafeguardJs._executePromise(`https://${hostName}/service/core/v4/AuthenticationProviders`, SafeguardJs.HttpMethods.GET, null, 'json', null, null, null);
224
+ results = JSON.parse(results);
210
225
  } catch (err) {
211
- try {
212
- // Retry as a GET
213
- result = await SafeguardJs._executePromise(`https://${hostName}/RSTS/UserLogin/LoginController?response_type=token&redirect_uri=urn:InstalledApplication&loginRequestStep=1`, SafeguardJs.HttpMethods.GET, bodyData, 'json', headers);
214
- result = JSON.parse(result);
215
- } catch (err) {
216
- throw new Error(`Could not find the provider: '${provider}'. ${err}`);
217
- }
226
+ throw new Error(`Could not find the provider: '${provider}'. ${err}`);
218
227
  }
219
228
 
220
229
  try {
221
- for (const p of result.Providers) {
222
- if (provider.toUpperCase() == p.DisplayName.toUpperCase()) {
223
- return p.Id;
224
- } else if (provider.toUpperCase() == p.Id.toUpperCase()) {
225
- return p.Id;
226
- } else if (p.Id.toUpperCase().includes(provider.toUpperCase())) {
227
- return p.Id;
230
+ for (const p of results) {
231
+ if (provider.toUpperCase() == p.Name.toUpperCase()) {
232
+ return p.RstsProviderScope;
233
+ } else if (provider.toUpperCase() == p.RstsProviderId.toUpperCase()) {
234
+ return p.RstsProviderScope;
235
+ } else if (p.RstsProviderId.toUpperCase().includes(provider.toUpperCase())) {
236
+ return p.RstsProviderScope;
228
237
  }
229
238
  }
230
239
  } catch (err) {
@@ -234,6 +243,18 @@ const SafeguardJs = {
234
243
  throw new Error(`Could not find the provider: '${provider}'`);
235
244
  },
236
245
 
246
+ oAuthCodeVerifier: () => {
247
+ return SafeguardJs.toBase64Url(CryptoJS.lib.WordArray.random(30));
248
+ },
249
+
250
+ oAuthCodeChallenge: (codeVerifier) => {
251
+ return SafeguardJs.toBase64Url(CryptoJS.SHA256(codeVerifier));
252
+ },
253
+
254
+ toBase64Url: (data) => {
255
+ return CryptoJS.enc.Base64.stringify(data).replace(/[=]/gi, '').replace(/[+]/gi, '-').replace(/[/]/gi, '_');
256
+ },
257
+
237
258
  /**
238
259
  * (Internal) Gets the RSTS URL with a given redirect.
239
260
  *
@@ -241,14 +262,20 @@ const SafeguardJs = {
241
262
  * @param {string} redirectTo The redirect URL to be used after successful authentication.
242
263
  */
243
264
  _loginUrl: (hostName, redirectTo) => {
244
- return `https://${hostName}/RSTS/Login?response_type=token&redirect_uri=${encodeURIComponent(redirectTo)}`;
265
+ var codeVerifier = SafeguardJs.oAuthCodeVerifier();
266
+ var randomState = SafeguardJs.oAuthCodeVerifier();
267
+
268
+ SafeguardJs.Storage.setCodeVerifier(codeVerifier);
269
+ SafeguardJs.Storage.setRandomState(randomState);
270
+
271
+ return `https://${hostName}/RSTS/Login?response_type=code&code_challenge_method=S256&code_challenge=${SafeguardJs.oAuthCodeChallenge(codeVerifier)}&state=${randomState}&redirect_uri=${encodeURIComponent(redirectTo)}`;
245
272
  },
246
273
 
247
274
  /**
248
275
  * (Internal) Redirects the current window to the login page.
249
276
  *
250
- * @param {string} hostName The name or ip of the safeguard appliance.
251
- * @param {string} redirectTo The redirect URL to be used after successful authentication.
277
+ * @param {string} hostName The name or ip of the safeguard appliance.
278
+ * @param {string} redirectTo The redirect URL to be used after successful authentication.
252
279
  */
253
280
  _goToLogin: (hostName, redirectTo) => {
254
281
  window.location = SafeguardJs._loginUrl(hostName, redirectTo);
@@ -257,16 +284,37 @@ const SafeguardJs = {
257
284
  /**
258
285
  * (Internal) Contacts the safeguard appliance to trade an access token for a user token.
259
286
  *
260
- * @param {string} accessToken The access token to trade.
261
- * @param {string} hostName The name or ip of the safeguard appliance.
287
+ * @param {string} accessToken The access token to trade.
288
+ * @param {string} hostName The name or ip of the safeguard appliance.
262
289
  */
263
290
  _tradeForUserToken: (accessToken, hostName) => {
264
- let url = `https://${hostName}/service/core/v3/Token/LoginResponse`;
291
+ let url = `https://${hostName}/service/core/v4/Token/LoginResponse`;
265
292
  body = {
266
293
  "StsAccessToken" : accessToken
267
294
  }
268
295
 
269
- SafeguardJs._executePromise(url, SafeguardJs.HttpMethods.POST, body, 'json', null, SafeguardJs._saveUserToken);
296
+ return SafeguardJs._executePromise(url, SafeguardJs.HttpMethods.POST, body, 'json', null, SafeguardJs._saveUserToken);
297
+ },
298
+
299
+ /**
300
+ * (Internal) Contacts the rsts to trade a code for an access token.
301
+ *
302
+ * @param {string} code The code to trade.
303
+ * @param {string} codeVerifier The code verifier.
304
+ * @param {string} hostName The name or ip of the safeguard appliance.
305
+ */
306
+ _tradeForAccessToken: (code, codeVerifier, hostName) => {
307
+ let url = `https://${hostName}/RSTS/oauth2/token`;
308
+ body = new URLSearchParams({
309
+ grant_type: "authorization_code",
310
+ code: code,
311
+ code_verifier: codeVerifier
312
+ });
313
+ let headers = {
314
+ "content-type": "application/x-www-form-urlencoded"
315
+ }
316
+
317
+ return SafeguardJs._executePromise(url, SafeguardJs.HttpMethods.POST, body, 'json', headers, SafeguardJs._saveAccessToken);
270
318
  },
271
319
 
272
320
  /**
@@ -303,6 +351,8 @@ const SafeguardJs = {
303
351
 
304
352
  let userToken = SafeguardJs.Storage.getUserToken();
305
353
  let accessToken = SafeguardJs.Storage.getAccessToken();
354
+ let code = SafeguardJs.Storage.getCode();
355
+ let state = SafeguardJs.Storage.getState();
306
356
 
307
357
  if (userToken) {
308
358
  let connection = new SafeguardJs.SafeguardConnection(hostName);
@@ -310,6 +360,7 @@ const SafeguardJs = {
310
360
  callback(connection);
311
361
  }
312
362
  return connection;
363
+
313
364
  } else if (accessToken) {
314
365
  SafeguardJs._tradeForUserToken(accessToken, hostName);
315
366
  let connection = new SafeguardJs.SafeguardConnection(hostName);
@@ -317,6 +368,25 @@ const SafeguardJs = {
317
368
  callback(connection);
318
369
  }
319
370
  return connection;
371
+
372
+ } else if (code && state) {
373
+ let codeVerifier = SafeguardJs.Storage.getCodeVerifier();
374
+ let randomState = SafeguardJs.Storage.getRandomState();
375
+
376
+ SafeguardJs.Storage.clearPKCEStorage();
377
+
378
+ if (state == randomState) {
379
+ SafeguardJs._tradeForAccessToken(code, codeVerifier, hostName)
380
+ .then(() => {
381
+ accessToken = SafeguardJs.Storage.getAccessToken();
382
+ SafeguardJs._tradeForUserToken(accessToken, hostName);
383
+ let connection = new SafeguardJs.SafeguardConnection(hostName);
384
+ if (callback) {
385
+ callback(connection);
386
+ }
387
+ return connection;
388
+ });
389
+ }
320
390
  } else {
321
391
  getAccessToken();
322
392
  }
@@ -396,7 +466,7 @@ const SafeguardJs = {
396
466
  throw new Error('password may not be null or empty');
397
467
  }
398
468
 
399
- let providerId = await SafeguardJs._getProviderId(hostName, 'local', provider);
469
+ let providerScope = await SafeguardJs._getProviderScope(hostName, 'local', provider);
400
470
 
401
471
  if (storage) {
402
472
  SafeguardJs.Storage = storage;
@@ -411,7 +481,7 @@ const SafeguardJs = {
411
481
  "grant_type" : "password",
412
482
  "username" : userName,
413
483
  "password" : password,
414
- "scope" : `rsts:sts:primaryproviderid:${providerId}`
484
+ "scope" : providerScope
415
485
  };
416
486
 
417
487
  let accessToken = await SafeguardJs._executePromise(`https://${hostName}/RSTS/oauth2/token`, SafeguardJs.HttpMethods.POST, bodyData, 'json', null, null, null);
@@ -421,7 +491,7 @@ const SafeguardJs = {
421
491
  "StsAccessToken" : SafeguardJs.Storage.getAccessToken()
422
492
  };
423
493
 
424
- let stsToken = await SafeguardJs._executePromise(`https://${hostName}/service/core/v3/Token/LoginResponse`, SafeguardJs.HttpMethods.POST, bodyData, 'json', null, null, null);
494
+ let stsToken = await SafeguardJs._executePromise(`https://${hostName}/service/core/v4/Token/LoginResponse`, SafeguardJs.HttpMethods.POST, bodyData, 'json', null, null, null);
425
495
  SafeguardJs.Storage.setUserToken(JSON.parse(stsToken).UserToken);
426
496
 
427
497
  let connection = new SafeguardJs.SafeguardConnection(hostName);
@@ -462,7 +532,7 @@ const SafeguardJs = {
462
532
  throw new Error('passphrase may not be null or empty');
463
533
  }
464
534
 
465
- let providerId = await SafeguardJs._getProviderId(hostName, 'certificate', provider);
535
+ let providerScope = await SafeguardJs._getProviderScope(hostName, 'certificate', provider);
466
536
 
467
537
  if (storage) {
468
538
  SafeguardJs.Storage = storage;
@@ -475,7 +545,7 @@ const SafeguardJs = {
475
545
  try {
476
546
  let bodyData = {
477
547
  "grant_type" : "client_credentials",
478
- "scope" : `rsts:sts:primaryproviderid:${providerId}`
548
+ "scope" : providerScope
479
549
  };
480
550
 
481
551
  let httpsAgent = new HTTPS.Agent({
@@ -493,7 +563,7 @@ const SafeguardJs = {
493
563
  "StsAccessToken" : SafeguardJs.Storage.getAccessToken()
494
564
  };
495
565
 
496
- let stsToken = await SafeguardJs._executePromise(`https://${hostName}/service/core/v3/Token/LoginResponse`, SafeguardJs.HttpMethods.POST, bodyData, 'json');
566
+ let stsToken = await SafeguardJs._executePromise(`https://${hostName}/service/core/v4/Token/LoginResponse`, SafeguardJs.HttpMethods.POST, bodyData, 'json');
497
567
  SafeguardJs.Storage.setUserToken(JSON.parse(stsToken).UserToken);
498
568
 
499
569
  let connection = new SafeguardJs.SafeguardConnection(hostName);
@@ -611,7 +681,7 @@ const SafeguardJs = {
611
681
  'authorization': `A2A ${apiKey}`
612
682
  }
613
683
 
614
- let credential = await SafeguardJs._executePromise(`https://${hostName}/service/a2a/v3/Credentials?type=${type}&keyFormat=${keyFormat}`, SafeguardJs.HttpMethods.GET, null, 'json', additionalHeaders, null, null, httpsAgent);
684
+ let credential = await SafeguardJs._executePromise(`https://${hostName}/service/a2a/v4/Credentials?type=${type}&keyFormat=${keyFormat}`, SafeguardJs.HttpMethods.GET, null, 'json', additionalHeaders, null, null, httpsAgent);
615
685
 
616
686
  // Remove any leading or trailing quotes that were added from string conversion
617
687
  if (credential.slice(0, 1) === '"') {
@@ -711,19 +781,14 @@ const SafeguardJs = {
711
781
  switch(service) {
712
782
  case SafeguardJs.Services.CORE:
713
783
  return `${baseUrl}core/${relativeUrl}`;
714
- break;
715
784
  case SafeguardJs.Services.APPLIANCE:
716
785
  return `${baseUrl}appliance/${relativeUrl}`;
717
- break;
718
786
  case SafeguardJs.Services.NOTIFICATION:
719
787
  return `${baseUrl}notification/${relativeUrl}`;
720
- break;
721
788
  case SafeguardJs.Services.A2A:
722
789
  return `${baseUrl}a2a/${relativeUrl}`;
723
- break;
724
790
  default:
725
791
  throw new Error(`Unsupported service requested: '${service}'.`);
726
- break;
727
792
  }
728
793
  }
729
794
 
@@ -748,7 +813,7 @@ const SafeguardJs = {
748
813
  */
749
814
  async getAccessTokenLifetimeRemaining(callback) {
750
815
  let bearerToken = this._getBearerToken();
751
- let url = this._constructUrl(SafeguardJs.Services.CORE, 'v3/LoginMessage', null);
816
+ let url = this._constructUrl(SafeguardJs.Services.CORE, 'v4/LoginMessage', null);
752
817
  let additionalHeaders = {
753
818
  'authorization': bearerToken,
754
819
  'X-TokenLifetimeRemaining': ''
@@ -769,7 +834,7 @@ const SafeguardJs = {
769
834
  */
770
835
  async logout(callback) {
771
836
  let bearerToken = this._getBearerToken();
772
- let url = this._constructUrl(SafeguardJs.Services.CORE, 'v3/Token/Logout', null);
837
+ let url = this._constructUrl(SafeguardJs.Services.CORE, 'v4/Token/Logout', null);
773
838
  let additionalHeaders = {
774
839
  'authorization': bearerToken
775
840
  }