@lvce-editor/auth-worker 3.21.0 → 3.22.1
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/dist/authWorkerMain.js +276 -175
- package/package.json +1 -1
package/dist/authWorkerMain.js
CHANGED
|
@@ -1135,18 +1135,17 @@ const {
|
|
|
1135
1135
|
const {
|
|
1136
1136
|
invoke,
|
|
1137
1137
|
invokeAndTransfer} = create(RendererWorker);
|
|
1138
|
-
const sendMessagePortToOpenerWorker
|
|
1138
|
+
const sendMessagePortToOpenerWorker = async (port, rpcId) => {
|
|
1139
1139
|
const command = 'HandleMessagePort.handleMessagePort';
|
|
1140
1140
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToOpenerWorker', port, command, rpcId);
|
|
1141
1141
|
};
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
await sendMessagePortToOpenerWorker$1(port, 0);
|
|
1142
|
+
const send = async (port, sourceId = 0) => {
|
|
1143
|
+
await sendMessagePortToOpenerWorker(port, sourceId);
|
|
1145
1144
|
};
|
|
1146
1145
|
const initializeOpenerWorker = async () => {
|
|
1147
1146
|
const rpc = await create$2({
|
|
1148
1147
|
commandMap: {},
|
|
1149
|
-
send
|
|
1148
|
+
send
|
|
1150
1149
|
});
|
|
1151
1150
|
set(rpc);
|
|
1152
1151
|
};
|
|
@@ -2171,6 +2170,259 @@ const getOidcUserName = async (backendUrl, accessToken, fetchFn = fetch) => {
|
|
|
2171
2170
|
return typeof displayName === 'string' ? displayName : '';
|
|
2172
2171
|
};
|
|
2173
2172
|
|
|
2173
|
+
const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
|
|
2174
|
+
let idbProxyableTypes;
|
|
2175
|
+
let cursorAdvanceMethods;
|
|
2176
|
+
// This is a function to prevent it throwing up in node environments.
|
|
2177
|
+
function getIdbProxyableTypes() {
|
|
2178
|
+
return idbProxyableTypes || (idbProxyableTypes = [IDBIndex, IDBObjectStore, IDBCursor, IDBDatabase, IDBTransaction]);
|
|
2179
|
+
}
|
|
2180
|
+
// This is a function to prevent it throwing up in node environments.
|
|
2181
|
+
function getCursorAdvanceMethods() {
|
|
2182
|
+
return cursorAdvanceMethods || (cursorAdvanceMethods = ['advance', 'continue', 'continuePrimaryKey'].map(method => IDBCursor.prototype[method]));
|
|
2183
|
+
}
|
|
2184
|
+
const transactionDoneMap = new WeakMap();
|
|
2185
|
+
const transformCache = new WeakMap();
|
|
2186
|
+
const reverseTransformCache = new WeakMap();
|
|
2187
|
+
function promisifyRequest(request) {
|
|
2188
|
+
const promise = new Promise((resolve, reject) => {
|
|
2189
|
+
const unlisten = () => {
|
|
2190
|
+
request.removeEventListener('success', success);
|
|
2191
|
+
request.removeEventListener('error', error);
|
|
2192
|
+
};
|
|
2193
|
+
const success = () => {
|
|
2194
|
+
resolve(wrap(request.result));
|
|
2195
|
+
unlisten();
|
|
2196
|
+
};
|
|
2197
|
+
const error = () => {
|
|
2198
|
+
reject(request.error);
|
|
2199
|
+
unlisten();
|
|
2200
|
+
};
|
|
2201
|
+
request.addEventListener('success', success);
|
|
2202
|
+
request.addEventListener('error', error);
|
|
2203
|
+
});
|
|
2204
|
+
// This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
|
|
2205
|
+
// is because we create many promises from a single IDBRequest.
|
|
2206
|
+
reverseTransformCache.set(promise, request);
|
|
2207
|
+
return promise;
|
|
2208
|
+
}
|
|
2209
|
+
function cacheDonePromiseForTransaction(tx) {
|
|
2210
|
+
// Early bail if we've already created a done promise for this transaction.
|
|
2211
|
+
if (transactionDoneMap.has(tx)) return;
|
|
2212
|
+
const done = new Promise((resolve, reject) => {
|
|
2213
|
+
const unlisten = () => {
|
|
2214
|
+
tx.removeEventListener('complete', complete);
|
|
2215
|
+
tx.removeEventListener('error', error);
|
|
2216
|
+
tx.removeEventListener('abort', error);
|
|
2217
|
+
};
|
|
2218
|
+
const complete = () => {
|
|
2219
|
+
resolve();
|
|
2220
|
+
unlisten();
|
|
2221
|
+
};
|
|
2222
|
+
const error = () => {
|
|
2223
|
+
reject(tx.error || new DOMException('AbortError', 'AbortError'));
|
|
2224
|
+
unlisten();
|
|
2225
|
+
};
|
|
2226
|
+
tx.addEventListener('complete', complete);
|
|
2227
|
+
tx.addEventListener('error', error);
|
|
2228
|
+
tx.addEventListener('abort', error);
|
|
2229
|
+
});
|
|
2230
|
+
// Cache it for later retrieval.
|
|
2231
|
+
transactionDoneMap.set(tx, done);
|
|
2232
|
+
}
|
|
2233
|
+
let idbProxyTraps = {
|
|
2234
|
+
get(target, prop, receiver) {
|
|
2235
|
+
if (target instanceof IDBTransaction) {
|
|
2236
|
+
// Special handling for transaction.done.
|
|
2237
|
+
if (prop === 'done') return transactionDoneMap.get(target);
|
|
2238
|
+
// Make tx.store return the only store in the transaction, or undefined if there are many.
|
|
2239
|
+
if (prop === 'store') {
|
|
2240
|
+
return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
// Else transform whatever we get back.
|
|
2244
|
+
return wrap(target[prop]);
|
|
2245
|
+
},
|
|
2246
|
+
set(target, prop, value) {
|
|
2247
|
+
target[prop] = value;
|
|
2248
|
+
return true;
|
|
2249
|
+
},
|
|
2250
|
+
has(target, prop) {
|
|
2251
|
+
if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
|
|
2252
|
+
return true;
|
|
2253
|
+
}
|
|
2254
|
+
return prop in target;
|
|
2255
|
+
}
|
|
2256
|
+
};
|
|
2257
|
+
function replaceTraps(callback) {
|
|
2258
|
+
idbProxyTraps = callback(idbProxyTraps);
|
|
2259
|
+
}
|
|
2260
|
+
function wrapFunction(func) {
|
|
2261
|
+
// Due to expected object equality (which is enforced by the caching in `wrap`), we
|
|
2262
|
+
// only create one new func per func.
|
|
2263
|
+
// Cursor methods are special, as the behaviour is a little more different to standard IDB. In
|
|
2264
|
+
// IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
|
|
2265
|
+
// cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
|
|
2266
|
+
// with real promises, so each advance methods returns a new promise for the cursor object, or
|
|
2267
|
+
// undefined if the end of the cursor has been reached.
|
|
2268
|
+
if (getCursorAdvanceMethods().includes(func)) {
|
|
2269
|
+
return function (...args) {
|
|
2270
|
+
// Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
|
|
2271
|
+
// the original object.
|
|
2272
|
+
func.apply(unwrap(this), args);
|
|
2273
|
+
return wrap(this.request);
|
|
2274
|
+
};
|
|
2275
|
+
}
|
|
2276
|
+
return function (...args) {
|
|
2277
|
+
// Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
|
|
2278
|
+
// the original object.
|
|
2279
|
+
return wrap(func.apply(unwrap(this), args));
|
|
2280
|
+
};
|
|
2281
|
+
}
|
|
2282
|
+
function transformCachableValue(value) {
|
|
2283
|
+
if (typeof value === 'function') return wrapFunction(value);
|
|
2284
|
+
// This doesn't return, it just creates a 'done' promise for the transaction,
|
|
2285
|
+
// which is later returned for transaction.done (see idbObjectHandler).
|
|
2286
|
+
if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
|
|
2287
|
+
if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
|
|
2288
|
+
// Return the same value back if we're not going to transform it.
|
|
2289
|
+
return value;
|
|
2290
|
+
}
|
|
2291
|
+
function wrap(value) {
|
|
2292
|
+
// We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
|
|
2293
|
+
// IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
|
|
2294
|
+
if (value instanceof IDBRequest) return promisifyRequest(value);
|
|
2295
|
+
// If we've already transformed this value before, reuse the transformed value.
|
|
2296
|
+
// This is faster, but it also provides object equality.
|
|
2297
|
+
if (transformCache.has(value)) return transformCache.get(value);
|
|
2298
|
+
const newValue = transformCachableValue(value);
|
|
2299
|
+
// Not all types are transformed.
|
|
2300
|
+
// These may be primitive types, so they can't be WeakMap keys.
|
|
2301
|
+
if (!Object.is(newValue, value)) {
|
|
2302
|
+
transformCache.set(value, newValue);
|
|
2303
|
+
reverseTransformCache.set(newValue, value);
|
|
2304
|
+
}
|
|
2305
|
+
return newValue;
|
|
2306
|
+
}
|
|
2307
|
+
const unwrap = value => reverseTransformCache.get(value);
|
|
2308
|
+
|
|
2309
|
+
/**
|
|
2310
|
+
* Open a database.
|
|
2311
|
+
*
|
|
2312
|
+
* @param name Name of the database.
|
|
2313
|
+
* @param version Schema version.
|
|
2314
|
+
* @param callbacks Additional callbacks.
|
|
2315
|
+
*/
|
|
2316
|
+
function openDB(name, version, {
|
|
2317
|
+
blocked,
|
|
2318
|
+
upgrade,
|
|
2319
|
+
blocking,
|
|
2320
|
+
terminated
|
|
2321
|
+
} = {}) {
|
|
2322
|
+
const request = indexedDB.open(name, version);
|
|
2323
|
+
const openPromise = wrap(request);
|
|
2324
|
+
if (upgrade) {
|
|
2325
|
+
request.addEventListener('upgradeneeded', event => {
|
|
2326
|
+
upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
|
|
2327
|
+
});
|
|
2328
|
+
}
|
|
2329
|
+
if (blocked) {
|
|
2330
|
+
request.addEventListener('blocked', event => blocked(
|
|
2331
|
+
// Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
|
|
2332
|
+
event.oldVersion, event.newVersion, event));
|
|
2333
|
+
}
|
|
2334
|
+
openPromise.then(db => {
|
|
2335
|
+
if (terminated) db.addEventListener('close', () => terminated());
|
|
2336
|
+
if (blocking) {
|
|
2337
|
+
db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
|
|
2338
|
+
}
|
|
2339
|
+
}).catch(() => {});
|
|
2340
|
+
return openPromise;
|
|
2341
|
+
}
|
|
2342
|
+
const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
|
|
2343
|
+
const writeMethods = ['put', 'add', 'delete', 'clear'];
|
|
2344
|
+
const cachedMethods = {};
|
|
2345
|
+
function getMethod(target, prop) {
|
|
2346
|
+
if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
if (cachedMethods[prop]) return cachedMethods[prop];
|
|
2350
|
+
const targetFuncName = prop.replace(/FromIndex$/, '');
|
|
2351
|
+
const useIndex = prop !== targetFuncName;
|
|
2352
|
+
const isWrite = writeMethods.includes(targetFuncName);
|
|
2353
|
+
if (
|
|
2354
|
+
// Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
|
|
2355
|
+
!(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
const method = async function (storeName, ...args) {
|
|
2359
|
+
// isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
|
|
2360
|
+
const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
|
|
2361
|
+
let target = tx.store;
|
|
2362
|
+
if (useIndex) target = target.index(args.shift());
|
|
2363
|
+
// Must reject if op rejects.
|
|
2364
|
+
// If it's a write operation, must reject if tx.done rejects.
|
|
2365
|
+
// Must reject with op rejection first.
|
|
2366
|
+
// Must resolve with op value.
|
|
2367
|
+
// Must handle both promises (no unhandled rejections)
|
|
2368
|
+
return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
|
|
2369
|
+
};
|
|
2370
|
+
return cachedMethods[prop] = method;
|
|
2371
|
+
}
|
|
2372
|
+
replaceTraps(oldTraps => ({
|
|
2373
|
+
...oldTraps,
|
|
2374
|
+
get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
|
|
2375
|
+
has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
|
|
2376
|
+
}));
|
|
2377
|
+
const advanceMethodProps = ['advance', 'continue', 'continuePrimaryKey'];
|
|
2378
|
+
const methodMap = {};
|
|
2379
|
+
const advanceResults = new WeakMap();
|
|
2380
|
+
const ittrProxiedCursorToOriginalProxy = new WeakMap();
|
|
2381
|
+
const cursorIteratorTraps = {
|
|
2382
|
+
get(target, prop) {
|
|
2383
|
+
if (!advanceMethodProps.includes(prop)) return target[prop];
|
|
2384
|
+
let cachedFunc = methodMap[prop];
|
|
2385
|
+
if (!cachedFunc) {
|
|
2386
|
+
cachedFunc = methodMap[prop] = function (...args) {
|
|
2387
|
+
advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
return cachedFunc;
|
|
2391
|
+
}
|
|
2392
|
+
};
|
|
2393
|
+
async function* iterate(...args) {
|
|
2394
|
+
// tslint:disable-next-line:no-this-assignment
|
|
2395
|
+
let cursor = this;
|
|
2396
|
+
if (!(cursor instanceof IDBCursor)) {
|
|
2397
|
+
cursor = await cursor.openCursor(...args);
|
|
2398
|
+
}
|
|
2399
|
+
if (!cursor) return;
|
|
2400
|
+
cursor = cursor;
|
|
2401
|
+
const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
|
|
2402
|
+
ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
|
|
2403
|
+
// Map this double-proxy back to the original, so other cursor methods work.
|
|
2404
|
+
reverseTransformCache.set(proxiedCursor, unwrap(cursor));
|
|
2405
|
+
while (cursor) {
|
|
2406
|
+
yield proxiedCursor;
|
|
2407
|
+
// If one of the advancing methods was not called, call continue().
|
|
2408
|
+
cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
|
|
2409
|
+
advanceResults.delete(proxiedCursor);
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
function isIteratorProp(target, prop) {
|
|
2413
|
+
return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
|
|
2414
|
+
}
|
|
2415
|
+
replaceTraps(oldTraps => ({
|
|
2416
|
+
...oldTraps,
|
|
2417
|
+
get(target, prop, receiver) {
|
|
2418
|
+
if (isIteratorProp(target, prop)) return iterate;
|
|
2419
|
+
return oldTraps.get(target, prop, receiver);
|
|
2420
|
+
},
|
|
2421
|
+
has(target, prop) {
|
|
2422
|
+
return isIteratorProp(target, prop) || oldTraps.has(target, prop);
|
|
2423
|
+
}
|
|
2424
|
+
}));
|
|
2425
|
+
|
|
2174
2426
|
const authStorageId = 'lvce-editor.auth';
|
|
2175
2427
|
const deleteSecret = async key => {
|
|
2176
2428
|
await deleteSecret$1(authStorageId, key);
|
|
@@ -2189,53 +2441,18 @@ const secretKeys = new Set(['accessToken', 'refreshToken', 'accountSessions']);
|
|
|
2189
2441
|
const state$2 = {
|
|
2190
2442
|
databasePromise: undefined
|
|
2191
2443
|
};
|
|
2192
|
-
|
|
2193
|
-
// IndexedDB request objects are mutable browser primitives and cannot satisfy the readonly rule structurally.
|
|
2194
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
2195
|
-
const requestToPromise = request => {
|
|
2196
|
-
return new Promise((resolve, reject) => {
|
|
2197
|
-
request.addEventListener('success', () => {
|
|
2198
|
-
resolve(request.result);
|
|
2199
|
-
});
|
|
2200
|
-
request.addEventListener('error', () => {
|
|
2201
|
-
reject(request.error ?? new Error('Persistent storage request failed.'));
|
|
2202
|
-
});
|
|
2203
|
-
});
|
|
2204
|
-
};
|
|
2205
|
-
|
|
2206
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
2207
|
-
const transactionToPromise = transaction => {
|
|
2208
|
-
return new Promise((resolve, reject) => {
|
|
2209
|
-
transaction.addEventListener('complete', () => {
|
|
2210
|
-
resolve();
|
|
2211
|
-
});
|
|
2212
|
-
transaction.addEventListener('abort', () => {
|
|
2213
|
-
reject(transaction.error ?? new Error('Persistent storage transaction failed.'));
|
|
2214
|
-
});
|
|
2215
|
-
transaction.addEventListener('error', () => {
|
|
2216
|
-
reject(transaction.error ?? new Error('Persistent storage transaction failed.'));
|
|
2217
|
-
});
|
|
2218
|
-
});
|
|
2219
|
-
};
|
|
2220
2444
|
const getDatabase = async () => {
|
|
2221
2445
|
if (typeof indexedDB === 'undefined') {
|
|
2222
2446
|
return undefined;
|
|
2223
2447
|
}
|
|
2224
2448
|
if (!state$2.databasePromise) {
|
|
2225
|
-
state$2.databasePromise =
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
const database = request.result;
|
|
2449
|
+
state$2.databasePromise = openDB(databaseName, 1, {
|
|
2450
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
2451
|
+
upgrade(database) {
|
|
2229
2452
|
if (!database.objectStoreNames.contains(objectStoreName)) {
|
|
2230
2453
|
database.createObjectStore(objectStoreName);
|
|
2231
2454
|
}
|
|
2232
|
-
}
|
|
2233
|
-
request.addEventListener('success', () => {
|
|
2234
|
-
resolve(request.result);
|
|
2235
|
-
});
|
|
2236
|
-
request.addEventListener('error', () => {
|
|
2237
|
-
reject(request.error ?? new Error('Failed to open persistent auth storage.'));
|
|
2238
|
-
});
|
|
2455
|
+
}
|
|
2239
2456
|
});
|
|
2240
2457
|
}
|
|
2241
2458
|
return state$2.databasePromise;
|
|
@@ -2245,9 +2462,7 @@ const getIndexedDbValue = async key => {
|
|
|
2245
2462
|
if (!database) {
|
|
2246
2463
|
return memoryStorage.get(key) ?? '';
|
|
2247
2464
|
}
|
|
2248
|
-
const
|
|
2249
|
-
const objectStore = transaction.objectStore(objectStoreName);
|
|
2250
|
-
const value = await requestToPromise(objectStore.get(key));
|
|
2465
|
+
const value = await database.get(objectStoreName, key);
|
|
2251
2466
|
return typeof value === 'string' ? value : '';
|
|
2252
2467
|
};
|
|
2253
2468
|
const setIndexedDbValue = async (key, value) => {
|
|
@@ -2256,10 +2471,7 @@ const setIndexedDbValue = async (key, value) => {
|
|
|
2256
2471
|
if (!database) {
|
|
2257
2472
|
return;
|
|
2258
2473
|
}
|
|
2259
|
-
|
|
2260
|
-
const objectStore = transaction.objectStore(objectStoreName);
|
|
2261
|
-
objectStore.put(value, key);
|
|
2262
|
-
await transactionToPromise(transaction);
|
|
2474
|
+
await database.put(objectStoreName, value, key);
|
|
2263
2475
|
};
|
|
2264
2476
|
const clearIndexedDbValue = async key => {
|
|
2265
2477
|
memoryStorage.delete(key);
|
|
@@ -2267,10 +2479,7 @@ const clearIndexedDbValue = async key => {
|
|
|
2267
2479
|
if (!database) {
|
|
2268
2480
|
return;
|
|
2269
2481
|
}
|
|
2270
|
-
|
|
2271
|
-
const objectStore = transaction.objectStore(objectStoreName);
|
|
2272
|
-
objectStore.delete(key);
|
|
2273
|
-
await transactionToPromise(transaction);
|
|
2482
|
+
await database.delete(objectStoreName, key);
|
|
2274
2483
|
};
|
|
2275
2484
|
const shouldUseSecretStorage = key => {
|
|
2276
2485
|
return getAuthPlatform() === Electron && secretKeys.has(key);
|
|
@@ -2279,17 +2488,7 @@ const getPersistentAuthValue = async key => {
|
|
|
2279
2488
|
if (!shouldUseSecretStorage(key)) {
|
|
2280
2489
|
return getIndexedDbValue(key);
|
|
2281
2490
|
}
|
|
2282
|
-
|
|
2283
|
-
if (secret) {
|
|
2284
|
-
return secret;
|
|
2285
|
-
}
|
|
2286
|
-
const legacyValue = await getIndexedDbValue(key);
|
|
2287
|
-
if (!legacyValue) {
|
|
2288
|
-
return '';
|
|
2289
|
-
}
|
|
2290
|
-
await storeSecret(key, legacyValue);
|
|
2291
|
-
await clearIndexedDbValue(key);
|
|
2292
|
-
return legacyValue;
|
|
2491
|
+
return (await getSecret(key)) || '';
|
|
2293
2492
|
};
|
|
2294
2493
|
const setPersistentAuthValue = async (key, value) => {
|
|
2295
2494
|
if (!shouldUseSecretStorage(key)) {
|
|
@@ -2550,58 +2749,9 @@ const userNameKey = 'userName';
|
|
|
2550
2749
|
const userSubscriptionPlanKey = 'userSubscriptionPlan';
|
|
2551
2750
|
const userSubscriptionStatusKey = 'userSubscriptionStatus';
|
|
2552
2751
|
const userUsedTokensKey = 'userUsedTokens';
|
|
2553
|
-
const toOptionalString = value => {
|
|
2554
|
-
return value || undefined;
|
|
2555
|
-
};
|
|
2556
|
-
const toOptionalNumber = value => {
|
|
2557
|
-
if (!value) {
|
|
2558
|
-
return undefined;
|
|
2559
|
-
}
|
|
2560
|
-
const numberValue = Number(value);
|
|
2561
|
-
return Number.isFinite(numberValue) ? numberValue : undefined;
|
|
2562
|
-
};
|
|
2563
2752
|
const clearPersistedAuthSession = async () => {
|
|
2564
2753
|
await Promise.all([clearPersistentAuthValue(accessTokenKey), clearPersistentAuthValue(accessTokenExpiresAtKey), clearPersistentAuthValue(refreshTokenKey), clearStoredOidcClientId(), clearPersistentAuthValue(userNameKey), clearPersistentAuthValue(userSubscriptionPlanKey), clearPersistentAuthValue(userSubscriptionStatusKey), clearPersistentAuthValue(userUsedTokensKey)]);
|
|
2565
2754
|
};
|
|
2566
|
-
const getPersistedAuthSession = async () => {
|
|
2567
|
-
const [accessToken, accessTokenExpiresAt, refreshToken, authClientId, userName, userSubscriptionPlan, userSubscriptionStatus, userUsedTokens] = await Promise.all([getPersistentAuthValue(accessTokenKey), getPersistentAuthValue(accessTokenExpiresAtKey), getPersistentAuthValue(refreshTokenKey), getStoredOidcClientId(), getPersistentAuthValue(userNameKey), getPersistentAuthValue(userSubscriptionPlanKey), getPersistentAuthValue(userSubscriptionStatusKey), getPersistentAuthValue(userUsedTokensKey)]);
|
|
2568
|
-
if (!accessToken && !refreshToken) {
|
|
2569
|
-
return undefined;
|
|
2570
|
-
}
|
|
2571
|
-
const optionalAuthClientId = toOptionalString(authClientId);
|
|
2572
|
-
const optionalAccessTokenExpiresAt = toOptionalNumber(accessTokenExpiresAt);
|
|
2573
|
-
const optionalRefreshToken = toOptionalString(refreshToken);
|
|
2574
|
-
const optionalUserName = toOptionalString(userName);
|
|
2575
|
-
const optionalSubscriptionPlan = toOptionalString(userSubscriptionPlan);
|
|
2576
|
-
const optionalSubscriptionStatus = toOptionalString(userSubscriptionStatus);
|
|
2577
|
-
const optionalUsedTokens = toOptionalNumber(userUsedTokens);
|
|
2578
|
-
return {
|
|
2579
|
-
authAccessToken: accessToken,
|
|
2580
|
-
...(typeof optionalAccessTokenExpiresAt === 'number' && {
|
|
2581
|
-
authAccessTokenExpiresAt: optionalAccessTokenExpiresAt
|
|
2582
|
-
}),
|
|
2583
|
-
authErrorMessage: '',
|
|
2584
|
-
userState: 'loggedIn',
|
|
2585
|
-
...(optionalAuthClientId && {
|
|
2586
|
-
authClientId
|
|
2587
|
-
}),
|
|
2588
|
-
...(optionalRefreshToken && {
|
|
2589
|
-
authRefreshToken: refreshToken
|
|
2590
|
-
}),
|
|
2591
|
-
...(optionalUserName && {
|
|
2592
|
-
userName
|
|
2593
|
-
}),
|
|
2594
|
-
...(optionalSubscriptionPlan && {
|
|
2595
|
-
userSubscriptionPlan
|
|
2596
|
-
}),
|
|
2597
|
-
...(optionalSubscriptionStatus && {
|
|
2598
|
-
userSubscriptionStatus
|
|
2599
|
-
}),
|
|
2600
|
-
...(typeof optionalUsedTokens === 'number' && {
|
|
2601
|
-
userUsedTokens: optionalUsedTokens
|
|
2602
|
-
})
|
|
2603
|
-
};
|
|
2604
|
-
};
|
|
2605
2755
|
const persistAuthSession = async loginResult => {
|
|
2606
2756
|
await Promise.all([setPersistentAuthValue(accessTokenKey, loginResult.authAccessToken ?? ''), setPersistentAuthValue(accessTokenExpiresAtKey, typeof loginResult.authAccessTokenExpiresAt === 'number' ? String(loginResult.authAccessTokenExpiresAt) : ''), setPersistentAuthValue(refreshTokenKey, loginResult.authRefreshToken ?? ''), loginResult.authClientId ? saveOidcClientId(loginResult.authClientId) : clearStoredOidcClientId(), setPersistentAuthValue(userNameKey, loginResult.userName ?? ''), setPersistentAuthValue(userSubscriptionPlanKey, loginResult.userSubscriptionPlan ?? ''), setPersistentAuthValue(userSubscriptionStatusKey, loginResult.userSubscriptionStatus ?? ''), setPersistentAuthValue(userUsedTokensKey, typeof loginResult.userUsedTokens === 'number' ? String(loginResult.userUsedTokens) : '')]);
|
|
2607
2757
|
};
|
|
@@ -3254,10 +3404,10 @@ const accounts = createAccountSessions({
|
|
|
3254
3404
|
});
|
|
3255
3405
|
const refreshes = new Map();
|
|
3256
3406
|
const state = {
|
|
3257
|
-
login: undefined
|
|
3258
|
-
migration: undefined
|
|
3407
|
+
login: undefined
|
|
3259
3408
|
};
|
|
3260
3409
|
const normalizeBackendUrl = backendUrl => new URL(backendUrl).origin;
|
|
3410
|
+
const getNormalizedBackendUrl = (backendUrl = getAuthBackendUrl()) => normalizeBackendUrl(backendUrl);
|
|
3261
3411
|
const addSession = async (backendUrl, session, revision) => {
|
|
3262
3412
|
if (session.userState !== 'loggedIn' || !session.authAccessToken) {
|
|
3263
3413
|
return;
|
|
@@ -3273,55 +3423,6 @@ const addSession = async (backendUrl, session, revision) => {
|
|
|
3273
3423
|
}
|
|
3274
3424
|
}, revision);
|
|
3275
3425
|
};
|
|
3276
|
-
const migrate = async backendUrl => {
|
|
3277
|
-
if (await getPersistentAuthValue(storageKey)) {
|
|
3278
|
-
return;
|
|
3279
|
-
}
|
|
3280
|
-
const legacy = await getPersistedAuthSession();
|
|
3281
|
-
if (legacy) {
|
|
3282
|
-
if (legacy.authClientId && legacy.authRefreshToken) {
|
|
3283
|
-
const tokens = await refreshOidcTokens(backendUrl, legacy.authClientId, legacy.authRefreshToken);
|
|
3284
|
-
const authAccessTokenExpiresAt = getAccessTokenExpiresAt(tokens.expiresIn);
|
|
3285
|
-
const {
|
|
3286
|
-
authAccessTokenExpiresAt: _legacyExpiry,
|
|
3287
|
-
...legacySession
|
|
3288
|
-
} = legacy;
|
|
3289
|
-
await addSession(backendUrl, {
|
|
3290
|
-
...legacySession,
|
|
3291
|
-
authAccessToken: tokens.accessToken,
|
|
3292
|
-
...(authAccessTokenExpiresAt && {
|
|
3293
|
-
authAccessTokenExpiresAt
|
|
3294
|
-
}),
|
|
3295
|
-
authRefreshToken: tokens.refreshToken
|
|
3296
|
-
}, 0);
|
|
3297
|
-
} else {
|
|
3298
|
-
await addSession(backendUrl, legacy, 0);
|
|
3299
|
-
}
|
|
3300
|
-
} else {
|
|
3301
|
-
await setPersistentAuthValue(storageKey, JSON.stringify({
|
|
3302
|
-
accounts: [],
|
|
3303
|
-
activeId: '',
|
|
3304
|
-
revision: 0
|
|
3305
|
-
}));
|
|
3306
|
-
}
|
|
3307
|
-
// Clear legacy credentials only after the registry is durably committed.
|
|
3308
|
-
await clearPersistedAuthSession();
|
|
3309
|
-
};
|
|
3310
|
-
const ensureMigrated = async (backendUrl = getAuthBackendUrl()) => {
|
|
3311
|
-
const url = normalizeBackendUrl(backendUrl);
|
|
3312
|
-
if (!state.migration) {
|
|
3313
|
-
state.migration = (async () => {
|
|
3314
|
-
try {
|
|
3315
|
-
await migrate(url);
|
|
3316
|
-
} catch (error) {
|
|
3317
|
-
state.migration = undefined;
|
|
3318
|
-
throw error;
|
|
3319
|
-
}
|
|
3320
|
-
})();
|
|
3321
|
-
}
|
|
3322
|
-
await state.migration;
|
|
3323
|
-
return url;
|
|
3324
|
-
};
|
|
3325
3426
|
const getActive = async backendUrl => {
|
|
3326
3427
|
const registry = await accounts.read();
|
|
3327
3428
|
return registry.accounts.find(account => account.id === registry.activeId && account.backendUrl === backendUrl);
|
|
@@ -3387,7 +3488,7 @@ const getConnectionRequestHeaders = accessToken => {
|
|
|
3387
3488
|
};
|
|
3388
3489
|
};
|
|
3389
3490
|
const getConnectedAccounts = async () => {
|
|
3390
|
-
const backendUrl =
|
|
3491
|
+
const backendUrl = getNormalizedBackendUrl();
|
|
3391
3492
|
const accessToken = await getAccessToken({
|
|
3392
3493
|
refresh: 'if-needed'
|
|
3393
3494
|
});
|
|
@@ -3407,7 +3508,7 @@ const getConnectedAccounts = async () => {
|
|
|
3407
3508
|
return payload.connections;
|
|
3408
3509
|
};
|
|
3409
3510
|
const disconnectConnectedAccount = async provider => {
|
|
3410
|
-
const backendUrl =
|
|
3511
|
+
const backendUrl = getNormalizedBackendUrl();
|
|
3411
3512
|
const accessToken = await getAccessToken({
|
|
3412
3513
|
refresh: 'if-needed'
|
|
3413
3514
|
});
|
|
@@ -3423,7 +3524,7 @@ const disconnectConnectedAccount = async provider => {
|
|
|
3423
3524
|
}
|
|
3424
3525
|
};
|
|
3425
3526
|
const getAccounts = async () => {
|
|
3426
|
-
const backendUrl =
|
|
3527
|
+
const backendUrl = getNormalizedBackendUrl();
|
|
3427
3528
|
const registry = await accounts.read();
|
|
3428
3529
|
return registry.accounts.filter(account => account.backendUrl === backendUrl).map(account => ({
|
|
3429
3530
|
...account.profile,
|
|
@@ -3434,7 +3535,7 @@ const getAccounts = async () => {
|
|
|
3434
3535
|
}));
|
|
3435
3536
|
};
|
|
3436
3537
|
const getAccessToken = async (options = {}) => {
|
|
3437
|
-
const backendUrl =
|
|
3538
|
+
const backendUrl = getNormalizedBackendUrl();
|
|
3438
3539
|
const account = await getActive(backendUrl);
|
|
3439
3540
|
if (!account) {
|
|
3440
3541
|
return '';
|
|
@@ -3460,7 +3561,7 @@ const initialize = async (options = {}) => {
|
|
|
3460
3561
|
if (typeof options.platform === 'number') {
|
|
3461
3562
|
setAuthPlatform(options.platform);
|
|
3462
3563
|
}
|
|
3463
|
-
const backendUrl =
|
|
3564
|
+
const backendUrl = getNormalizedBackendUrl(options.backendUrl ?? getAuthBackendUrl());
|
|
3464
3565
|
const registry = await accounts.read();
|
|
3465
3566
|
const completed = await completeBrowserOidcLogin(backendUrl);
|
|
3466
3567
|
if (completed) {
|
|
@@ -3481,7 +3582,7 @@ const login = async options => {
|
|
|
3481
3582
|
return state.login;
|
|
3482
3583
|
}
|
|
3483
3584
|
const operation = (async () => {
|
|
3484
|
-
const backendUrl =
|
|
3585
|
+
const backendUrl = getNormalizedBackendUrl(options.backendUrl ?? getAuthBackendUrl());
|
|
3485
3586
|
const registry = await accounts.read();
|
|
3486
3587
|
const result = await handleClickLogin({
|
|
3487
3588
|
...options,
|
|
@@ -3498,7 +3599,7 @@ const login = async options => {
|
|
|
3498
3599
|
}
|
|
3499
3600
|
};
|
|
3500
3601
|
const useAccount = async id => {
|
|
3501
|
-
const backendUrl =
|
|
3602
|
+
const backendUrl = getNormalizedBackendUrl();
|
|
3502
3603
|
const registry = await accounts.read();
|
|
3503
3604
|
if (registry.accounts.every(account => !(account.id === id && account.backendUrl === backendUrl))) {
|
|
3504
3605
|
throw new Error('Account is no longer available.');
|
|
@@ -3507,7 +3608,7 @@ const useAccount = async id => {
|
|
|
3507
3608
|
return getCurrentState(backendUrl);
|
|
3508
3609
|
};
|
|
3509
3610
|
const removeAccount = async id => {
|
|
3510
|
-
const backendUrl =
|
|
3611
|
+
const backendUrl = getNormalizedBackendUrl();
|
|
3511
3612
|
const registry = await accounts.read();
|
|
3512
3613
|
if (registry.accounts.some(account => account.id === id && account.backendUrl === backendUrl)) {
|
|
3513
3614
|
await accounts.remove(id);
|
|
@@ -3515,7 +3616,7 @@ const removeAccount = async id => {
|
|
|
3515
3616
|
return getCurrentState(backendUrl);
|
|
3516
3617
|
};
|
|
3517
3618
|
const logout = async () => {
|
|
3518
|
-
const backendUrl =
|
|
3619
|
+
const backendUrl = getNormalizedBackendUrl();
|
|
3519
3620
|
const account = await getActive(backendUrl);
|
|
3520
3621
|
return account ? removeAccount(account.id) : getLoggedOutBackendAuthState();
|
|
3521
3622
|
};
|