@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.
Files changed (2) hide show
  1. package/dist/authWorkerMain.js +304 -187
  2. package/package.json +1 -1
@@ -1135,18 +1135,17 @@ const {
1135
1135
  const {
1136
1136
  invoke,
1137
1137
  invokeAndTransfer} = create(RendererWorker);
1138
- const sendMessagePortToOpenerWorker$1 = async (port, rpcId) => {
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
- const sendMessagePortToOpenerWorker = async port => {
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: sendMessagePortToOpenerWorker
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 state$4 = {
1246
- backendUrl: ''
1247
- };
1248
- const getAuthBackendUrl = () => {
1249
- return state$4.backendUrl;
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 = new Promise((resolve, reject) => {
2226
- const request = indexedDB.open(databaseName, 1);
2227
- request.addEventListener('upgradeneeded', () => {
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 transaction = database.transaction(objectStoreName, 'readonly');
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
- const transaction = database.transaction(objectStoreName, 'readwrite');
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
- const transaction = database.transaction(objectStoreName, 'readwrite');
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
- const secret = await getSecret(key);
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 ensureMigrated();
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 ensureMigrated();
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 ensureMigrated();
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 ensureMigrated();
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 ensureMigrated(options.backendUrl);
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 ensureMigrated(options.backendUrl);
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 ensureMigrated();
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 ensureMigrated();
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 ensureMigrated();
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 = () => new URL('/cloudflare', getAuthBackendUrl()).href;
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/auth-worker",
3
- "version": "3.22.0",
3
+ "version": "3.22.2",
4
4
  "description": "Auth Worker",
5
5
  "repository": {
6
6
  "type": "git",