@azure/msal-node-extensions 1.0.0-alpha.2 → 1.0.0-alpha.22

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.
Files changed (45) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +193 -42
  3. package/binding.gyp +29 -29
  4. package/dist/error/PersistenceError.d.ts +32 -4
  5. package/dist/index.d.ts +3 -0
  6. package/dist/msal-node-extensions.cjs.development.js +615 -849
  7. package/dist/msal-node-extensions.cjs.development.js.map +1 -1
  8. package/dist/msal-node-extensions.cjs.production.min.js +1 -1
  9. package/dist/msal-node-extensions.cjs.production.min.js.map +1 -1
  10. package/dist/msal-node-extensions.esm.js +625 -864
  11. package/dist/msal-node-extensions.esm.js.map +1 -1
  12. package/dist/persistence/BasePersistence.d.ts +5 -0
  13. package/dist/persistence/FilePersistence.d.ts +4 -2
  14. package/dist/persistence/FilePersistenceWithDataProtection.d.ts +3 -1
  15. package/dist/persistence/IPersistence.d.ts +3 -1
  16. package/dist/persistence/IPersistenceConfiguration.d.ts +8 -0
  17. package/dist/persistence/KeychainPersistence.d.ts +3 -1
  18. package/dist/persistence/LibSecretPersistence.d.ts +3 -1
  19. package/dist/persistence/PersistenceCachePlugin.d.ts +11 -7
  20. package/dist/persistence/PersistenceCreator.d.ts +5 -0
  21. package/dist/utils/Constants.d.ts +31 -0
  22. package/dist/utils/Environment.d.ts +16 -0
  23. package/package.json +27 -14
  24. package/src/dpapi-addon/Dpapi.ts +17 -12
  25. package/src/dpapi-addon/dpapi_addon.h +6 -6
  26. package/src/dpapi-addon/dpapi_not_supported.cpp +19 -19
  27. package/src/dpapi-addon/dpapi_win.cpp +114 -114
  28. package/src/dpapi-addon/main.cpp +32 -32
  29. package/src/error/PersistenceError.ts +101 -65
  30. package/src/index.ts +16 -8
  31. package/src/lock/CrossPlatformLock.ts +89 -82
  32. package/src/lock/CrossPlatformLockOptions.ts +15 -15
  33. package/src/persistence/BasePersistence.ts +41 -0
  34. package/src/persistence/DataProtectionScope.ts +20 -20
  35. package/src/persistence/FilePersistence.ts +140 -134
  36. package/src/persistence/FilePersistenceWithDataProtection.ts +92 -84
  37. package/src/persistence/IPersistence.ts +17 -15
  38. package/src/persistence/IPersistenceConfiguration.ts +14 -0
  39. package/src/persistence/KeychainPersistence.ts +86 -78
  40. package/src/persistence/LibSecretPersistence.ts +87 -79
  41. package/src/persistence/PersistenceCachePlugin.ts +106 -96
  42. package/src/persistence/PersistenceCreator.ts +73 -0
  43. package/src/utils/Constants.ts +62 -24
  44. package/src/utils/Environment.ts +99 -0
  45. package/changelog.md +0 -14
@@ -2,203 +2,20 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
+
5
7
  var fs = require('fs');
6
- var process = require('process');
8
+ var process$1 = require('process');
7
9
  var path = require('path');
10
+ var path__default = _interopDefault(path);
8
11
  var msalCommon = require('@azure/msal-common');
9
12
  var keytar = require('keytar');
10
13
 
11
- // A type of promise-like that resolves synchronously and supports only one observer
12
- const _Pact = /*#__PURE__*/(function() {
13
- function _Pact() {}
14
- _Pact.prototype.then = function(onFulfilled, onRejected) {
15
- const result = new _Pact();
16
- const state = this.s;
17
- if (state) {
18
- const callback = state & 1 ? onFulfilled : onRejected;
19
- if (callback) {
20
- try {
21
- _settle(result, 1, callback(this.v));
22
- } catch (e) {
23
- _settle(result, 2, e);
24
- }
25
- return result;
26
- } else {
27
- return this;
28
- }
29
- }
30
- this.o = function(_this) {
31
- try {
32
- const value = _this.v;
33
- if (_this.s & 1) {
34
- _settle(result, 1, onFulfilled ? onFulfilled(value) : value);
35
- } else if (onRejected) {
36
- _settle(result, 1, onRejected(value));
37
- } else {
38
- _settle(result, 2, value);
39
- }
40
- } catch (e) {
41
- _settle(result, 2, e);
42
- }
43
- };
44
- return result;
45
- };
46
- return _Pact;
47
- })();
48
-
49
- // Settles a pact synchronously
50
- function _settle(pact, state, value) {
51
- if (!pact.s) {
52
- if (value instanceof _Pact) {
53
- if (value.s) {
54
- if (state & 1) {
55
- state = value.s;
56
- }
57
- value = value.v;
58
- } else {
59
- value.o = _settle.bind(null, pact, state);
60
- return;
61
- }
62
- }
63
- if (value && value.then) {
64
- value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2));
65
- return;
66
- }
67
- pact.s = state;
68
- pact.v = value;
69
- const observer = pact.o;
70
- if (observer) {
71
- observer(pact);
72
- }
73
- }
74
- }
75
-
76
- function _isSettledPact(thenable) {
77
- return thenable instanceof _Pact && thenable.s & 1;
78
- }
79
-
80
- const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator";
81
-
82
- const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator";
83
-
84
- // Asynchronously implement a generic for loop
85
- function _for(test, update, body) {
86
- var stage;
87
- for (;;) {
88
- var shouldContinue = test();
89
- if (_isSettledPact(shouldContinue)) {
90
- shouldContinue = shouldContinue.v;
91
- }
92
- if (!shouldContinue) {
93
- return result;
94
- }
95
- if (shouldContinue.then) {
96
- stage = 0;
97
- break;
98
- }
99
- var result = body();
100
- if (result && result.then) {
101
- if (_isSettledPact(result)) {
102
- result = result.s;
103
- } else {
104
- stage = 1;
105
- break;
106
- }
107
- }
108
- if (update) {
109
- var updateValue = update();
110
- if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
111
- stage = 2;
112
- break;
113
- }
114
- }
115
- }
116
- var pact = new _Pact();
117
- var reject = _settle.bind(null, pact, 2);
118
- (stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);
119
- return pact;
120
- function _resumeAfterBody(value) {
121
- result = value;
122
- do {
123
- if (update) {
124
- updateValue = update();
125
- if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
126
- updateValue.then(_resumeAfterUpdate).then(void 0, reject);
127
- return;
128
- }
129
- }
130
- shouldContinue = test();
131
- if (!shouldContinue || (_isSettledPact(shouldContinue) && !shouldContinue.v)) {
132
- _settle(pact, 1, result);
133
- return;
134
- }
135
- if (shouldContinue.then) {
136
- shouldContinue.then(_resumeAfterTest).then(void 0, reject);
137
- return;
138
- }
139
- result = body();
140
- if (_isSettledPact(result)) {
141
- result = result.v;
142
- }
143
- } while (!result || !result.then);
144
- result.then(_resumeAfterBody).then(void 0, reject);
145
- }
146
- function _resumeAfterTest(shouldContinue) {
147
- if (shouldContinue) {
148
- result = body();
149
- if (result && result.then) {
150
- result.then(_resumeAfterBody).then(void 0, reject);
151
- } else {
152
- _resumeAfterBody(result);
153
- }
154
- } else {
155
- _settle(pact, 1, result);
156
- }
157
- }
158
- function _resumeAfterUpdate() {
159
- if (shouldContinue = test()) {
160
- if (shouldContinue.then) {
161
- shouldContinue.then(_resumeAfterTest).then(void 0, reject);
162
- } else {
163
- _resumeAfterTest(shouldContinue);
164
- }
165
- } else {
166
- _settle(pact, 1, result);
167
- }
168
- }
169
- }
170
-
171
- // Asynchronously call a function and send errors to recovery continuation
172
- function _catch(body, recover) {
173
- try {
174
- var result = body();
175
- } catch(e) {
176
- return recover(e);
177
- }
178
- if (result && result.then) {
179
- return result.then(void 0, recover);
180
- }
181
- return result;
182
- }
183
-
184
- // Asynchronously await a promise and pass the result to a finally continuation
185
- function _finallyRethrows(body, finalizer) {
186
- try {
187
- var result = body();
188
- } catch (e) {
189
- return finalizer(true, e);
190
- }
191
- if (result && result.then) {
192
- return result.then(finalizer.bind(null, false), finalizer.bind(null, true));
193
- }
194
- return finalizer(false, result);
195
- }
196
-
197
14
  /*
198
15
  * Copyright (c) Microsoft Corporation. All rights reserved.
199
16
  * Licensed under the MIT License.
200
17
  */
201
- var Constants = {
18
+ const Constants = {
202
19
  /**
203
20
  * An existing file was the target of an operation that required that the target not exist
204
21
  */
@@ -212,108 +29,48 @@ var Constants = {
212
29
  ENOENT_ERROR: "ENOENT",
213
30
 
214
31
  /**
215
- * Default service name for using MSAL Keytar
32
+ * Operation not permitted. An attempt was made to perform an operation that requires
33
+ * elevated privileges.
216
34
  */
217
- DEFAULT_SERVICE_NAME: "msal-node-extensions"
218
- };
219
-
220
- function _inheritsLoose(subClass, superClass) {
221
- subClass.prototype = Object.create(superClass.prototype);
222
- subClass.prototype.constructor = subClass;
223
- subClass.__proto__ = superClass;
224
- }
225
-
226
- function _getPrototypeOf(o) {
227
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
228
- return o.__proto__ || Object.getPrototypeOf(o);
229
- };
230
- return _getPrototypeOf(o);
231
- }
232
-
233
- function _setPrototypeOf(o, p) {
234
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
235
- o.__proto__ = p;
236
- return o;
237
- };
238
-
239
- return _setPrototypeOf(o, p);
240
- }
241
-
242
- function _isNativeReflectConstruct() {
243
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
244
- if (Reflect.construct.sham) return false;
245
- if (typeof Proxy === "function") return true;
246
-
247
- try {
248
- Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
249
- return true;
250
- } catch (e) {
251
- return false;
252
- }
253
- }
35
+ EPERM_ERROR: "EPERM",
254
36
 
255
- function _construct(Parent, args, Class) {
256
- if (_isNativeReflectConstruct()) {
257
- _construct = Reflect.construct;
258
- } else {
259
- _construct = function _construct(Parent, args, Class) {
260
- var a = [null];
261
- a.push.apply(a, args);
262
- var Constructor = Function.bind.apply(Parent, a);
263
- var instance = new Constructor();
264
- if (Class) _setPrototypeOf(instance, Class.prototype);
265
- return instance;
266
- };
267
- }
268
-
269
- return _construct.apply(null, arguments);
270
- }
271
-
272
- function _isNativeFunction(fn) {
273
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
274
- }
275
-
276
- function _wrapNativeSuper(Class) {
277
- var _cache = typeof Map === "function" ? new Map() : undefined;
278
-
279
- _wrapNativeSuper = function _wrapNativeSuper(Class) {
280
- if (Class === null || !_isNativeFunction(Class)) return Class;
281
-
282
- if (typeof Class !== "function") {
283
- throw new TypeError("Super expression must either be null or a function");
284
- }
285
-
286
- if (typeof _cache !== "undefined") {
287
- if (_cache.has(Class)) return _cache.get(Class);
288
-
289
- _cache.set(Class, Wrapper);
290
- }
291
-
292
- function Wrapper() {
293
- return _construct(Class, arguments, _getPrototypeOf(this).constructor);
294
- }
37
+ /**
38
+ * Default service name for using MSAL Keytar
39
+ */
40
+ DEFAULT_SERVICE_NAME: "msal-node-extensions",
295
41
 
296
- Wrapper.prototype = Object.create(Class.prototype, {
297
- constructor: {
298
- value: Wrapper,
299
- enumerable: false,
300
- writable: true,
301
- configurable: true
302
- }
303
- });
304
- return _setPrototypeOf(Wrapper, Class);
305
- };
42
+ /**
43
+ * Test data used to verify underlying persistence mechanism
44
+ */
45
+ PERSISTENCE_TEST_DATA: "Dummy data to verify underlying persistence mechanism",
306
46
 
307
- return _wrapNativeSuper(Class);
308
- }
47
+ /**
48
+ * This is the value of a the guid if the process is being ran by the root user
49
+ */
50
+ LINUX_ROOT_USER_GUID: 0,
309
51
 
310
- function _assertThisInitialized(self) {
311
- if (self === void 0) {
312
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
313
- }
52
+ /**
53
+ * List of environment variables
54
+ */
55
+ ENVIRONMENT: {
56
+ HOME: "HOME",
57
+ LOGNAME: "LOGNAME",
58
+ USER: "USER",
59
+ LNAME: "LNAME",
60
+ USERNAME: "USERNAME",
61
+ PLATFORM: "platform",
62
+ LOCAL_APPLICATION_DATA: "LOCALAPPDATA"
63
+ },
64
+ // Name of the default cache file
65
+ DEFAULT_CACHE_FILE_NAME: "cache.json"
66
+ };
67
+ var Platform;
314
68
 
315
- return self;
316
- }
69
+ (function (Platform) {
70
+ Platform["WINDOWS"] = "win32";
71
+ Platform["LINUX"] = "linux";
72
+ Platform["MACOS"] = "darwin";
73
+ })(Platform || (Platform = {}));
317
74
 
318
75
  /*
319
76
  * Copyright (c) Microsoft Corporation. All rights reserved.
@@ -323,75 +80,113 @@ function _assertThisInitialized(self) {
323
80
  /**
324
81
  * Error thrown when trying to write MSAL cache to persistence.
325
82
  */
326
- var PersistenceError = /*#__PURE__*/function (_Error) {
327
- _inheritsLoose(PersistenceError, _Error);
328
-
329
- function PersistenceError(errorCode, errorMessage) {
330
- var _this;
331
-
332
- var errorString = errorMessage ? errorCode + ": " + errorMessage : errorCode;
333
- _this = _Error.call(this, errorString) || this;
334
- Object.setPrototypeOf(_assertThisInitialized(_this), PersistenceError.prototype);
335
- _this.errorCode = errorCode;
336
- _this.errorMessage = errorMessage;
337
- _this.name = "PersistenceError";
338
- return _this;
83
+ class PersistenceError extends Error {
84
+ constructor(errorCode, errorMessage) {
85
+ const errorString = errorMessage ? `${errorCode}: ${errorMessage}` : errorCode;
86
+ super(errorString);
87
+ Object.setPrototypeOf(this, PersistenceError.prototype);
88
+ this.errorCode = errorCode;
89
+ this.errorMessage = errorMessage;
90
+ this.name = "PersistenceError";
339
91
  }
340
92
  /**
341
93
  * Error thrown when trying to access the file system.
342
94
  */
343
95
 
344
96
 
345
- PersistenceError.createFileSystemError = function createFileSystemError(errorCode, errorMessage) {
97
+ static createFileSystemError(errorCode, errorMessage) {
346
98
  return new PersistenceError(errorCode, errorMessage);
347
99
  }
348
100
  /**
349
101
  * Error thrown when trying to write, load, or delete data from secret service on linux.
350
102
  * Libsecret is used to access secret service.
351
103
  */
352
- ;
353
104
 
354
- PersistenceError.createLibSecretError = function createLibSecretError(errorCode, errorMessage) {
355
- var updatedErrorMessage = "Error accessing Gnome Keyring: " + errorCode + "- " + errorMessage;
356
- return new PersistenceError("GnomeKeyringError", updatedErrorMessage);
105
+
106
+ static createLibSecretError(errorMessage) {
107
+ return new PersistenceError("GnomeKeyringError", errorMessage);
357
108
  }
358
109
  /**
359
110
  * Error thrown when trying to write, load, or delete data from keychain on macOs.
360
111
  */
361
- ;
362
112
 
363
- PersistenceError.createKeychainPersistenceError = function createKeychainPersistenceError(errorCode, errorMessage) {
364
- var updatedErrorMessage = "Error accessing Keychain: " + errorCode + "- " + errorMessage;
365
- return new PersistenceError("KeychainError", updatedErrorMessage);
113
+
114
+ static createKeychainPersistenceError(errorMessage) {
115
+ return new PersistenceError("KeychainError", errorMessage);
366
116
  }
367
117
  /**
368
118
  * Error thrown when trying to encrypt or decrypt data using DPAPI on Windows.
369
119
  */
370
- ;
371
120
 
372
- PersistenceError.createFilePersistenceWithDPAPIError = function createFilePersistenceWithDPAPIError(errorCode, errorMessage) {
373
- var updatedErrorMessage = "Error accessing DPAPI encrypted file: " + errorCode + "- " + errorMessage;
374
- return new PersistenceError("DPAPIEncryptedFileError", updatedErrorMessage);
121
+
122
+ static createFilePersistenceWithDPAPIError(errorMessage) {
123
+ return new PersistenceError("DPAPIEncryptedFileError", errorMessage);
375
124
  }
376
125
  /**
377
126
  * Error thrown when using the cross platform lock.
378
127
  */
379
- ;
380
128
 
381
- PersistenceError.createCrossPlatformLockError = function createCrossPlatformLockError(errorCode, errorMessage) {
382
- var updatedErrorMessage = "Error acquiring lock: " + errorCode + "- " + errorMessage;
383
- return new PersistenceError("CrossPlatformLockError", updatedErrorMessage);
384
- };
385
129
 
386
- return PersistenceError;
387
- }( /*#__PURE__*/_wrapNativeSuper(Error));
130
+ static createCrossPlatformLockError(errorMessage) {
131
+ return new PersistenceError("CrossPlatformLockError", errorMessage);
132
+ }
133
+ /**
134
+ * Throw cache persistence error
135
+ *
136
+ * @param errorMessage string
137
+ * @returns PersistenceError
138
+ */
139
+
140
+
141
+ static createCachePersistenceError(errorMessage) {
142
+ return new PersistenceError("CachePersistenceError", errorMessage);
143
+ }
144
+ /**
145
+ * Throw unsupported error
146
+ *
147
+ * @param errorMessage string
148
+ * @returns PersistenceError
149
+ */
150
+
151
+
152
+ static createNotSupportedError(errorMessage) {
153
+ return new PersistenceError("NotSupportedError", errorMessage);
154
+ }
155
+ /**
156
+ * Throw persistence not verified error
157
+ *
158
+ * @param errorMessage string
159
+ * @returns PersistenceError
160
+ */
161
+
162
+
163
+ static createPersistenceNotVerifiedError(errorMessage) {
164
+ return new PersistenceError("PersistenceNotVerifiedError", errorMessage);
165
+ }
166
+ /**
167
+ * Throw persistence creation validation error
168
+ *
169
+ * @param errorMessage string
170
+ * @returns PersistenceError
171
+ */
172
+
173
+
174
+ static createPersistenceNotValidatedError(errorMessage) {
175
+ return new PersistenceError("PersistenceNotValidatedError", errorMessage);
176
+ }
177
+
178
+ }
388
179
 
180
+ /*
181
+ * Copyright (c) Microsoft Corporation. All rights reserved.
182
+ * Licensed under the MIT License.
183
+ */
389
184
  /**
390
185
  * Cross-process lock that works on all platforms.
391
186
  */
392
187
 
393
- var CrossPlatformLock = /*#__PURE__*/function () {
394
- function CrossPlatformLock(lockFilePath, logger, lockOptions) {
188
+ class CrossPlatformLock {
189
+ constructor(lockFilePath, logger, lockOptions) {
395
190
  this.lockFilePath = lockFilePath;
396
191
  this.retryNumber = lockOptions ? lockOptions.retryNumber : 500;
397
192
  this.retryDelay = lockOptions ? lockOptions.retryDelay : 100;
@@ -404,91 +199,65 @@ var CrossPlatformLock = /*#__PURE__*/function () {
404
199
  */
405
200
 
406
201
 
407
- var _proto = CrossPlatformLock.prototype;
408
-
409
- _proto.lock = function lock() {
410
- try {
411
- var _temp3 = function _temp3(_result3) {
412
- if (_exit2) return _result3;
413
- throw PersistenceError.createCrossPlatformLockError("Exceeded retry options", "Not able to acquire lock. Exceeded amount of retries set in options");
414
- };
415
-
416
- var _exit2 = false;
417
-
418
- var _this2 = this;
419
-
420
- var _tryCount = 0;
421
-
422
- var _temp4 = _for(function () {
423
- return !_exit2 && _tryCount < _this2.retryNumber;
424
- }, function () {
425
- return _tryCount++;
426
- }, function () {
427
- return _catch(function () {
428
- _this2.logger.info("Pid " + process.pid + " trying to acquire lock");
429
-
430
- return Promise.resolve(fs.promises.open(_this2.lockFilePath, "wx+")).then(function (_fs$open) {
431
- _this2.lockFileHandle = _fs$open;
432
-
433
- _this2.logger.info("Pid " + process.pid + " acquired lock");
434
-
435
- return Promise.resolve(_this2.lockFileHandle.write(process.pid.toString())).then(function () {
436
- _exit2 = true;
437
- });
438
- });
439
- }, function (err) {
440
- return function () {
441
- if (err.code == Constants.EEXIST_ERROR) {
442
- _this2.logger.info(err);
443
-
444
- return Promise.resolve(_this2.sleep(_this2.retryDelay)).then(function () {});
445
- } else {
446
- throw PersistenceError.createCrossPlatformLockError(err.code, err.message);
447
- }
448
- }();
449
- });
450
- });
451
-
452
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
453
- } catch (e) {
454
- return Promise.reject(e);
202
+ async lock() {
203
+ for (let tryCount = 0; tryCount < this.retryNumber; tryCount++) {
204
+ try {
205
+ this.logger.info(`Pid ${process$1.pid} trying to acquire lock`);
206
+ this.lockFileHandle = await fs.promises.open(this.lockFilePath, "wx+");
207
+ this.logger.info(`Pid ${process$1.pid} acquired lock`);
208
+ await this.lockFileHandle.write(process$1.pid.toString());
209
+ return;
210
+ } catch (err) {
211
+ if (err.code === Constants.EEXIST_ERROR || err.code === Constants.EPERM_ERROR) {
212
+ this.logger.info(err);
213
+ await this.sleep(this.retryDelay);
214
+ } else {
215
+ this.logger.error(`${process$1.pid} was not able to acquire lock. Ran into error: ${err.message}`);
216
+ throw PersistenceError.createCrossPlatformLockError(err.message);
217
+ }
218
+ }
455
219
  }
220
+
221
+ this.logger.error(`${process$1.pid} was not able to acquire lock. Exceeded amount of retries set in the options`);
222
+ throw PersistenceError.createCrossPlatformLockError("Not able to acquire lock. Exceeded amount of retries set in options");
456
223
  }
457
224
  /**
458
225
  * unlocks cache file by deleting .lockfile.
459
226
  */
460
- ;
461
227
 
462
- _proto.unlock = function unlock() {
228
+
229
+ async unlock() {
463
230
  try {
464
- var _this4 = this;
465
-
466
- return Promise.resolve(_catch(function () {
467
- // delete lock file
468
- return Promise.resolve(fs.promises.unlink(_this4.lockFilePath)).then(function () {
469
- return Promise.resolve(_this4.lockFileHandle.close()).then(function () {});
470
- });
471
- }, function (err) {
472
- if (err.code == Constants.ENOENT_ERROR) {
473
- _this4.logger.warning("Tried to unlock but Lockfile does not exist");
474
- } else {
475
- throw PersistenceError.createCrossPlatformLockError(err.code, err.message);
476
- }
477
- }));
478
- } catch (e) {
479
- return Promise.reject(e);
231
+ if (this.lockFileHandle) {
232
+ // if we have a file handle to the .lockfile, delete lock file
233
+ await fs.promises.unlink(this.lockFilePath);
234
+ await this.lockFileHandle.close();
235
+ this.logger.info("lockfile deleted");
236
+ } else {
237
+ this.logger.warning("lockfile handle does not exist, so lockfile could not be deleted");
238
+ }
239
+ } catch (err) {
240
+ if (err.code === Constants.ENOENT_ERROR) {
241
+ this.logger.info("Tried to unlock but lockfile does not exist");
242
+ } else {
243
+ this.logger.error(`${process$1.pid} was not able to release lock. Ran into error: ${err.message}`);
244
+ throw PersistenceError.createCrossPlatformLockError(err.message);
245
+ }
480
246
  }
481
- };
247
+ }
482
248
 
483
- _proto.sleep = function sleep(ms) {
484
- return new Promise(function (resolve) {
249
+ sleep(ms) {
250
+ return new Promise(resolve => {
485
251
  setTimeout(resolve, ms);
486
252
  });
487
- };
253
+ }
488
254
 
489
- return CrossPlatformLock;
490
- }();
255
+ }
491
256
 
257
+ /*
258
+ * Copyright (c) Microsoft Corporation. All rights reserved.
259
+ * Licensed under the MIT License.
260
+ */
492
261
  /**
493
262
  * MSAL cache plugin which enables callers to write the MSAL cache to disk on Windows,
494
263
  * macOs, and Linux.
@@ -503,125 +272,115 @@ var CrossPlatformLock = /*#__PURE__*/function () {
503
272
  * libsecret be installed.
504
273
  */
505
274
 
506
- var PersistenceCachePlugin = /*#__PURE__*/function () {
507
- function PersistenceCachePlugin(persistence, lockOptions) {
275
+ class PersistenceCachePlugin {
276
+ constructor(persistence, lockOptions) {
508
277
  this.persistence = persistence; // initialize logger
509
278
 
510
279
  this.logger = persistence.getLogger(); // create file lock
511
280
 
512
- this.lockFilePath = this.persistence.getFilePath() + ".lockfile";
281
+ this.lockFilePath = `${this.persistence.getFilePath()}.lockfile`;
513
282
  this.crossPlatformLock = new CrossPlatformLock(this.lockFilePath, this.logger, lockOptions); // initialize default values
514
283
 
515
284
  this.lastSync = 0;
516
285
  this.currentCache = null;
517
286
  }
518
287
  /**
519
- * Reads from storage and avoids saves an in memory copy. If persistence has not been updated
288
+ * Reads from storage and saves an in-memory copy. If persistence has not been updated
520
289
  * since last time data was read, in memory copy is used.
290
+ *
291
+ * If cacheContext.cacheHasChanged === true, then file lock is created and not deleted until
292
+ * afterCacheAccess() is called, to prevent the cache file from changing in between
293
+ * beforeCacheAccess() and afterCacheAccess().
521
294
  */
522
295
 
523
296
 
524
- var _proto = PersistenceCachePlugin.prototype;
525
-
526
- _proto.readFromStorage = function readFromStorage() {
527
- try {
528
- var _this2 = this;
529
-
530
- _this2.logger.info("Reading from storage");
297
+ async beforeCacheAccess(cacheContext) {
298
+ this.logger.info("Executing before cache access");
299
+ const reloadNecessary = await this.persistence.reloadNecessary(this.lastSync);
531
300
 
532
- return Promise.resolve(_this2.persistence.reloadNecessary(_this2.lastSync)).then(function (_this$persistence$rel) {
533
- function _temp3() {
534
- return _this2.currentCache;
535
- }
301
+ if (!reloadNecessary && this.currentCache !== null) {
302
+ if (cacheContext.cacheHasChanged) {
303
+ this.logger.verbose("Cache context has changed");
304
+ await this.crossPlatformLock.lock();
305
+ }
536
306
 
537
- var _temp2 = function () {
538
- if (_this$persistence$rel || _this2.currentCache == null) {
539
- var _temp4 = _finallyRethrows(function () {
540
- _this2.logger.info("Reload necessary. Last sync time: " + _this2.lastSync);
541
-
542
- return Promise.resolve(_this2.crossPlatformLock.lock()).then(function () {
543
- return Promise.resolve(_this2.persistence.load()).then(function (_this$persistence$loa) {
544
- _this2.currentCache = _this$persistence$loa;
545
- _this2.lastSync = new Date().getTime();
546
-
547
- _this2.logger.info("Last sync time updated to: " + _this2.lastSync);
548
- });
549
- });
550
- }, function (_wasThrown, _result) {
551
- return Promise.resolve(_this2.crossPlatformLock.unlock()).then(function () {
552
- _this2.logger.info("Pid " + process.pid + " Released lock");
553
-
554
- if (_wasThrown) throw _result;
555
- return _result;
556
- });
557
- });
558
-
559
- if (_temp4 && _temp4.then) return _temp4.then(function () {});
560
- }
561
- }();
307
+ return;
308
+ }
562
309
 
563
- return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2);
564
- });
565
- } catch (e) {
566
- return Promise.reject(e);
310
+ try {
311
+ this.logger.info(`Reload necessary. Last sync time: ${this.lastSync}`);
312
+ await this.crossPlatformLock.lock();
313
+ this.currentCache = await this.persistence.load();
314
+ this.lastSync = new Date().getTime();
315
+ cacheContext.tokenCache.deserialize(this.currentCache);
316
+ this.logger.info(`Last sync time updated to: ${this.lastSync}`);
317
+ } finally {
318
+ if (!cacheContext.cacheHasChanged) {
319
+ await this.crossPlatformLock.unlock();
320
+ this.logger.info(`Pid ${process$1.pid} released lock`);
321
+ } else {
322
+ this.logger.info(`Pid ${process$1.pid} beforeCacheAccess did not release lock`);
323
+ }
567
324
  }
568
325
  }
569
326
  /**
570
- * Writes to storage. If persistence has not been updated since last time data was read,
571
- * reads and latest state from persistence, sends state via callback, and updates in memory copy.
327
+ * Writes to storage if MSAL in memory copy of cache has been changed.
572
328
  */
573
- ;
574
329
 
575
- _proto.writeToStorage = function writeToStorage(callback) {
330
+
331
+ async afterCacheAccess(cacheContext) {
332
+ this.logger.info("Executing after cache access");
333
+
576
334
  try {
577
- var _this4 = this;
578
-
579
- var _temp8 = _finallyRethrows(function () {
580
- _this4.logger.info("Writing to storage");
581
-
582
- return Promise.resolve(_this4.crossPlatformLock.lock()).then(function () {
583
- return Promise.resolve(_this4.persistence.reloadNecessary(_this4.lastSync)).then(function (_this3$persistence$re) {
584
- function _temp6() {
585
- return Promise.resolve(callback(_this4.currentCache)).then(function (_callback) {
586
- _this4.currentCache = _callback;
587
- return Promise.resolve(_this4.persistence.save(_this4.currentCache)).then(function () {});
588
- });
589
- }
590
-
591
- var _temp5 = function () {
592
- if (_this3$persistence$re) {
593
- _this4.logger.info("Reload necessary. Last sync time: " + _this4.lastSync);
594
-
595
- return Promise.resolve(_this4.persistence.load()).then(function (_this3$persistence$lo) {
596
- _this4.currentCache = _this3$persistence$lo;
597
- _this4.lastSync = new Date().getTime();
598
-
599
- _this4.logger.info("Last sync time updated to: " + _this4.lastSync);
600
- });
601
- }
602
- }();
603
-
604
- return _temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5);
605
- });
606
- });
607
- }, function (_wasThrown2, _result2) {
608
- return Promise.resolve(_this4.crossPlatformLock.unlock()).then(function () {
609
- _this4.logger.info("Pid " + process.pid + " Released lock");
610
-
611
- if (_wasThrown2) throw _result2;
612
- return _result2;
613
- });
614
- });
335
+ if (cacheContext.cacheHasChanged) {
336
+ this.logger.info("Msal in-memory cache has changed. Writing changes to persistence");
337
+ this.currentCache = cacheContext.tokenCache.serialize();
338
+ await this.persistence.save(this.currentCache);
339
+ } else {
340
+ this.logger.info("Msal in-memory cache has not changed. Did not write to persistence");
341
+ }
342
+ } finally {
343
+ await this.crossPlatformLock.unlock();
344
+ this.logger.info(`Pid ${process$1.pid} afterCacheAccess released lock`);
345
+ }
346
+ }
347
+
348
+ }
615
349
 
616
- return Promise.resolve(_temp8 && _temp8.then ? _temp8.then(function () {}) : void 0);
350
+ /*
351
+ * Copyright (c) Microsoft Corporation. All rights reserved.
352
+ * Licensed under the MIT License.
353
+ */
354
+ class BasePersistence {
355
+ async verifyPersistence() {
356
+ // We are using a different location for the test to avoid overriding the functional cache
357
+ const persistenceValidator = await this.createForPersistenceValidation();
358
+
359
+ try {
360
+ await persistenceValidator.save(Constants.PERSISTENCE_TEST_DATA);
361
+ const retrievedDummyData = await persistenceValidator.load();
362
+
363
+ if (!retrievedDummyData) {
364
+ throw PersistenceError.createCachePersistenceError("Persistence check failed. Data was written but it could not be read. " + "Possible cause: on Linux, LibSecret is installed but D-Bus isn't running because it cannot be started over SSH.");
365
+ }
366
+
367
+ if (retrievedDummyData !== Constants.PERSISTENCE_TEST_DATA) {
368
+ throw PersistenceError.createCachePersistenceError(`Persistence check failed. Data written ${Constants.PERSISTENCE_TEST_DATA} is different from data read ${retrievedDummyData}`);
369
+ }
370
+
371
+ await persistenceValidator.delete();
372
+ return true;
617
373
  } catch (e) {
618
- return Promise.reject(e);
374
+ throw PersistenceError.createCachePersistenceError(`Verifing persistence failed with the error: ${e}`);
619
375
  }
620
- };
376
+ }
621
377
 
622
- return PersistenceCachePlugin;
623
- }();
378
+ }
624
379
 
380
+ /*
381
+ * Copyright (c) Microsoft Corporation. All rights reserved.
382
+ * Licensed under the MIT License.
383
+ */
625
384
  /**
626
385
  * Reads and writes data to file specified by file location. File contents are not
627
386
  * encrypted.
@@ -630,201 +389,152 @@ var PersistenceCachePlugin = /*#__PURE__*/function () {
630
389
  * file and any directories in the path recursively.
631
390
  */
632
391
 
633
- var FilePersistence = /*#__PURE__*/function () {
634
- function FilePersistence() {}
392
+ class FilePersistence extends BasePersistence {
393
+ static async create(fileLocation, loggerOptions) {
394
+ const filePersistence = new FilePersistence();
395
+ filePersistence.filePath = fileLocation;
396
+ filePersistence.logger = new msalCommon.Logger(loggerOptions || FilePersistence.createDefaultLoggerOptions());
397
+ await filePersistence.createCacheFile();
398
+ return filePersistence;
399
+ }
635
400
 
636
- FilePersistence.create = function create(fileLocation, loggerOptions) {
401
+ async save(contents) {
637
402
  try {
638
- var filePersistence = new FilePersistence();
639
- filePersistence.filePath = fileLocation;
640
- filePersistence.logger = new msalCommon.Logger(loggerOptions || FilePersistence.createDefaultLoggerOptions());
641
- return Promise.resolve(filePersistence.createCacheFile()).then(function () {
642
- return filePersistence;
643
- });
644
- } catch (e) {
645
- return Promise.reject(e);
403
+ await fs.promises.writeFile(this.getFilePath(), contents, "utf-8");
404
+ } catch (err) {
405
+ throw PersistenceError.createFileSystemError(err.code, err.message);
646
406
  }
647
- };
648
-
649
- var _proto = FilePersistence.prototype;
650
-
651
- _proto.save = function save(contents) {
652
- try {
653
- var _this2 = this;
654
-
655
- return Promise.resolve(_catch(function () {
656
- return Promise.resolve(fs.promises.writeFile(_this2.getFilePath(), contents, "utf-8")).then(function () {});
657
- }, function (err) {
658
- throw PersistenceError.createFileSystemError(err.code, err.message);
659
- }));
660
- } catch (e) {
661
- return Promise.reject(e);
662
- }
663
- };
407
+ }
664
408
 
665
- _proto.saveBuffer = function saveBuffer(contents) {
409
+ async saveBuffer(contents) {
666
410
  try {
667
- var _this4 = this;
668
-
669
- return Promise.resolve(_catch(function () {
670
- return Promise.resolve(fs.promises.writeFile(_this4.getFilePath(), contents)).then(function () {});
671
- }, function (err) {
672
- throw PersistenceError.createFileSystemError(err.code, err.message);
673
- }));
674
- } catch (e) {
675
- return Promise.reject(e);
411
+ await fs.promises.writeFile(this.getFilePath(), contents);
412
+ } catch (err) {
413
+ throw PersistenceError.createFileSystemError(err.code, err.message);
676
414
  }
677
- };
415
+ }
678
416
 
679
- _proto.load = function load() {
417
+ async load() {
680
418
  try {
681
- var _this6 = this;
682
-
683
- return Promise.resolve(_catch(function () {
684
- return Promise.resolve(fs.promises.readFile(_this6.getFilePath(), "utf-8"));
685
- }, function (err) {
686
- throw PersistenceError.createFileSystemError(err.code, err.message);
687
- }));
688
- } catch (e) {
689
- return Promise.reject(e);
419
+ return await fs.promises.readFile(this.getFilePath(), "utf-8");
420
+ } catch (err) {
421
+ throw PersistenceError.createFileSystemError(err.code, err.message);
690
422
  }
691
- };
423
+ }
692
424
 
693
- _proto.loadBuffer = function loadBuffer() {
425
+ async loadBuffer() {
694
426
  try {
695
- var _this8 = this;
696
-
697
- return Promise.resolve(_catch(function () {
698
- return Promise.resolve(fs.promises.readFile(_this8.getFilePath()));
699
- }, function (err) {
700
- throw PersistenceError.createFileSystemError(err.code, err.message);
701
- }));
702
- } catch (e) {
703
- return Promise.reject(e);
427
+ return await fs.promises.readFile(this.getFilePath());
428
+ } catch (err) {
429
+ throw PersistenceError.createFileSystemError(err.code, err.message);
704
430
  }
705
- };
431
+ }
706
432
 
707
- _proto["delete"] = function _delete() {
433
+ async delete() {
708
434
  try {
709
- var _this10 = this;
710
-
711
- return Promise.resolve(_catch(function () {
712
- return Promise.resolve(fs.promises.unlink(_this10.getFilePath())).then(function () {
713
- return true;
714
- });
715
- }, function (err) {
716
- if (err.code == Constants.ENOENT_ERROR) {
717
- // file does not exist, so it was not deleted
718
- _this10.logger.warning("Cache file does not exist, so it could not be deleted");
719
-
720
- return false;
721
- }
435
+ await fs.promises.unlink(this.getFilePath());
436
+ return true;
437
+ } catch (err) {
438
+ if (err.code === Constants.ENOENT_ERROR) {
439
+ // file does not exist, so it was not deleted
440
+ this.logger.warning("Cache file does not exist, so it could not be deleted");
441
+ return false;
442
+ }
722
443
 
723
- throw PersistenceError.createFileSystemError(err.code, err.message);
724
- }));
725
- } catch (e) {
726
- return Promise.reject(e);
444
+ throw PersistenceError.createFileSystemError(err.code, err.message);
727
445
  }
728
- };
446
+ }
729
447
 
730
- _proto.getFilePath = function getFilePath() {
448
+ getFilePath() {
731
449
  return this.filePath;
732
- };
733
-
734
- _proto.reloadNecessary = function reloadNecessary(lastSync) {
735
- try {
736
- var _this12 = this;
450
+ }
737
451
 
738
- return Promise.resolve(_this12.timeLastModified()).then(function (_this11$timeLastModif) {
739
- return lastSync < _this11$timeLastModif;
740
- });
741
- } catch (e) {
742
- return Promise.reject(e);
743
- }
744
- };
452
+ async reloadNecessary(lastSync) {
453
+ return lastSync < (await this.timeLastModified());
454
+ }
745
455
 
746
- _proto.getLogger = function getLogger() {
456
+ getLogger() {
747
457
  return this.logger;
748
- };
458
+ }
749
459
 
750
- FilePersistence.createDefaultLoggerOptions = function createDefaultLoggerOptions() {
460
+ createForPersistenceValidation() {
461
+ const testCacheFileLocation = `${path.dirname(this.filePath)}/test.cache`;
462
+ return FilePersistence.create(testCacheFileLocation);
463
+ }
464
+
465
+ static createDefaultLoggerOptions() {
751
466
  return {
752
- loggerCallback: function loggerCallback() {// allow users to not set loggerCallback
467
+ loggerCallback: () => {// allow users to not set loggerCallback
753
468
  },
754
469
  piiLoggingEnabled: false,
755
470
  logLevel: msalCommon.LogLevel.Info
756
471
  };
757
- };
472
+ }
758
473
 
759
- _proto.timeLastModified = function timeLastModified() {
474
+ async timeLastModified() {
760
475
  try {
761
- var _this14 = this;
762
-
763
- return Promise.resolve(_catch(function () {
764
- return Promise.resolve(fs.promises.stat(_this14.filePath)).then(function (stats) {
765
- return stats.mtime.getTime();
766
- });
767
- }, function (err) {
768
- if (err.code == Constants.ENOENT_ERROR) {
769
- // file does not exist, so it's never been modified
770
- _this14.logger.verbose("Cache file does not exist");
771
-
772
- return 0;
773
- }
476
+ const stats = await fs.promises.stat(this.filePath);
477
+ return stats.mtime.getTime();
478
+ } catch (err) {
479
+ if (err.code === Constants.ENOENT_ERROR) {
480
+ // file does not exist, so it's never been modified
481
+ this.logger.verbose("Cache file does not exist");
482
+ return 0;
483
+ }
774
484
 
775
- throw PersistenceError.createFileSystemError(err.code, err.message);
776
- }));
777
- } catch (e) {
778
- return Promise.reject(e);
485
+ throw PersistenceError.createFileSystemError(err.code, err.message);
779
486
  }
780
- };
487
+ }
488
+
489
+ async createCacheFile() {
490
+ await this.createFileDirectory(); // File is created only if it does not exist
781
491
 
782
- _proto.createCacheFile = function createCacheFile() {
492
+ const fileHandle = await fs.promises.open(this.filePath, "a");
493
+ await fileHandle.close();
494
+ this.logger.info(`File created at ${this.filePath}`);
495
+ }
496
+
497
+ async createFileDirectory() {
783
498
  try {
784
- var _this16 = this;
785
-
786
- return Promise.resolve(_this16.createFileDirectory()).then(function () {
787
- // File is created only if it does not exist
788
- return Promise.resolve(fs.promises.open(_this16.filePath, "a")).then(function (fileHandle) {
789
- return Promise.resolve(fileHandle.close()).then(function () {
790
- _this16.logger.info("File created at " + _this16.filePath);
791
- });
792
- });
499
+ await fs.promises.mkdir(path.dirname(this.filePath), {
500
+ recursive: true
793
501
  });
794
- } catch (e) {
795
- return Promise.reject(e);
502
+ } catch (err) {
503
+ if (err.code === Constants.EEXIST_ERROR) {
504
+ this.logger.info(`Directory ${path.dirname(this.filePath)} already exists`);
505
+ } else {
506
+ throw PersistenceError.createFileSystemError(err.code, err.message);
507
+ }
796
508
  }
797
- };
509
+ }
798
510
 
799
- _proto.createFileDirectory = function createFileDirectory() {
800
- try {
801
- var _this18 = this;
802
-
803
- return Promise.resolve(_catch(function () {
804
- return Promise.resolve(fs.promises.mkdir(path.dirname(_this18.filePath), {
805
- recursive: true
806
- })).then(function () {});
807
- }, function (err) {
808
- if (err.code == Constants.EEXIST_ERROR) {
809
- _this18.logger.info("Directory " + path.dirname(_this18.filePath) + " already exists");
810
- } else {
811
- throw PersistenceError.createFileSystemError(err.code, err.message);
812
- }
813
- }));
814
- } catch (e) {
815
- return Promise.reject(e);
816
- }
817
- };
511
+ }
512
+
513
+ /*
514
+ * Copyright (c) Microsoft Corporation. All rights reserved.
515
+ * Licensed under the MIT License.
516
+ */
818
517
 
819
- return FilePersistence;
820
- }();
518
+ /* eslint-disable-next-line @typescript-eslint/no-var-requires, no-var, import/no-commonjs */
519
+ var Dpapi = /*#__PURE__*/require("bindings")({
520
+ bindings: "dpapi",
521
+ userDefinedTries: [["module_root", "node_modules", "@azure", "msal-node-extensions", "build", "Release", "bindings"]]
522
+ });
821
523
 
822
524
  /*
823
525
  * Copyright (c) Microsoft Corporation. All rights reserved.
824
526
  * Licensed under the MIT License.
825
527
  */
826
- var Dpapi = /*#__PURE__*/require("bindings")("dpapi");
827
528
 
529
+ (function (DataProtectionScope) {
530
+ DataProtectionScope["CurrentUser"] = "CurrentUser";
531
+ DataProtectionScope["LocalMachine"] = "LocalMachine";
532
+ })(exports.DataProtectionScope || (exports.DataProtectionScope = {}));
533
+
534
+ /*
535
+ * Copyright (c) Microsoft Corporation. All rights reserved.
536
+ * Licensed under the MIT License.
537
+ */
828
538
  /**
829
539
  * Uses CryptProtectData and CryptUnprotectData on Windows to encrypt and decrypt file contents.
830
540
  *
@@ -832,104 +542,70 @@ var Dpapi = /*#__PURE__*/require("bindings")("dpapi");
832
542
  * optionalEntropy: Password or other additional entropy used to encrypt the data
833
543
  */
834
544
 
835
- var FilePersistenceWithDataProtection = /*#__PURE__*/function () {
836
- function FilePersistenceWithDataProtection(scope, optionalEntropy) {
545
+ class FilePersistenceWithDataProtection extends BasePersistence {
546
+ constructor(scope, optionalEntropy) {
547
+ super();
837
548
  this.scope = scope;
838
549
  this.optionalEntropy = optionalEntropy ? Buffer.from(optionalEntropy, "utf-8") : null;
839
550
  }
840
551
 
841
- FilePersistenceWithDataProtection.create = function create(fileLocation, scope, optionalEntropy, loggerOptions) {
842
- try {
843
- var persistence = new FilePersistenceWithDataProtection(scope, optionalEntropy);
844
- return Promise.resolve(FilePersistence.create(fileLocation, loggerOptions)).then(function (_FilePersistence$crea) {
845
- persistence.filePersistence = _FilePersistence$crea;
846
- return persistence;
847
- });
848
- } catch (e) {
849
- return Promise.reject(e);
850
- }
851
- };
852
-
853
- var _proto = FilePersistenceWithDataProtection.prototype;
552
+ static async create(fileLocation, scope, optionalEntropy, loggerOptions) {
553
+ const persistence = new FilePersistenceWithDataProtection(scope, optionalEntropy);
554
+ persistence.filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
555
+ return persistence;
556
+ }
854
557
 
855
- _proto.save = function save(contents) {
558
+ async save(contents) {
856
559
  try {
857
- var _this2 = this;
858
-
859
- return Promise.resolve(_catch(function () {
860
- var encryptedContents = Dpapi.protectData(Buffer.from(contents, "utf-8"), _this2.optionalEntropy, _this2.scope.toString());
861
- return Promise.resolve(_this2.filePersistence.saveBuffer(encryptedContents)).then(function () {});
862
- }, function (err) {
863
- throw PersistenceError.createFilePersistenceWithDPAPIError(err.code, err.message);
864
- }));
865
- } catch (e) {
866
- return Promise.reject(e);
560
+ const encryptedContents = Dpapi.protectData(Buffer.from(contents, "utf-8"), this.optionalEntropy, this.scope.toString());
561
+ await this.filePersistence.saveBuffer(encryptedContents);
562
+ } catch (err) {
563
+ throw PersistenceError.createFilePersistenceWithDPAPIError(err.message);
867
564
  }
868
- };
565
+ }
869
566
 
870
- _proto.load = function load() {
567
+ async load() {
871
568
  try {
872
- var _this4 = this;
873
-
874
- return Promise.resolve(_catch(function () {
875
- return Promise.resolve(_this4.filePersistence.loadBuffer()).then(function (encryptedContents) {
876
- if (typeof encryptedContents === "undefined" || !encryptedContents || 0 === encryptedContents.length) {
877
- _this4.filePersistence.getLogger().info("Encrypted contents loaded from file were null or empty");
878
-
879
- return null;
880
- }
569
+ const encryptedContents = await this.filePersistence.loadBuffer();
881
570
 
882
- return Dpapi.unprotectData(encryptedContents, _this4.optionalEntropy, _this4.scope.toString()).toString();
883
- });
884
- }, function (err) {
885
- throw PersistenceError.createFilePersistenceWithDPAPIError(err.code, err.message);
886
- }));
887
- } catch (e) {
888
- return Promise.reject(e);
889
- }
890
- };
891
-
892
- _proto["delete"] = function _delete() {
893
- try {
894
- var _this6 = this;
571
+ if (typeof encryptedContents === "undefined" || !encryptedContents || 0 === encryptedContents.length) {
572
+ this.filePersistence.getLogger().info("Encrypted contents loaded from file were null or empty");
573
+ return null;
574
+ }
895
575
 
896
- return Promise.resolve(_this6.filePersistence["delete"]());
897
- } catch (e) {
898
- return Promise.reject(e);
576
+ return Dpapi.unprotectData(encryptedContents, this.optionalEntropy, this.scope.toString()).toString();
577
+ } catch (err) {
578
+ throw PersistenceError.createFilePersistenceWithDPAPIError(err.message);
899
579
  }
900
- };
580
+ }
901
581
 
902
- _proto.reloadNecessary = function reloadNecessary(lastSync) {
903
- try {
904
- var _this8 = this;
582
+ async delete() {
583
+ return this.filePersistence.delete();
584
+ }
905
585
 
906
- return Promise.resolve(_this8.filePersistence.reloadNecessary(lastSync));
907
- } catch (e) {
908
- return Promise.reject(e);
909
- }
910
- };
586
+ async reloadNecessary(lastSync) {
587
+ return this.filePersistence.reloadNecessary(lastSync);
588
+ }
911
589
 
912
- _proto.getFilePath = function getFilePath() {
590
+ getFilePath() {
913
591
  return this.filePersistence.getFilePath();
914
- };
592
+ }
915
593
 
916
- _proto.getLogger = function getLogger() {
594
+ getLogger() {
917
595
  return this.filePersistence.getLogger();
918
- };
596
+ }
597
+
598
+ createForPersistenceValidation() {
599
+ const testCacheFileLocation = `${path.dirname(this.filePersistence.getFilePath())}/test.cache`;
600
+ return FilePersistenceWithDataProtection.create(testCacheFileLocation, exports.DataProtectionScope.CurrentUser);
601
+ }
919
602
 
920
- return FilePersistenceWithDataProtection;
921
- }();
603
+ }
922
604
 
923
605
  /*
924
606
  * Copyright (c) Microsoft Corporation. All rights reserved.
925
607
  * Licensed under the MIT License.
926
608
  */
927
-
928
- (function (DataProtectionScope) {
929
- DataProtectionScope["CurrentUser"] = "CurrentUser";
930
- DataProtectionScope["LocalMachine"] = "LocalMachine";
931
- })(exports.DataProtectionScope || (exports.DataProtectionScope = {}));
932
-
933
609
  /**
934
610
  * Uses reads and writes passwords to macOS keychain
935
611
  *
@@ -937,99 +613,70 @@ var FilePersistenceWithDataProtection = /*#__PURE__*/function () {
937
613
  * accountName: Account under which password should be stored
938
614
  */
939
615
 
940
- var KeychainPersistence = /*#__PURE__*/function () {
941
- function KeychainPersistence(serviceName, accountName) {
616
+ class KeychainPersistence extends BasePersistence {
617
+ constructor(serviceName, accountName) {
618
+ super();
942
619
  this.serviceName = serviceName;
943
620
  this.accountName = accountName;
944
621
  }
945
622
 
946
- KeychainPersistence.create = function create(fileLocation, serviceName, accountName, loggerOptions) {
947
- try {
948
- var persistence = new KeychainPersistence(serviceName, accountName);
949
- return Promise.resolve(FilePersistence.create(fileLocation, loggerOptions)).then(function (_FilePersistence$crea) {
950
- persistence.filePersistence = _FilePersistence$crea;
951
- return persistence;
952
- });
953
- } catch (e) {
954
- return Promise.reject(e);
955
- }
956
- };
957
-
958
- var _proto = KeychainPersistence.prototype;
623
+ static async create(fileLocation, serviceName, accountName, loggerOptions) {
624
+ const persistence = new KeychainPersistence(serviceName, accountName);
625
+ persistence.filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
626
+ return persistence;
627
+ }
959
628
 
960
- _proto.save = function save(contents) {
629
+ async save(contents) {
961
630
  try {
962
- var _temp3 = function _temp3(_result) {
963
- return _exit2 ? _result : Promise.resolve(_this2.filePersistence.save("{}")).then(function () {});
964
- };
965
-
966
- var _exit2 = false;
631
+ await keytar.setPassword(this.serviceName, this.accountName, contents);
632
+ } catch (err) {
633
+ throw PersistenceError.createKeychainPersistenceError(err.message);
634
+ } // Write dummy data to update file mtime
967
635
 
968
- var _this2 = this;
969
636
 
970
- var _temp4 = _catch(function () {
971
- return Promise.resolve(keytar.setPassword(_this2.serviceName, _this2.accountName, contents)).then(function () {});
972
- }, function (err) {
973
- throw PersistenceError.createKeychainPersistenceError(err.code, err.message);
974
- });
975
-
976
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4)); // Write dummy data to update file mtime
977
- } catch (e) {
978
- return Promise.reject(e);
979
- }
980
- };
637
+ await this.filePersistence.save("{}");
638
+ }
981
639
 
982
- _proto.load = function load() {
640
+ async load() {
983
641
  try {
984
- var _this4 = this;
985
-
986
- return Promise.resolve(_catch(function () {
987
- return Promise.resolve(keytar.getPassword(_this4.serviceName, _this4.accountName));
988
- }, function (err) {
989
- throw PersistenceError.createKeychainPersistenceError(err.code, err.message);
990
- }));
991
- } catch (e) {
992
- return Promise.reject(e);
642
+ return await keytar.getPassword(this.serviceName, this.accountName);
643
+ } catch (err) {
644
+ throw PersistenceError.createKeychainPersistenceError(err.message);
993
645
  }
994
- };
646
+ }
995
647
 
996
- _proto["delete"] = function _delete() {
648
+ async delete() {
997
649
  try {
998
- var _this6 = this;
999
-
1000
- return Promise.resolve(_catch(function () {
1001
- return Promise.resolve(_this6.filePersistence["delete"]()).then(function () {
1002
- return Promise.resolve(keytar.deletePassword(_this6.serviceName, _this6.accountName));
1003
- });
1004
- }, function (err) {
1005
- throw PersistenceError.createKeychainPersistenceError(err.code, err.message);
1006
- }));
1007
- } catch (e) {
1008
- return Promise.reject(e);
650
+ await this.filePersistence.delete();
651
+ return await keytar.deletePassword(this.serviceName, this.accountName);
652
+ } catch (err) {
653
+ throw PersistenceError.createKeychainPersistenceError(err.message);
1009
654
  }
1010
- };
1011
-
1012
- _proto.reloadNecessary = function reloadNecessary(lastSync) {
1013
- try {
1014
- var _this8 = this;
655
+ }
1015
656
 
1016
- return Promise.resolve(_this8.filePersistence.reloadNecessary(lastSync));
1017
- } catch (e) {
1018
- return Promise.reject(e);
1019
- }
1020
- };
657
+ async reloadNecessary(lastSync) {
658
+ return this.filePersistence.reloadNecessary(lastSync);
659
+ }
1021
660
 
1022
- _proto.getFilePath = function getFilePath() {
661
+ getFilePath() {
1023
662
  return this.filePersistence.getFilePath();
1024
- };
663
+ }
1025
664
 
1026
- _proto.getLogger = function getLogger() {
665
+ getLogger() {
1027
666
  return this.filePersistence.getLogger();
1028
- };
667
+ }
1029
668
 
1030
- return KeychainPersistence;
1031
- }();
669
+ createForPersistenceValidation() {
670
+ const testCacheFileLocation = `${path.dirname(this.filePersistence.getFilePath())}/test.cache`;
671
+ return KeychainPersistence.create(testCacheFileLocation, "persistenceValidationServiceName", "persistencValidationAccountName");
672
+ }
1032
673
 
674
+ }
675
+
676
+ /*
677
+ * Copyright (c) Microsoft Corporation. All rights reserved.
678
+ * Licensed under the MIT License.
679
+ */
1033
680
  /**
1034
681
  * Uses reads and writes passwords to Secret Service API/libsecret. Requires libsecret
1035
682
  * to be installed.
@@ -1038,102 +685,221 @@ var KeychainPersistence = /*#__PURE__*/function () {
1038
685
  * accountName: Account under which password should be stored
1039
686
  */
1040
687
 
1041
- var LibSecretPersistence = /*#__PURE__*/function () {
1042
- function LibSecretPersistence(serviceName, accountName) {
688
+ class LibSecretPersistence extends BasePersistence {
689
+ constructor(serviceName, accountName) {
690
+ super();
1043
691
  this.serviceName = serviceName;
1044
692
  this.accountName = accountName;
1045
693
  }
1046
694
 
1047
- LibSecretPersistence.create = function create(fileLocation, serviceName, accountName, loggerOptions) {
695
+ static async create(fileLocation, serviceName, accountName, loggerOptions) {
696
+ const persistence = new LibSecretPersistence(serviceName, accountName);
697
+ persistence.filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
698
+ return persistence;
699
+ }
700
+
701
+ async save(contents) {
1048
702
  try {
1049
- var persistence = new LibSecretPersistence(serviceName, accountName);
1050
- return Promise.resolve(FilePersistence.create(fileLocation, loggerOptions)).then(function (_FilePersistence$crea) {
1051
- persistence.filePersistence = _FilePersistence$crea;
1052
- return persistence;
1053
- });
1054
- } catch (e) {
1055
- return Promise.reject(e);
1056
- }
1057
- };
703
+ await keytar.setPassword(this.serviceName, this.accountName, contents);
704
+ } catch (err) {
705
+ throw PersistenceError.createLibSecretError(err.message);
706
+ } // Write dummy data to update file mtime
1058
707
 
1059
- var _proto = LibSecretPersistence.prototype;
1060
708
 
1061
- _proto.save = function save(contents) {
709
+ await this.filePersistence.save("{}");
710
+ }
711
+
712
+ async load() {
1062
713
  try {
1063
- var _temp3 = function _temp3(_result) {
1064
- return _exit2 ? _result : Promise.resolve(_this2.filePersistence.save("{}")).then(function () {});
1065
- };
714
+ return await keytar.getPassword(this.serviceName, this.accountName);
715
+ } catch (err) {
716
+ throw PersistenceError.createLibSecretError(err.message);
717
+ }
718
+ }
1066
719
 
1067
- var _exit2 = false;
720
+ async delete() {
721
+ try {
722
+ await this.filePersistence.delete();
723
+ return await keytar.deletePassword(this.serviceName, this.accountName);
724
+ } catch (err) {
725
+ throw PersistenceError.createLibSecretError(err.message);
726
+ }
727
+ }
1068
728
 
1069
- var _this2 = this;
729
+ async reloadNecessary(lastSync) {
730
+ return this.filePersistence.reloadNecessary(lastSync);
731
+ }
1070
732
 
1071
- var _temp4 = _catch(function () {
1072
- return Promise.resolve(keytar.setPassword(_this2.serviceName, _this2.accountName, contents)).then(function () {});
1073
- }, function (err) {
1074
- throw PersistenceError.createLibSecretError(err.code, err.message);
1075
- });
733
+ getFilePath() {
734
+ return this.filePersistence.getFilePath();
735
+ }
1076
736
 
1077
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4)); // Write dummy data to update file mtime
1078
- } catch (e) {
1079
- return Promise.reject(e);
1080
- }
1081
- };
737
+ getLogger() {
738
+ return this.filePersistence.getLogger();
739
+ }
1082
740
 
1083
- _proto.load = function load() {
1084
- try {
1085
- var _this4 = this;
741
+ createForPersistenceValidation() {
742
+ const testCacheFileLocation = `${path.dirname(this.filePersistence.getFilePath())}/test.cache`;
743
+ return LibSecretPersistence.create(testCacheFileLocation, "persistenceValidationServiceName", "persistencValidationAccountName");
744
+ }
1086
745
 
1087
- return Promise.resolve(_catch(function () {
1088
- return Promise.resolve(keytar.getPassword(_this4.serviceName, _this4.accountName));
1089
- }, function (err) {
1090
- throw PersistenceError.createLibSecretError(err.code, err.message);
1091
- }));
1092
- } catch (e) {
1093
- return Promise.reject(e);
746
+ }
747
+
748
+ /*
749
+ * Copyright (c) Microsoft Corporation. All rights reserved.
750
+ * Licensed under the MIT License.
751
+ */
752
+ class Environment {
753
+ static get homeEnvVar() {
754
+ return this.getEnvironmentVariable(Constants.ENVIRONMENT.HOME);
755
+ }
756
+
757
+ static get lognameEnvVar() {
758
+ return this.getEnvironmentVariable(Constants.ENVIRONMENT.LOGNAME);
759
+ }
760
+
761
+ static get userEnvVar() {
762
+ return this.getEnvironmentVariable(Constants.ENVIRONMENT.USER);
763
+ }
764
+
765
+ static get lnameEnvVar() {
766
+ return this.getEnvironmentVariable(Constants.ENVIRONMENT.LNAME);
767
+ }
768
+
769
+ static get usernameEnvVar() {
770
+ return this.getEnvironmentVariable(Constants.ENVIRONMENT.USERNAME);
771
+ }
772
+
773
+ static getEnvironmentVariable(name) {
774
+ return process.env[name];
775
+ }
776
+
777
+ static getEnvironmentPlatform() {
778
+ return process.platform;
779
+ }
780
+
781
+ static isWindowsPlatform() {
782
+ return this.getEnvironmentPlatform() === Platform.WINDOWS;
783
+ }
784
+
785
+ static isLinuxPlatform() {
786
+ return this.getEnvironmentPlatform() === Platform.LINUX;
787
+ }
788
+
789
+ static isMacPlatform() {
790
+ return this.getEnvironmentPlatform() === Platform.MACOS;
791
+ }
792
+
793
+ static isLinuxRootUser() {
794
+ return process.getuid() === Constants.LINUX_ROOT_USER_GUID;
795
+ }
796
+
797
+ static getUserRootDirectory() {
798
+ return !this.isWindowsPlatform ? this.getUserHomeDirOnUnix() : this.getUserHomeDirOnWindows();
799
+ }
800
+
801
+ static getUserHomeDirOnWindows() {
802
+ return this.getEnvironmentVariable(Constants.ENVIRONMENT.LOCAL_APPLICATION_DATA);
803
+ }
804
+
805
+ static getUserHomeDirOnUnix() {
806
+ if (this.isWindowsPlatform()) {
807
+ throw PersistenceError.createNotSupportedError("Getting the user home directory for unix is not supported in windows");
1094
808
  }
1095
- };
1096
809
 
1097
- _proto["delete"] = function _delete() {
1098
- try {
1099
- var _this6 = this;
1100
-
1101
- return Promise.resolve(_catch(function () {
1102
- return Promise.resolve(_this6.filePersistence["delete"]()).then(function () {
1103
- return Promise.resolve(keytar.deletePassword(_this6.serviceName, _this6.accountName));
1104
- });
1105
- }, function (err) {
1106
- throw PersistenceError.createLibSecretError(err.code, err.message);
1107
- }));
1108
- } catch (e) {
1109
- return Promise.reject(e);
810
+ if (!msalCommon.StringUtils.isEmpty(this.homeEnvVar)) {
811
+ return this.homeEnvVar;
1110
812
  }
1111
- };
1112
813
 
1113
- _proto.reloadNecessary = function reloadNecessary(lastSync) {
1114
- try {
1115
- var _this8 = this;
814
+ let username = null;
1116
815
 
1117
- return Promise.resolve(_this8.filePersistence.reloadNecessary(lastSync));
1118
- } catch (e) {
1119
- return Promise.reject(e);
816
+ if (!msalCommon.StringUtils.isEmpty(this.lognameEnvVar)) {
817
+ username = this.lognameEnvVar;
818
+ } else if (!msalCommon.StringUtils.isEmpty(this.userEnvVar)) {
819
+ username = this.userEnvVar;
820
+ } else if (!msalCommon.StringUtils.isEmpty(this.lnameEnvVar)) {
821
+ username = this.lnameEnvVar;
822
+ } else if (!msalCommon.StringUtils.isEmpty(this.usernameEnvVar)) {
823
+ username = this.usernameEnvVar;
1120
824
  }
1121
- };
1122
825
 
1123
- _proto.getFilePath = function getFilePath() {
1124
- return this.filePersistence.getFilePath();
1125
- };
826
+ if (this.isMacPlatform()) {
827
+ return !msalCommon.StringUtils.isEmpty(username) ? path__default.join("/Users", username) : null;
828
+ } else if (this.isLinuxPlatform()) {
829
+ if (this.isLinuxRootUser()) {
830
+ return "/root";
831
+ } else {
832
+ return !msalCommon.StringUtils.isEmpty(username) ? path__default.join("/home", username) : null;
833
+ }
834
+ } else {
835
+ throw PersistenceError.createNotSupportedError("Getting the user home directory for unix is not supported in windows");
836
+ }
837
+ }
1126
838
 
1127
- _proto.getLogger = function getLogger() {
1128
- return this.filePersistence.getLogger();
1129
- };
839
+ }
840
+
841
+ /*
842
+ * Copyright (c) Microsoft Corporation. All rights reserved.
843
+ * Licensed under the MIT License.
844
+ */
845
+ class PersistenceCreator {
846
+ static async createPersistence(config) {
847
+ let peristence; // On Windows, uses a DPAPI encrypted file
848
+
849
+ if (Environment.isWindowsPlatform()) {
850
+ if (!config.cachePath || !config.dataProtectionScope) {
851
+ throw PersistenceError.createPersistenceNotValidatedError("Cache path and/or data protection scope not provided for the FilePersistenceWithDataProtection cache plugin");
852
+ }
853
+
854
+ peristence = await FilePersistenceWithDataProtection.create(config.cachePath, exports.DataProtectionScope.CurrentUser);
855
+ } // On Mac, uses keychain.
856
+ else if (Environment.isMacPlatform()) {
857
+ if (!config.cachePath || !config.serviceName || !config.accountName) {
858
+ throw PersistenceError.createPersistenceNotValidatedError("Cache path, service name and/or account name not provided for the KeychainPersistence cache plugin");
859
+ }
860
+
861
+ peristence = await KeychainPersistence.create(config.cachePath, config.serviceName, config.accountName);
862
+ } // On Linux, uses libsecret to store to secret service. Libsecret has to be installed.
863
+ else if (Environment.isLinuxPlatform()) {
864
+ if (!config.cachePath || !config.serviceName || !config.accountName) {
865
+ throw PersistenceError.createPersistenceNotValidatedError("Cache path, service name and/or account name not provided for the LibSecretPersistence cache plugin");
866
+ }
867
+
868
+ peristence = await LibSecretPersistence.create(config.cachePath, config.serviceName, config.accountName);
869
+ } else {
870
+ throw PersistenceError.createNotSupportedError("The current environment is not supported by msal-node-extensions yet.");
871
+ } // Initially suppress the error thrown during persistence verification to allow us to fallback to plain text
872
+
873
+
874
+ const isPersistenceVerified = await peristence.verifyPersistence().catch(() => false);
1130
875
 
1131
- return LibSecretPersistence;
1132
- }();
876
+ if (!isPersistenceVerified) {
877
+ if (Environment.isLinuxPlatform() && config.usePlaintextFileOnLinux) {
878
+ if (!config.cachePath) {
879
+ throw PersistenceError.createPersistenceNotValidatedError("Cache path not provided for the FilePersistence cache plugin");
880
+ }
881
+
882
+ peristence = await FilePersistence.create(config.cachePath);
883
+ const isFilePersistenceVerified = await peristence.verifyPersistence();
884
+
885
+ if (isFilePersistenceVerified) {
886
+ return peristence;
887
+ }
888
+ }
889
+
890
+ throw PersistenceError.createPersistenceNotVerifiedError("Persistence could not be verified");
891
+ }
892
+
893
+ return peristence;
894
+ }
895
+
896
+ }
1133
897
 
898
+ exports.Environment = Environment;
1134
899
  exports.FilePersistence = FilePersistence;
1135
900
  exports.FilePersistenceWithDataProtection = FilePersistenceWithDataProtection;
1136
901
  exports.KeychainPersistence = KeychainPersistence;
1137
902
  exports.LibSecretPersistence = LibSecretPersistence;
1138
903
  exports.PersistenceCachePlugin = PersistenceCachePlugin;
904
+ exports.PersistenceCreator = PersistenceCreator;
1139
905
  //# sourceMappingURL=msal-node-extensions.cjs.development.js.map