@lvce-editor/auth-worker 3.22.0 → 3.22.2
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 +304 -187
- 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
|
};
|
|
@@ -1242,14 +1241,11 @@ const createAccountSessions = storage => {
|
|
|
1242
1241
|
};
|
|
1243
1242
|
};
|
|
1244
1243
|
|
|
1245
|
-
const
|
|
1246
|
-
backendUrl
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
return
|
|
1250
|
-
};
|
|
1251
|
-
const setAuthBackendUrl = backendUrl => {
|
|
1252
|
-
state$4.backendUrl = backendUrl;
|
|
1244
|
+
const getAuthBackendUrl = async backendUrl => {
|
|
1245
|
+
if (typeof backendUrl === 'string') {
|
|
1246
|
+
return backendUrl;
|
|
1247
|
+
}
|
|
1248
|
+
return invoke('Layout.getBackendUrl');
|
|
1253
1249
|
};
|
|
1254
1250
|
|
|
1255
1251
|
const state$3 = {
|
|
@@ -2171,6 +2167,259 @@ const getOidcUserName = async (backendUrl, accessToken, fetchFn = fetch) => {
|
|
|
2171
2167
|
return typeof displayName === 'string' ? displayName : '';
|
|
2172
2168
|
};
|
|
2173
2169
|
|
|
2170
|
+
const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
|
|
2171
|
+
let idbProxyableTypes;
|
|
2172
|
+
let cursorAdvanceMethods;
|
|
2173
|
+
// This is a function to prevent it throwing up in node environments.
|
|
2174
|
+
function getIdbProxyableTypes() {
|
|
2175
|
+
return idbProxyableTypes || (idbProxyableTypes = [IDBIndex, IDBObjectStore, IDBCursor, IDBDatabase, IDBTransaction]);
|
|
2176
|
+
}
|
|
2177
|
+
// This is a function to prevent it throwing up in node environments.
|
|
2178
|
+
function getCursorAdvanceMethods() {
|
|
2179
|
+
return cursorAdvanceMethods || (cursorAdvanceMethods = ['advance', 'continue', 'continuePrimaryKey'].map(method => IDBCursor.prototype[method]));
|
|
2180
|
+
}
|
|
2181
|
+
const transactionDoneMap = new WeakMap();
|
|
2182
|
+
const transformCache = new WeakMap();
|
|
2183
|
+
const reverseTransformCache = new WeakMap();
|
|
2184
|
+
function promisifyRequest(request) {
|
|
2185
|
+
const promise = new Promise((resolve, reject) => {
|
|
2186
|
+
const unlisten = () => {
|
|
2187
|
+
request.removeEventListener('success', success);
|
|
2188
|
+
request.removeEventListener('error', error);
|
|
2189
|
+
};
|
|
2190
|
+
const success = () => {
|
|
2191
|
+
resolve(wrap(request.result));
|
|
2192
|
+
unlisten();
|
|
2193
|
+
};
|
|
2194
|
+
const error = () => {
|
|
2195
|
+
reject(request.error);
|
|
2196
|
+
unlisten();
|
|
2197
|
+
};
|
|
2198
|
+
request.addEventListener('success', success);
|
|
2199
|
+
request.addEventListener('error', error);
|
|
2200
|
+
});
|
|
2201
|
+
// This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
|
|
2202
|
+
// is because we create many promises from a single IDBRequest.
|
|
2203
|
+
reverseTransformCache.set(promise, request);
|
|
2204
|
+
return promise;
|
|
2205
|
+
}
|
|
2206
|
+
function cacheDonePromiseForTransaction(tx) {
|
|
2207
|
+
// Early bail if we've already created a done promise for this transaction.
|
|
2208
|
+
if (transactionDoneMap.has(tx)) return;
|
|
2209
|
+
const done = new Promise((resolve, reject) => {
|
|
2210
|
+
const unlisten = () => {
|
|
2211
|
+
tx.removeEventListener('complete', complete);
|
|
2212
|
+
tx.removeEventListener('error', error);
|
|
2213
|
+
tx.removeEventListener('abort', error);
|
|
2214
|
+
};
|
|
2215
|
+
const complete = () => {
|
|
2216
|
+
resolve();
|
|
2217
|
+
unlisten();
|
|
2218
|
+
};
|
|
2219
|
+
const error = () => {
|
|
2220
|
+
reject(tx.error || new DOMException('AbortError', 'AbortError'));
|
|
2221
|
+
unlisten();
|
|
2222
|
+
};
|
|
2223
|
+
tx.addEventListener('complete', complete);
|
|
2224
|
+
tx.addEventListener('error', error);
|
|
2225
|
+
tx.addEventListener('abort', error);
|
|
2226
|
+
});
|
|
2227
|
+
// Cache it for later retrieval.
|
|
2228
|
+
transactionDoneMap.set(tx, done);
|
|
2229
|
+
}
|
|
2230
|
+
let idbProxyTraps = {
|
|
2231
|
+
get(target, prop, receiver) {
|
|
2232
|
+
if (target instanceof IDBTransaction) {
|
|
2233
|
+
// Special handling for transaction.done.
|
|
2234
|
+
if (prop === 'done') return transactionDoneMap.get(target);
|
|
2235
|
+
// Make tx.store return the only store in the transaction, or undefined if there are many.
|
|
2236
|
+
if (prop === 'store') {
|
|
2237
|
+
return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
// Else transform whatever we get back.
|
|
2241
|
+
return wrap(target[prop]);
|
|
2242
|
+
},
|
|
2243
|
+
set(target, prop, value) {
|
|
2244
|
+
target[prop] = value;
|
|
2245
|
+
return true;
|
|
2246
|
+
},
|
|
2247
|
+
has(target, prop) {
|
|
2248
|
+
if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
|
|
2249
|
+
return true;
|
|
2250
|
+
}
|
|
2251
|
+
return prop in target;
|
|
2252
|
+
}
|
|
2253
|
+
};
|
|
2254
|
+
function replaceTraps(callback) {
|
|
2255
|
+
idbProxyTraps = callback(idbProxyTraps);
|
|
2256
|
+
}
|
|
2257
|
+
function wrapFunction(func) {
|
|
2258
|
+
// Due to expected object equality (which is enforced by the caching in `wrap`), we
|
|
2259
|
+
// only create one new func per func.
|
|
2260
|
+
// Cursor methods are special, as the behaviour is a little more different to standard IDB. In
|
|
2261
|
+
// IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
|
|
2262
|
+
// cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
|
|
2263
|
+
// with real promises, so each advance methods returns a new promise for the cursor object, or
|
|
2264
|
+
// undefined if the end of the cursor has been reached.
|
|
2265
|
+
if (getCursorAdvanceMethods().includes(func)) {
|
|
2266
|
+
return function (...args) {
|
|
2267
|
+
// Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
|
|
2268
|
+
// the original object.
|
|
2269
|
+
func.apply(unwrap(this), args);
|
|
2270
|
+
return wrap(this.request);
|
|
2271
|
+
};
|
|
2272
|
+
}
|
|
2273
|
+
return function (...args) {
|
|
2274
|
+
// Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
|
|
2275
|
+
// the original object.
|
|
2276
|
+
return wrap(func.apply(unwrap(this), args));
|
|
2277
|
+
};
|
|
2278
|
+
}
|
|
2279
|
+
function transformCachableValue(value) {
|
|
2280
|
+
if (typeof value === 'function') return wrapFunction(value);
|
|
2281
|
+
// This doesn't return, it just creates a 'done' promise for the transaction,
|
|
2282
|
+
// which is later returned for transaction.done (see idbObjectHandler).
|
|
2283
|
+
if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
|
|
2284
|
+
if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
|
|
2285
|
+
// Return the same value back if we're not going to transform it.
|
|
2286
|
+
return value;
|
|
2287
|
+
}
|
|
2288
|
+
function wrap(value) {
|
|
2289
|
+
// We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
|
|
2290
|
+
// IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
|
|
2291
|
+
if (value instanceof IDBRequest) return promisifyRequest(value);
|
|
2292
|
+
// If we've already transformed this value before, reuse the transformed value.
|
|
2293
|
+
// This is faster, but it also provides object equality.
|
|
2294
|
+
if (transformCache.has(value)) return transformCache.get(value);
|
|
2295
|
+
const newValue = transformCachableValue(value);
|
|
2296
|
+
// Not all types are transformed.
|
|
2297
|
+
// These may be primitive types, so they can't be WeakMap keys.
|
|
2298
|
+
if (!Object.is(newValue, value)) {
|
|
2299
|
+
transformCache.set(value, newValue);
|
|
2300
|
+
reverseTransformCache.set(newValue, value);
|
|
2301
|
+
}
|
|
2302
|
+
return newValue;
|
|
2303
|
+
}
|
|
2304
|
+
const unwrap = value => reverseTransformCache.get(value);
|
|
2305
|
+
|
|
2306
|
+
/**
|
|
2307
|
+
* Open a database.
|
|
2308
|
+
*
|
|
2309
|
+
* @param name Name of the database.
|
|
2310
|
+
* @param version Schema version.
|
|
2311
|
+
* @param callbacks Additional callbacks.
|
|
2312
|
+
*/
|
|
2313
|
+
function openDB(name, version, {
|
|
2314
|
+
blocked,
|
|
2315
|
+
upgrade,
|
|
2316
|
+
blocking,
|
|
2317
|
+
terminated
|
|
2318
|
+
} = {}) {
|
|
2319
|
+
const request = indexedDB.open(name, version);
|
|
2320
|
+
const openPromise = wrap(request);
|
|
2321
|
+
if (upgrade) {
|
|
2322
|
+
request.addEventListener('upgradeneeded', event => {
|
|
2323
|
+
upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
if (blocked) {
|
|
2327
|
+
request.addEventListener('blocked', event => blocked(
|
|
2328
|
+
// Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
|
|
2329
|
+
event.oldVersion, event.newVersion, event));
|
|
2330
|
+
}
|
|
2331
|
+
openPromise.then(db => {
|
|
2332
|
+
if (terminated) db.addEventListener('close', () => terminated());
|
|
2333
|
+
if (blocking) {
|
|
2334
|
+
db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
|
|
2335
|
+
}
|
|
2336
|
+
}).catch(() => {});
|
|
2337
|
+
return openPromise;
|
|
2338
|
+
}
|
|
2339
|
+
const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
|
|
2340
|
+
const writeMethods = ['put', 'add', 'delete', 'clear'];
|
|
2341
|
+
const cachedMethods = {};
|
|
2342
|
+
function getMethod(target, prop) {
|
|
2343
|
+
if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
|
|
2344
|
+
return;
|
|
2345
|
+
}
|
|
2346
|
+
if (cachedMethods[prop]) return cachedMethods[prop];
|
|
2347
|
+
const targetFuncName = prop.replace(/FromIndex$/, '');
|
|
2348
|
+
const useIndex = prop !== targetFuncName;
|
|
2349
|
+
const isWrite = writeMethods.includes(targetFuncName);
|
|
2350
|
+
if (
|
|
2351
|
+
// Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
|
|
2352
|
+
!(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
|
|
2353
|
+
return;
|
|
2354
|
+
}
|
|
2355
|
+
const method = async function (storeName, ...args) {
|
|
2356
|
+
// isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
|
|
2357
|
+
const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
|
|
2358
|
+
let target = tx.store;
|
|
2359
|
+
if (useIndex) target = target.index(args.shift());
|
|
2360
|
+
// Must reject if op rejects.
|
|
2361
|
+
// If it's a write operation, must reject if tx.done rejects.
|
|
2362
|
+
// Must reject with op rejection first.
|
|
2363
|
+
// Must resolve with op value.
|
|
2364
|
+
// Must handle both promises (no unhandled rejections)
|
|
2365
|
+
return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
|
|
2366
|
+
};
|
|
2367
|
+
return cachedMethods[prop] = method;
|
|
2368
|
+
}
|
|
2369
|
+
replaceTraps(oldTraps => ({
|
|
2370
|
+
...oldTraps,
|
|
2371
|
+
get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
|
|
2372
|
+
has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
|
|
2373
|
+
}));
|
|
2374
|
+
const advanceMethodProps = ['advance', 'continue', 'continuePrimaryKey'];
|
|
2375
|
+
const methodMap = {};
|
|
2376
|
+
const advanceResults = new WeakMap();
|
|
2377
|
+
const ittrProxiedCursorToOriginalProxy = new WeakMap();
|
|
2378
|
+
const cursorIteratorTraps = {
|
|
2379
|
+
get(target, prop) {
|
|
2380
|
+
if (!advanceMethodProps.includes(prop)) return target[prop];
|
|
2381
|
+
let cachedFunc = methodMap[prop];
|
|
2382
|
+
if (!cachedFunc) {
|
|
2383
|
+
cachedFunc = methodMap[prop] = function (...args) {
|
|
2384
|
+
advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
|
|
2385
|
+
};
|
|
2386
|
+
}
|
|
2387
|
+
return cachedFunc;
|
|
2388
|
+
}
|
|
2389
|
+
};
|
|
2390
|
+
async function* iterate(...args) {
|
|
2391
|
+
// tslint:disable-next-line:no-this-assignment
|
|
2392
|
+
let cursor = this;
|
|
2393
|
+
if (!(cursor instanceof IDBCursor)) {
|
|
2394
|
+
cursor = await cursor.openCursor(...args);
|
|
2395
|
+
}
|
|
2396
|
+
if (!cursor) return;
|
|
2397
|
+
cursor = cursor;
|
|
2398
|
+
const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
|
|
2399
|
+
ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
|
|
2400
|
+
// Map this double-proxy back to the original, so other cursor methods work.
|
|
2401
|
+
reverseTransformCache.set(proxiedCursor, unwrap(cursor));
|
|
2402
|
+
while (cursor) {
|
|
2403
|
+
yield proxiedCursor;
|
|
2404
|
+
// If one of the advancing methods was not called, call continue().
|
|
2405
|
+
cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
|
|
2406
|
+
advanceResults.delete(proxiedCursor);
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
function isIteratorProp(target, prop) {
|
|
2410
|
+
return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
|
|
2411
|
+
}
|
|
2412
|
+
replaceTraps(oldTraps => ({
|
|
2413
|
+
...oldTraps,
|
|
2414
|
+
get(target, prop, receiver) {
|
|
2415
|
+
if (isIteratorProp(target, prop)) return iterate;
|
|
2416
|
+
return oldTraps.get(target, prop, receiver);
|
|
2417
|
+
},
|
|
2418
|
+
has(target, prop) {
|
|
2419
|
+
return isIteratorProp(target, prop) || oldTraps.has(target, prop);
|
|
2420
|
+
}
|
|
2421
|
+
}));
|
|
2422
|
+
|
|
2174
2423
|
const authStorageId = 'lvce-editor.auth';
|
|
2175
2424
|
const deleteSecret = async key => {
|
|
2176
2425
|
await deleteSecret$1(authStorageId, key);
|
|
@@ -2189,53 +2438,18 @@ const secretKeys = new Set(['accessToken', 'refreshToken', 'accountSessions']);
|
|
|
2189
2438
|
const state$2 = {
|
|
2190
2439
|
databasePromise: undefined
|
|
2191
2440
|
};
|
|
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
2441
|
const getDatabase = async () => {
|
|
2221
2442
|
if (typeof indexedDB === 'undefined') {
|
|
2222
2443
|
return undefined;
|
|
2223
2444
|
}
|
|
2224
2445
|
if (!state$2.databasePromise) {
|
|
2225
|
-
state$2.databasePromise =
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
const database = request.result;
|
|
2446
|
+
state$2.databasePromise = openDB(databaseName, 1, {
|
|
2447
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
2448
|
+
upgrade(database) {
|
|
2229
2449
|
if (!database.objectStoreNames.contains(objectStoreName)) {
|
|
2230
2450
|
database.createObjectStore(objectStoreName);
|
|
2231
2451
|
}
|
|
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
|
-
});
|
|
2452
|
+
}
|
|
2239
2453
|
});
|
|
2240
2454
|
}
|
|
2241
2455
|
return state$2.databasePromise;
|
|
@@ -2245,9 +2459,7 @@ const getIndexedDbValue = async key => {
|
|
|
2245
2459
|
if (!database) {
|
|
2246
2460
|
return memoryStorage.get(key) ?? '';
|
|
2247
2461
|
}
|
|
2248
|
-
const
|
|
2249
|
-
const objectStore = transaction.objectStore(objectStoreName);
|
|
2250
|
-
const value = await requestToPromise(objectStore.get(key));
|
|
2462
|
+
const value = await database.get(objectStoreName, key);
|
|
2251
2463
|
return typeof value === 'string' ? value : '';
|
|
2252
2464
|
};
|
|
2253
2465
|
const setIndexedDbValue = async (key, value) => {
|
|
@@ -2256,10 +2468,7 @@ const setIndexedDbValue = async (key, value) => {
|
|
|
2256
2468
|
if (!database) {
|
|
2257
2469
|
return;
|
|
2258
2470
|
}
|
|
2259
|
-
|
|
2260
|
-
const objectStore = transaction.objectStore(objectStoreName);
|
|
2261
|
-
objectStore.put(value, key);
|
|
2262
|
-
await transactionToPromise(transaction);
|
|
2471
|
+
await database.put(objectStoreName, value, key);
|
|
2263
2472
|
};
|
|
2264
2473
|
const clearIndexedDbValue = async key => {
|
|
2265
2474
|
memoryStorage.delete(key);
|
|
@@ -2267,10 +2476,7 @@ const clearIndexedDbValue = async key => {
|
|
|
2267
2476
|
if (!database) {
|
|
2268
2477
|
return;
|
|
2269
2478
|
}
|
|
2270
|
-
|
|
2271
|
-
const objectStore = transaction.objectStore(objectStoreName);
|
|
2272
|
-
objectStore.delete(key);
|
|
2273
|
-
await transactionToPromise(transaction);
|
|
2479
|
+
await database.delete(objectStoreName, key);
|
|
2274
2480
|
};
|
|
2275
2481
|
const shouldUseSecretStorage = key => {
|
|
2276
2482
|
return getAuthPlatform() === Electron && secretKeys.has(key);
|
|
@@ -2279,17 +2485,7 @@ const getPersistentAuthValue = async key => {
|
|
|
2279
2485
|
if (!shouldUseSecretStorage(key)) {
|
|
2280
2486
|
return getIndexedDbValue(key);
|
|
2281
2487
|
}
|
|
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;
|
|
2488
|
+
return (await getSecret(key)) || '';
|
|
2293
2489
|
};
|
|
2294
2490
|
const setPersistentAuthValue = async (key, value) => {
|
|
2295
2491
|
if (!shouldUseSecretStorage(key)) {
|
|
@@ -2550,58 +2746,9 @@ const userNameKey = 'userName';
|
|
|
2550
2746
|
const userSubscriptionPlanKey = 'userSubscriptionPlan';
|
|
2551
2747
|
const userSubscriptionStatusKey = 'userSubscriptionStatus';
|
|
2552
2748
|
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
2749
|
const clearPersistedAuthSession = async () => {
|
|
2564
2750
|
await Promise.all([clearPersistentAuthValue(accessTokenKey), clearPersistentAuthValue(accessTokenExpiresAtKey), clearPersistentAuthValue(refreshTokenKey), clearStoredOidcClientId(), clearPersistentAuthValue(userNameKey), clearPersistentAuthValue(userSubscriptionPlanKey), clearPersistentAuthValue(userSubscriptionStatusKey), clearPersistentAuthValue(userUsedTokensKey)]);
|
|
2565
2751
|
};
|
|
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
2752
|
const persistAuthSession = async loginResult => {
|
|
2606
2753
|
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
2754
|
};
|
|
@@ -3254,10 +3401,13 @@ const accounts = createAccountSessions({
|
|
|
3254
3401
|
});
|
|
3255
3402
|
const refreshes = new Map();
|
|
3256
3403
|
const state = {
|
|
3257
|
-
login: undefined
|
|
3258
|
-
migration: undefined
|
|
3404
|
+
login: undefined
|
|
3259
3405
|
};
|
|
3260
3406
|
const normalizeBackendUrl = backendUrl => new URL(backendUrl).origin;
|
|
3407
|
+
const getNormalizedBackendUrl = async backendUrl => {
|
|
3408
|
+
const url = await getAuthBackendUrl(backendUrl);
|
|
3409
|
+
return url ? normalizeBackendUrl(url) : '';
|
|
3410
|
+
};
|
|
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,13 +3488,17 @@ const getConnectionRequestHeaders = accessToken => {
|
|
|
3387
3488
|
};
|
|
3388
3489
|
};
|
|
3389
3490
|
const getConnectedAccounts = async () => {
|
|
3390
|
-
const backendUrl = await
|
|
3491
|
+
const backendUrl = await getNormalizedBackendUrl();
|
|
3391
3492
|
const accessToken = await getAccessToken({
|
|
3493
|
+
backendUrl,
|
|
3392
3494
|
refresh: 'if-needed'
|
|
3393
3495
|
});
|
|
3394
3496
|
if (!accessToken) {
|
|
3395
3497
|
return [];
|
|
3396
3498
|
}
|
|
3499
|
+
if (backendUrl !== (await getNormalizedBackendUrl())) {
|
|
3500
|
+
throw new Error('Account backend changed. Retry connected accounts.');
|
|
3501
|
+
}
|
|
3397
3502
|
const response = await fetch(getConnectedAccountsUrl(backendUrl), {
|
|
3398
3503
|
headers: getConnectionRequestHeaders(accessToken)
|
|
3399
3504
|
});
|
|
@@ -3407,13 +3512,17 @@ const getConnectedAccounts = async () => {
|
|
|
3407
3512
|
return payload.connections;
|
|
3408
3513
|
};
|
|
3409
3514
|
const disconnectConnectedAccount = async provider => {
|
|
3410
|
-
const backendUrl = await
|
|
3515
|
+
const backendUrl = await getNormalizedBackendUrl();
|
|
3411
3516
|
const accessToken = await getAccessToken({
|
|
3517
|
+
backendUrl,
|
|
3412
3518
|
refresh: 'if-needed'
|
|
3413
3519
|
});
|
|
3414
3520
|
if (!accessToken) {
|
|
3415
3521
|
throw new Error('Sign in to disconnect connected accounts.');
|
|
3416
3522
|
}
|
|
3523
|
+
if (backendUrl !== (await getNormalizedBackendUrl())) {
|
|
3524
|
+
throw new Error('Account backend changed. Retry connected accounts.');
|
|
3525
|
+
}
|
|
3417
3526
|
const response = await fetch(getConnectedAccountDisconnectUrl(backendUrl, provider), {
|
|
3418
3527
|
headers: getConnectionRequestHeaders(accessToken),
|
|
3419
3528
|
method: 'POST'
|
|
@@ -3423,7 +3532,7 @@ const disconnectConnectedAccount = async provider => {
|
|
|
3423
3532
|
}
|
|
3424
3533
|
};
|
|
3425
3534
|
const getAccounts = async () => {
|
|
3426
|
-
const backendUrl = await
|
|
3535
|
+
const backendUrl = await getNormalizedBackendUrl();
|
|
3427
3536
|
const registry = await accounts.read();
|
|
3428
3537
|
return registry.accounts.filter(account => account.backendUrl === backendUrl).map(account => ({
|
|
3429
3538
|
...account.profile,
|
|
@@ -3434,7 +3543,10 @@ const getAccounts = async () => {
|
|
|
3434
3543
|
}));
|
|
3435
3544
|
};
|
|
3436
3545
|
const getAccessToken = async (options = {}) => {
|
|
3437
|
-
const backendUrl = await
|
|
3546
|
+
const backendUrl = await getNormalizedBackendUrl(options.backendUrl);
|
|
3547
|
+
if (!backendUrl) {
|
|
3548
|
+
return '';
|
|
3549
|
+
}
|
|
3438
3550
|
const account = await getActive(backendUrl);
|
|
3439
3551
|
if (!account) {
|
|
3440
3552
|
return '';
|
|
@@ -3460,7 +3572,7 @@ const initialize = async (options = {}) => {
|
|
|
3460
3572
|
if (typeof options.platform === 'number') {
|
|
3461
3573
|
setAuthPlatform(options.platform);
|
|
3462
3574
|
}
|
|
3463
|
-
const backendUrl = await
|
|
3575
|
+
const backendUrl = await getNormalizedBackendUrl(options.backendUrl);
|
|
3464
3576
|
const registry = await accounts.read();
|
|
3465
3577
|
const completed = await completeBrowserOidcLogin(backendUrl);
|
|
3466
3578
|
if (completed) {
|
|
@@ -3469,6 +3581,7 @@ const initialize = async (options = {}) => {
|
|
|
3469
3581
|
}
|
|
3470
3582
|
try {
|
|
3471
3583
|
await getAccessToken({
|
|
3584
|
+
backendUrl,
|
|
3472
3585
|
refresh: 'if-needed'
|
|
3473
3586
|
});
|
|
3474
3587
|
return getCurrentState(backendUrl);
|
|
@@ -3481,7 +3594,7 @@ const login = async options => {
|
|
|
3481
3594
|
return state.login;
|
|
3482
3595
|
}
|
|
3483
3596
|
const operation = (async () => {
|
|
3484
|
-
const backendUrl = await
|
|
3597
|
+
const backendUrl = await getNormalizedBackendUrl(options.backendUrl);
|
|
3485
3598
|
const registry = await accounts.read();
|
|
3486
3599
|
const result = await handleClickLogin({
|
|
3487
3600
|
...options,
|
|
@@ -3498,7 +3611,7 @@ const login = async options => {
|
|
|
3498
3611
|
}
|
|
3499
3612
|
};
|
|
3500
3613
|
const useAccount = async id => {
|
|
3501
|
-
const backendUrl = await
|
|
3614
|
+
const backendUrl = await getNormalizedBackendUrl();
|
|
3502
3615
|
const registry = await accounts.read();
|
|
3503
3616
|
if (registry.accounts.every(account => !(account.id === id && account.backendUrl === backendUrl))) {
|
|
3504
3617
|
throw new Error('Account is no longer available.');
|
|
@@ -3507,7 +3620,7 @@ const useAccount = async id => {
|
|
|
3507
3620
|
return getCurrentState(backendUrl);
|
|
3508
3621
|
};
|
|
3509
3622
|
const removeAccount = async id => {
|
|
3510
|
-
const backendUrl = await
|
|
3623
|
+
const backendUrl = await getNormalizedBackendUrl();
|
|
3511
3624
|
const registry = await accounts.read();
|
|
3512
3625
|
if (registry.accounts.some(account => account.id === id && account.backendUrl === backendUrl)) {
|
|
3513
3626
|
await accounts.remove(id);
|
|
@@ -3515,7 +3628,7 @@ const removeAccount = async id => {
|
|
|
3515
3628
|
return getCurrentState(backendUrl);
|
|
3516
3629
|
};
|
|
3517
3630
|
const logout = async () => {
|
|
3518
|
-
const backendUrl = await
|
|
3631
|
+
const backendUrl = await getNormalizedBackendUrl();
|
|
3519
3632
|
const account = await getActive(backendUrl);
|
|
3520
3633
|
return account ? removeAccount(account.id) : getLoggedOutBackendAuthState();
|
|
3521
3634
|
};
|
|
@@ -3525,13 +3638,18 @@ const syncBackendAuth = async backendUrl => initialize({
|
|
|
3525
3638
|
|
|
3526
3639
|
const identifier = /^[a-f0-9]{32}$/;
|
|
3527
3640
|
const confirmationCode = /^[A-F0-9]{8}$/;
|
|
3528
|
-
const getCloudflareConnectionsUrl = () =>
|
|
3641
|
+
const getCloudflareConnectionsUrl = async () => {
|
|
3642
|
+
const backendUrl = await getAuthBackendUrl();
|
|
3643
|
+
return backendUrl ? new URL('/cloudflare', backendUrl).href : '';
|
|
3644
|
+
};
|
|
3529
3645
|
const request = async (pathname, method = 'GET', body) => {
|
|
3530
|
-
const backendUrl = getAuthBackendUrl();
|
|
3646
|
+
const backendUrl = await getAuthBackendUrl();
|
|
3647
|
+
if (!backendUrl) throw new Error('Sign in to LVCE to manage Cloudflare connections.');
|
|
3531
3648
|
const accessToken = await getAccessToken({
|
|
3649
|
+
backendUrl,
|
|
3532
3650
|
refresh: 'if-needed'
|
|
3533
3651
|
});
|
|
3534
|
-
if (backendUrl !== getAuthBackendUrl()) throw new Error('Account backend changed. Retry Cloudflare setup.');
|
|
3652
|
+
if (backendUrl !== (await getAuthBackendUrl())) throw new Error('Account backend changed. Retry Cloudflare setup.');
|
|
3535
3653
|
if (!accessToken) throw new Error('Sign in to LVCE to manage Cloudflare connections.');
|
|
3536
3654
|
const response = await fetch(new URL(pathname, backendUrl), {
|
|
3537
3655
|
headers: {
|
|
@@ -3582,7 +3700,6 @@ const initializeMainProcess = async () => {
|
|
|
3582
3700
|
};
|
|
3583
3701
|
|
|
3584
3702
|
const configure = async options => {
|
|
3585
|
-
setAuthBackendUrl(options.backendUrl);
|
|
3586
3703
|
setAuthPlatform(options.platform);
|
|
3587
3704
|
setUseNativeAuth(options.useNativeAuth === true);
|
|
3588
3705
|
if (options.platform === Electron) {
|