@azure/msal-node-extensions 1.0.0-alpha.0 → 1.0.0-alpha.12
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/CHANGELOG.json +226 -0
- package/CHANGELOG.md +102 -0
- package/LICENSE +21 -21
- package/README.md +193 -44
- package/binding.gyp +29 -0
- package/dist/error/PersistenceError.d.ts +32 -4
- package/dist/index.d.ts +3 -0
- package/dist/msal-node-extensions.cjs.development.js +615 -849
- package/dist/msal-node-extensions.cjs.development.js.map +1 -1
- package/dist/msal-node-extensions.cjs.production.min.js +1 -1
- package/dist/msal-node-extensions.cjs.production.min.js.map +1 -1
- package/dist/msal-node-extensions.esm.js +625 -864
- package/dist/msal-node-extensions.esm.js.map +1 -1
- package/dist/persistence/BasePersistence.d.ts +5 -0
- package/dist/persistence/FilePersistence.d.ts +4 -2
- package/dist/persistence/FilePersistenceWithDataProtection.d.ts +3 -1
- package/dist/persistence/IPersistence.d.ts +3 -1
- package/dist/persistence/IPersistenceConfiguration.d.ts +8 -0
- package/dist/persistence/KeychainPersistence.d.ts +3 -1
- package/dist/persistence/LibSecretPersistence.d.ts +3 -1
- package/dist/persistence/PersistenceCachePlugin.d.ts +11 -7
- package/dist/persistence/PersistenceCreator.d.ts +5 -0
- package/dist/utils/Constants.d.ts +31 -0
- package/dist/utils/Environment.d.ts +16 -0
- package/package.json +30 -19
- package/src/dpapi-addon/Dpapi.ts +17 -12
- package/src/dpapi-addon/dpapi_addon.h +6 -6
- package/src/dpapi-addon/dpapi_not_supported.cpp +19 -19
- package/src/dpapi-addon/dpapi_win.cpp +114 -114
- package/src/dpapi-addon/main.cpp +32 -32
- package/src/error/PersistenceError.ts +101 -65
- package/src/index.ts +16 -8
- package/src/lock/CrossPlatformLock.ts +89 -82
- package/src/lock/CrossPlatformLockOptions.ts +15 -15
- package/src/persistence/BasePersistence.ts +41 -0
- package/src/persistence/DataProtectionScope.ts +20 -20
- package/src/persistence/FilePersistence.ts +140 -134
- package/src/persistence/FilePersistenceWithDataProtection.ts +92 -84
- package/src/persistence/IPersistence.ts +17 -15
- package/src/persistence/IPersistenceConfiguration.ts +14 -0
- package/src/persistence/KeychainPersistence.ts +86 -78
- package/src/persistence/LibSecretPersistence.ts +87 -79
- package/src/persistence/PersistenceCachePlugin.ts +106 -96
- package/src/persistence/PersistenceCreator.ts +73 -0
- package/src/utils/Constants.ts +62 -24
- package/src/utils/Environment.ts +99 -0
- package/changelog.md +0 -8
|
@@ -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
|
-
|
|
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
|
-
*
|
|
32
|
+
* Operation not permitted. An attempt was made to perform an operation that requires
|
|
33
|
+
* elevated privileges.
|
|
216
34
|
*/
|
|
217
|
-
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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
|
-
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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
|
-
|
|
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
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
-
|
|
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
|
-
|
|
355
|
-
|
|
356
|
-
return new PersistenceError("GnomeKeyringError",
|
|
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
|
-
|
|
364
|
-
|
|
365
|
-
return new PersistenceError("KeychainError",
|
|
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
|
-
|
|
373
|
-
|
|
374
|
-
return new PersistenceError("DPAPIEncryptedFileError",
|
|
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
|
-
|
|
387
|
-
|
|
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
|
-
|
|
394
|
-
|
|
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
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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
|
-
|
|
228
|
+
|
|
229
|
+
async unlock() {
|
|
463
230
|
try {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
|
|
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
|
-
|
|
484
|
-
return new Promise(
|
|
249
|
+
sleep(ms) {
|
|
250
|
+
return new Promise(resolve => {
|
|
485
251
|
setTimeout(resolve, ms);
|
|
486
252
|
});
|
|
487
|
-
}
|
|
253
|
+
}
|
|
488
254
|
|
|
489
|
-
|
|
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
|
-
|
|
507
|
-
|
|
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()
|
|
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
|
|
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
|
-
|
|
525
|
-
|
|
526
|
-
|
|
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
|
-
|
|
533
|
-
|
|
534
|
-
|
|
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
|
-
|
|
538
|
-
|
|
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
|
-
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
|
|
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
|
|
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
|
-
|
|
330
|
+
|
|
331
|
+
async afterCacheAccess(cacheContext) {
|
|
332
|
+
this.logger.info("Executing after cache access");
|
|
333
|
+
|
|
576
334
|
try {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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
|
-
|
|
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
|
-
|
|
374
|
+
throw PersistenceError.createCachePersistenceError(`Verifing persistence failed with the error: ${e}`);
|
|
619
375
|
}
|
|
620
|
-
}
|
|
376
|
+
}
|
|
621
377
|
|
|
622
|
-
|
|
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
|
-
|
|
634
|
-
|
|
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
|
-
|
|
401
|
+
async save(contents) {
|
|
637
402
|
try {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
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
|
-
|
|
409
|
+
async saveBuffer(contents) {
|
|
666
410
|
try {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
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
|
-
|
|
417
|
+
async load() {
|
|
680
418
|
try {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
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
|
-
|
|
425
|
+
async loadBuffer() {
|
|
694
426
|
try {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
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
|
-
|
|
433
|
+
async delete() {
|
|
708
434
|
try {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
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
|
-
|
|
724
|
-
}));
|
|
725
|
-
} catch (e) {
|
|
726
|
-
return Promise.reject(e);
|
|
444
|
+
throw PersistenceError.createFileSystemError(err.code, err.message);
|
|
727
445
|
}
|
|
728
|
-
}
|
|
446
|
+
}
|
|
729
447
|
|
|
730
|
-
|
|
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
|
-
|
|
739
|
-
|
|
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
|
-
|
|
456
|
+
getLogger() {
|
|
747
457
|
return this.logger;
|
|
748
|
-
}
|
|
458
|
+
}
|
|
749
459
|
|
|
750
|
-
|
|
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:
|
|
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
|
-
|
|
474
|
+
async timeLastModified() {
|
|
760
475
|
try {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
795
|
-
|
|
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
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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
|
-
|
|
820
|
-
|
|
518
|
+
/* eslint-disable-next-line @typescript-eslint/no-var-requires, no-var */
|
|
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
|
-
|
|
836
|
-
|
|
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
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
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
|
-
|
|
558
|
+
async save(contents) {
|
|
856
559
|
try {
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
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
|
-
|
|
567
|
+
async load() {
|
|
871
568
|
try {
|
|
872
|
-
|
|
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
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
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
|
|
897
|
-
} catch (
|
|
898
|
-
|
|
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
|
-
|
|
903
|
-
|
|
904
|
-
|
|
582
|
+
async delete() {
|
|
583
|
+
return this.filePersistence.delete();
|
|
584
|
+
}
|
|
905
585
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
}
|
|
910
|
-
};
|
|
586
|
+
async reloadNecessary(lastSync) {
|
|
587
|
+
return this.filePersistence.reloadNecessary(lastSync);
|
|
588
|
+
}
|
|
911
589
|
|
|
912
|
-
|
|
590
|
+
getFilePath() {
|
|
913
591
|
return this.filePersistence.getFilePath();
|
|
914
|
-
}
|
|
592
|
+
}
|
|
915
593
|
|
|
916
|
-
|
|
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
|
-
|
|
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
|
-
|
|
941
|
-
|
|
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
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
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
|
-
|
|
629
|
+
async save(contents) {
|
|
961
630
|
try {
|
|
962
|
-
|
|
963
|
-
|
|
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
|
-
|
|
971
|
-
|
|
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
|
-
|
|
640
|
+
async load() {
|
|
983
641
|
try {
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
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
|
-
|
|
648
|
+
async delete() {
|
|
997
649
|
try {
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
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
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
}
|
|
1020
|
-
};
|
|
657
|
+
async reloadNecessary(lastSync) {
|
|
658
|
+
return this.filePersistence.reloadNecessary(lastSync);
|
|
659
|
+
}
|
|
1021
660
|
|
|
1022
|
-
|
|
661
|
+
getFilePath() {
|
|
1023
662
|
return this.filePersistence.getFilePath();
|
|
1024
|
-
}
|
|
663
|
+
}
|
|
1025
664
|
|
|
1026
|
-
|
|
665
|
+
getLogger() {
|
|
1027
666
|
return this.filePersistence.getLogger();
|
|
1028
|
-
}
|
|
667
|
+
}
|
|
1029
668
|
|
|
1030
|
-
|
|
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
|
-
|
|
1042
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
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
|
-
|
|
709
|
+
await this.filePersistence.save("{}");
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
async load() {
|
|
1062
713
|
try {
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
714
|
+
return await keytar.getPassword(this.serviceName, this.accountName);
|
|
715
|
+
} catch (err) {
|
|
716
|
+
throw PersistenceError.createLibSecretError(err.message);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
1066
719
|
|
|
1067
|
-
|
|
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
|
-
|
|
729
|
+
async reloadNecessary(lastSync) {
|
|
730
|
+
return this.filePersistence.reloadNecessary(lastSync);
|
|
731
|
+
}
|
|
1070
732
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
throw PersistenceError.createLibSecretError(err.code, err.message);
|
|
1075
|
-
});
|
|
733
|
+
getFilePath() {
|
|
734
|
+
return this.filePersistence.getFilePath();
|
|
735
|
+
}
|
|
1076
736
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
}
|
|
1081
|
-
};
|
|
737
|
+
getLogger() {
|
|
738
|
+
return this.filePersistence.getLogger();
|
|
739
|
+
}
|
|
1082
740
|
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
741
|
+
createForPersistenceValidation() {
|
|
742
|
+
const testCacheFileLocation = `${path.dirname(this.filePersistence.getFilePath())}/test.cache`;
|
|
743
|
+
return LibSecretPersistence.create(testCacheFileLocation, "persistenceValidationServiceName", "persistencValidationAccountName");
|
|
744
|
+
}
|
|
1086
745
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
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
|
-
|
|
1098
|
-
|
|
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
|
-
|
|
1114
|
-
try {
|
|
1115
|
-
var _this8 = this;
|
|
814
|
+
let username = null;
|
|
1116
815
|
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
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
|
-
|
|
1124
|
-
|
|
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
|
-
|
|
1128
|
-
|
|
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
|
-
|
|
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
|