@lvce-editor/auth-worker 3.22.1 → 3.22.3

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.
@@ -1102,6 +1102,7 @@ const create = rpcId => {
1102
1102
  };
1103
1103
 
1104
1104
  const {
1105
+ dispose,
1105
1106
  invoke: invoke$3,
1106
1107
  set: set$2
1107
1108
  } = create(6040);
@@ -1241,32 +1242,29 @@ const createAccountSessions = storage => {
1241
1242
  };
1242
1243
  };
1243
1244
 
1244
- const state$4 = {
1245
- backendUrl: ''
1246
- };
1247
- const getAuthBackendUrl = () => {
1248
- return state$4.backendUrl;
1249
- };
1250
- const setAuthBackendUrl = backendUrl => {
1251
- state$4.backendUrl = backendUrl;
1245
+ const getAuthBackendUrl = async backendUrl => {
1246
+ if (typeof backendUrl === 'string') {
1247
+ return backendUrl;
1248
+ }
1249
+ return invoke('Layout.getBackendUrl');
1252
1250
  };
1253
1251
 
1254
- const state$3 = {
1252
+ const state$4 = {
1255
1253
  platform: Web,
1256
1254
  useNativeAuth: false
1257
1255
  };
1258
1256
  const getAuthPlatform = () => {
1259
- return state$3.platform;
1257
+ return state$4.platform;
1260
1258
  };
1261
1259
  const setAuthPlatform = value => {
1262
- state$3.platform = value;
1260
+ state$4.platform = value;
1263
1261
  };
1264
1262
 
1265
1263
  // Native shells can use loopback OAuth without Electron's process or secret storage.
1266
1264
  const setUseNativeAuth = value => {
1267
- state$3.useNativeAuth = value;
1265
+ state$4.useNativeAuth = value;
1268
1266
  };
1269
- const getUseNativeAuth = () => state$3.useNativeAuth;
1267
+ const getUseNativeAuth = () => state$4.useNativeAuth;
1270
1268
 
1271
1269
  let USER_AGENT;
1272
1270
  if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
@@ -2438,15 +2436,15 @@ const databaseName = 'auth-worker';
2438
2436
  const objectStoreName = 'auth';
2439
2437
  const memoryStorage = new Map();
2440
2438
  const secretKeys = new Set(['accessToken', 'refreshToken', 'accountSessions']);
2441
- const state$2 = {
2439
+ const state$3 = {
2442
2440
  databasePromise: undefined
2443
2441
  };
2444
2442
  const getDatabase = async () => {
2445
2443
  if (typeof indexedDB === 'undefined') {
2446
2444
  return undefined;
2447
2445
  }
2448
- if (!state$2.databasePromise) {
2449
- state$2.databasePromise = openDB(databaseName, 1, {
2446
+ if (!state$3.databasePromise) {
2447
+ state$3.databasePromise = openDB(databaseName, 1, {
2450
2448
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
2451
2449
  upgrade(database) {
2452
2450
  if (!database.objectStoreNames.contains(objectStoreName)) {
@@ -2455,7 +2453,7 @@ const getDatabase = async () => {
2455
2453
  }
2456
2454
  });
2457
2455
  }
2458
- return state$2.databasePromise;
2456
+ return state$3.databasePromise;
2459
2457
  };
2460
2458
  const getIndexedDbValue = async key => {
2461
2459
  const database = await getDatabase();
@@ -2651,32 +2649,32 @@ const delay = async ms => {
2651
2649
  await new Promise(resolve => setTimeout(resolve, ms));
2652
2650
  };
2653
2651
 
2654
- const state$1 = {
2652
+ const state$2 = {
2655
2653
  nextLoginResponse: undefined,
2656
2654
  nextRefreshResponse: undefined
2657
2655
  };
2658
2656
  const setNextLoginResponse = response => {
2659
- state$1.nextLoginResponse = response;
2657
+ state$2.nextLoginResponse = response;
2660
2658
  };
2661
2659
  const setNextRefreshResponse = response => {
2662
- state$1.nextRefreshResponse = response;
2660
+ state$2.nextRefreshResponse = response;
2663
2661
  };
2664
2662
  const clear = () => {
2665
- state$1.nextLoginResponse = undefined;
2666
- state$1.nextRefreshResponse = undefined;
2663
+ state$2.nextLoginResponse = undefined;
2664
+ state$2.nextRefreshResponse = undefined;
2667
2665
  };
2668
2666
  const hasPendingMockLoginResponse = () => {
2669
- return !!state$1.nextLoginResponse;
2667
+ return !!state$2.nextLoginResponse;
2670
2668
  };
2671
2669
  const hasPendingMockRefreshResponse = () => {
2672
- return !!state$1.nextRefreshResponse;
2670
+ return !!state$2.nextRefreshResponse;
2673
2671
  };
2674
2672
  const consumeNextLoginResponse = async () => {
2675
- if (!state$1.nextLoginResponse) {
2673
+ if (!state$2.nextLoginResponse) {
2676
2674
  return undefined;
2677
2675
  }
2678
- const response = state$1.nextLoginResponse;
2679
- state$1.nextLoginResponse = undefined;
2676
+ const response = state$2.nextLoginResponse;
2677
+ state$2.nextLoginResponse = undefined;
2680
2678
  if (response.delay > 0) {
2681
2679
  await delay(response.delay);
2682
2680
  }
@@ -2686,11 +2684,11 @@ const consumeNextLoginResponse = async () => {
2686
2684
  return response.response;
2687
2685
  };
2688
2686
  const consumeNextRefreshResponse = async () => {
2689
- if (!state$1.nextRefreshResponse) {
2687
+ if (!state$2.nextRefreshResponse) {
2690
2688
  return undefined;
2691
2689
  }
2692
- const response = state$1.nextRefreshResponse;
2693
- state$1.nextRefreshResponse = undefined;
2690
+ const response = state$2.nextRefreshResponse;
2691
+ state$2.nextRefreshResponse = undefined;
2694
2692
  if (response.delay > 0) {
2695
2693
  await new Promise(resolve => setTimeout(resolve, response.delay));
2696
2694
  }
@@ -3305,6 +3303,9 @@ const waitForElectronBackendLogin = async (backendUrl, uid, redirectUri, codeVer
3305
3303
  return getLoggedOutBackendAuthState('Timed out waiting for backend login.');
3306
3304
  };
3307
3305
 
3306
+ const state$1 = {
3307
+ nativeLoginCount: 0
3308
+ };
3308
3309
  const getMockLoginResult = async (signingInState, persistResult) => {
3309
3310
  if (!hasPendingMockLoginResponse()) {
3310
3311
  return undefined;
@@ -3325,10 +3326,13 @@ const getMockLoginResult = async (signingInState, persistResult) => {
3325
3326
  return persistResult(getLoggedInState(signingInState, response));
3326
3327
  };
3327
3328
  const getInteractiveLoginResult = async (backendUrl, platform, signingInState, persistResult, selectAccount) => {
3328
- const nativeAuth = getUseNativeAuth();
3329
+ const nativeAuth = getUseNativeAuth() || platform === Electron;
3329
3330
  const transportPlatform = nativeAuth ? Electron : platform;
3330
3331
  const authUseRedirect = getAuthUseRedirect(transportPlatform);
3331
3332
  const uid = nativeAuth ? globalThis.crypto.randomUUID() : 0;
3333
+ if (nativeAuth) {
3334
+ state$1.nativeLoginCount++;
3335
+ }
3332
3336
  try {
3333
3337
  const {
3334
3338
  clientId,
@@ -3361,7 +3365,14 @@ const getInteractiveLoginResult = async (backendUrl, platform, signingInState, p
3361
3365
  });
3362
3366
  } finally {
3363
3367
  if (nativeAuth) {
3364
- await invoke$3('OAuthServer.dispose', String(uid));
3368
+ try {
3369
+ await invoke$3('OAuthServer.dispose', String(uid));
3370
+ } finally {
3371
+ state$1.nativeLoginCount--;
3372
+ if (state$1.nativeLoginCount === 0) {
3373
+ await dispose();
3374
+ }
3375
+ }
3365
3376
  }
3366
3377
  }
3367
3378
  };
@@ -3407,7 +3418,10 @@ const state = {
3407
3418
  login: undefined
3408
3419
  };
3409
3420
  const normalizeBackendUrl = backendUrl => new URL(backendUrl).origin;
3410
- const getNormalizedBackendUrl = (backendUrl = getAuthBackendUrl()) => normalizeBackendUrl(backendUrl);
3421
+ const getNormalizedBackendUrl = async backendUrl => {
3422
+ const url = await getAuthBackendUrl(backendUrl);
3423
+ return url ? normalizeBackendUrl(url) : '';
3424
+ };
3411
3425
  const addSession = async (backendUrl, session, revision) => {
3412
3426
  if (session.userState !== 'loggedIn' || !session.authAccessToken) {
3413
3427
  return;
@@ -3488,13 +3502,17 @@ const getConnectionRequestHeaders = accessToken => {
3488
3502
  };
3489
3503
  };
3490
3504
  const getConnectedAccounts = async () => {
3491
- const backendUrl = getNormalizedBackendUrl();
3505
+ const backendUrl = await getNormalizedBackendUrl();
3492
3506
  const accessToken = await getAccessToken({
3507
+ backendUrl,
3493
3508
  refresh: 'if-needed'
3494
3509
  });
3495
3510
  if (!accessToken) {
3496
3511
  return [];
3497
3512
  }
3513
+ if (backendUrl !== (await getNormalizedBackendUrl())) {
3514
+ throw new Error('Account backend changed. Retry connected accounts.');
3515
+ }
3498
3516
  const response = await fetch(getConnectedAccountsUrl(backendUrl), {
3499
3517
  headers: getConnectionRequestHeaders(accessToken)
3500
3518
  });
@@ -3508,13 +3526,17 @@ const getConnectedAccounts = async () => {
3508
3526
  return payload.connections;
3509
3527
  };
3510
3528
  const disconnectConnectedAccount = async provider => {
3511
- const backendUrl = getNormalizedBackendUrl();
3529
+ const backendUrl = await getNormalizedBackendUrl();
3512
3530
  const accessToken = await getAccessToken({
3531
+ backendUrl,
3513
3532
  refresh: 'if-needed'
3514
3533
  });
3515
3534
  if (!accessToken) {
3516
3535
  throw new Error('Sign in to disconnect connected accounts.');
3517
3536
  }
3537
+ if (backendUrl !== (await getNormalizedBackendUrl())) {
3538
+ throw new Error('Account backend changed. Retry connected accounts.');
3539
+ }
3518
3540
  const response = await fetch(getConnectedAccountDisconnectUrl(backendUrl, provider), {
3519
3541
  headers: getConnectionRequestHeaders(accessToken),
3520
3542
  method: 'POST'
@@ -3524,7 +3546,7 @@ const disconnectConnectedAccount = async provider => {
3524
3546
  }
3525
3547
  };
3526
3548
  const getAccounts = async () => {
3527
- const backendUrl = getNormalizedBackendUrl();
3549
+ const backendUrl = await getNormalizedBackendUrl();
3528
3550
  const registry = await accounts.read();
3529
3551
  return registry.accounts.filter(account => account.backendUrl === backendUrl).map(account => ({
3530
3552
  ...account.profile,
@@ -3535,7 +3557,10 @@ const getAccounts = async () => {
3535
3557
  }));
3536
3558
  };
3537
3559
  const getAccessToken = async (options = {}) => {
3538
- const backendUrl = getNormalizedBackendUrl();
3560
+ const backendUrl = await getNormalizedBackendUrl(options.backendUrl);
3561
+ if (!backendUrl) {
3562
+ return '';
3563
+ }
3539
3564
  const account = await getActive(backendUrl);
3540
3565
  if (!account) {
3541
3566
  return '';
@@ -3561,7 +3586,7 @@ const initialize = async (options = {}) => {
3561
3586
  if (typeof options.platform === 'number') {
3562
3587
  setAuthPlatform(options.platform);
3563
3588
  }
3564
- const backendUrl = getNormalizedBackendUrl(options.backendUrl ?? getAuthBackendUrl());
3589
+ const backendUrl = await getNormalizedBackendUrl(options.backendUrl);
3565
3590
  const registry = await accounts.read();
3566
3591
  const completed = await completeBrowserOidcLogin(backendUrl);
3567
3592
  if (completed) {
@@ -3570,6 +3595,7 @@ const initialize = async (options = {}) => {
3570
3595
  }
3571
3596
  try {
3572
3597
  await getAccessToken({
3598
+ backendUrl,
3573
3599
  refresh: 'if-needed'
3574
3600
  });
3575
3601
  return getCurrentState(backendUrl);
@@ -3582,7 +3608,7 @@ const login = async options => {
3582
3608
  return state.login;
3583
3609
  }
3584
3610
  const operation = (async () => {
3585
- const backendUrl = getNormalizedBackendUrl(options.backendUrl ?? getAuthBackendUrl());
3611
+ const backendUrl = await getNormalizedBackendUrl(options.backendUrl);
3586
3612
  const registry = await accounts.read();
3587
3613
  const result = await handleClickLogin({
3588
3614
  ...options,
@@ -3599,7 +3625,7 @@ const login = async options => {
3599
3625
  }
3600
3626
  };
3601
3627
  const useAccount = async id => {
3602
- const backendUrl = getNormalizedBackendUrl();
3628
+ const backendUrl = await getNormalizedBackendUrl();
3603
3629
  const registry = await accounts.read();
3604
3630
  if (registry.accounts.every(account => !(account.id === id && account.backendUrl === backendUrl))) {
3605
3631
  throw new Error('Account is no longer available.');
@@ -3608,7 +3634,7 @@ const useAccount = async id => {
3608
3634
  return getCurrentState(backendUrl);
3609
3635
  };
3610
3636
  const removeAccount = async id => {
3611
- const backendUrl = getNormalizedBackendUrl();
3637
+ const backendUrl = await getNormalizedBackendUrl();
3612
3638
  const registry = await accounts.read();
3613
3639
  if (registry.accounts.some(account => account.id === id && account.backendUrl === backendUrl)) {
3614
3640
  await accounts.remove(id);
@@ -3616,7 +3642,7 @@ const removeAccount = async id => {
3616
3642
  return getCurrentState(backendUrl);
3617
3643
  };
3618
3644
  const logout = async () => {
3619
- const backendUrl = getNormalizedBackendUrl();
3645
+ const backendUrl = await getNormalizedBackendUrl();
3620
3646
  const account = await getActive(backendUrl);
3621
3647
  return account ? removeAccount(account.id) : getLoggedOutBackendAuthState();
3622
3648
  };
@@ -3626,13 +3652,18 @@ const syncBackendAuth = async backendUrl => initialize({
3626
3652
 
3627
3653
  const identifier = /^[a-f0-9]{32}$/;
3628
3654
  const confirmationCode = /^[A-F0-9]{8}$/;
3629
- const getCloudflareConnectionsUrl = () => new URL('/cloudflare', getAuthBackendUrl()).href;
3655
+ const getCloudflareConnectionsUrl = async () => {
3656
+ const backendUrl = await getAuthBackendUrl();
3657
+ return backendUrl ? new URL('/cloudflare', backendUrl).href : '';
3658
+ };
3630
3659
  const request = async (pathname, method = 'GET', body) => {
3631
- const backendUrl = getAuthBackendUrl();
3660
+ const backendUrl = await getAuthBackendUrl();
3661
+ if (!backendUrl) throw new Error('Sign in to LVCE to manage Cloudflare connections.');
3632
3662
  const accessToken = await getAccessToken({
3663
+ backendUrl,
3633
3664
  refresh: 'if-needed'
3634
3665
  });
3635
- if (backendUrl !== getAuthBackendUrl()) throw new Error('Account backend changed. Retry Cloudflare setup.');
3666
+ if (backendUrl !== (await getAuthBackendUrl())) throw new Error('Account backend changed. Retry Cloudflare setup.');
3636
3667
  if (!accessToken) throw new Error('Sign in to LVCE to manage Cloudflare connections.');
3637
3668
  const response = await fetch(new URL(pathname, backendUrl), {
3638
3669
  headers: {
@@ -3660,15 +3691,76 @@ const approveCloudflareMachine = (id, code, zoneId) => {
3660
3691
  });
3661
3692
  };
3662
3693
 
3663
- const sendMessagePortToAuthProcess = async port => {
3664
- await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToSharedProcess', port, 'HandleMessagePortForAuthProcess.handleMessagePortForAuthProcess');
3694
+ const connect = async () => {
3695
+ const {
3696
+ port1,
3697
+ port2
3698
+ } = new MessageChannel();
3699
+ const closed = Promise.withResolvers();
3700
+ const handleClose = () => closed.resolve(new Error('Auth process connection closed'));
3701
+ port2.addEventListener('close', handleClose, {
3702
+ once: true
3703
+ });
3704
+ const failOnClose = async () => {
3705
+ throw await closed.promise;
3706
+ };
3707
+ const raceClose = promise => Promise.race([promise, failOnClose()]);
3708
+ try {
3709
+ await raceClose(invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToSharedProcess', port1, 'HandleMessagePortForAuthProcess.handleMessagePortForAuthProcess'));
3710
+ const rpc = await create$4({
3711
+ commandMap: {},
3712
+ messagePort: port2
3713
+ });
3714
+ return {
3715
+ async dispose() {
3716
+ handleClose();
3717
+ port2.removeEventListener('close', handleClose);
3718
+ await rpc.dispose();
3719
+ },
3720
+ invoke: (method, ...params) => raceClose(rpc.invoke(method, ...params)),
3721
+ invokeAndTransfer: (method, ...params) => raceClose(rpc.invokeAndTransfer(method, ...params)),
3722
+ send: rpc.send
3723
+ };
3724
+ } catch (error) {
3725
+ port2.removeEventListener('close', handleClose);
3726
+ port1.close();
3727
+ port2.close();
3728
+ throw error;
3729
+ }
3730
+ };
3731
+ const createAuthProcessRpc = (create = connect) => {
3732
+ let pending;
3733
+ const get = () => {
3734
+ if (!pending) {
3735
+ pending = create();
3736
+ }
3737
+ return pending;
3738
+ };
3739
+ return {
3740
+ async dispose() {
3741
+ const previous = pending;
3742
+ // Detach before awaiting: a new login may connect while the old port closes.
3743
+ pending = undefined;
3744
+ if (previous) {
3745
+ const rpc = await previous;
3746
+ await rpc.dispose();
3747
+ }
3748
+ },
3749
+ async invoke(method, ...params) {
3750
+ const rpc = await get();
3751
+ return rpc.invoke(method, ...params);
3752
+ },
3753
+ async invokeAndTransfer(method, ...params) {
3754
+ const rpc = await get();
3755
+ return rpc.invokeAndTransfer(method, ...params);
3756
+ },
3757
+ send(method, ...params) {
3758
+ void get().then(rpc => rpc.send(method, ...params));
3759
+ }
3760
+ };
3665
3761
  };
3666
3762
  const initializeAuthProcess = async () => {
3667
- const rpc = await create$2({
3668
- commandMap: {},
3669
- send: sendMessagePortToAuthProcess
3670
- });
3671
- set$2(rpc);
3763
+ set$2(createAuthProcessRpc());
3672
3764
  };
3673
3765
 
3674
3766
  const sendMessagePortToMainProcess = async port => {
@@ -3683,7 +3775,6 @@ const initializeMainProcess = async () => {
3683
3775
  };
3684
3776
 
3685
3777
  const configure = async options => {
3686
- setAuthBackendUrl(options.backendUrl);
3687
3778
  setAuthPlatform(options.platform);
3688
3779
  setUseNativeAuth(options.useNativeAuth === true);
3689
3780
  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.1",
3
+ "version": "3.22.3",
4
4
  "description": "Auth Worker",
5
5
  "repository": {
6
6
  "type": "git",