@lvce-editor/auth-worker 1.4.0 → 1.5.0

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.
@@ -1127,18 +1127,18 @@ const create = rpcId => {
1127
1127
  };
1128
1128
  };
1129
1129
 
1130
+ const Electron = 2;
1131
+
1130
1132
  const OpenerWorker = 4561;
1131
1133
  const RendererWorker = 1;
1132
1134
 
1133
1135
  const {
1134
- invoke,
1136
+ invoke: invoke$1,
1135
1137
  set: set$1
1136
1138
  } = create(OpenerWorker);
1137
- const openUrl = async (url, platform) => {
1138
- return invoke('Open.openUrl', url, platform);
1139
- };
1140
1139
 
1141
1140
  const {
1141
+ invoke,
1142
1142
  invokeAndTransfer,
1143
1143
  set
1144
1144
  } = create(RendererWorker);
@@ -1178,10 +1178,6 @@ const getBackendAuthUrl = (backendUrl, path) => {
1178
1178
  return `${trimTrailingSlashes(backendUrl)}${path}`;
1179
1179
  };
1180
1180
 
1181
- const getBackendLoginUrl = backendUrl => {
1182
- return getBackendAuthUrl(backendUrl, '/auth/login');
1183
- };
1184
-
1185
1181
  const getLoggedOutBackendAuthState = (authErrorMessage = '') => {
1186
1182
  return {
1187
1183
  authAccessToken: '',
@@ -1359,6 +1355,38 @@ const waitForBackendLogin = async (backendUrl, timeoutMs = 30_000, pollIntervalM
1359
1355
  return getLoggedOutBackendAuthState(lastErrorMessage);
1360
1356
  };
1361
1357
 
1358
+ const getCurrentHref = async () => {
1359
+ try {
1360
+ return await invoke('Layout.getHref');
1361
+ } catch {
1362
+ // ignore
1363
+ }
1364
+ if (!globalThis.location || typeof globalThis.location.href !== 'string' || !globalThis.location.href) {
1365
+ return '';
1366
+ }
1367
+ return globalThis.location.href;
1368
+ };
1369
+ const getEffectiveRedirectUri = async (platform, uid, redirectUri) => {
1370
+ if (redirectUri) {
1371
+ return redirectUri;
1372
+ }
1373
+ if (platform === Electron) {
1374
+ return `http://localhost:${await invoke('OAuthServer.create', String(uid))}`;
1375
+ }
1376
+ return getCurrentHref();
1377
+ };
1378
+ const getBackendLoginRequest = async (backendUrl, platform = 0, uid = 0, redirectUri = '') => {
1379
+ const loginUrl = new URL(getBackendAuthUrl(backendUrl, '/login'));
1380
+ const effectiveRedirectUri = await getEffectiveRedirectUri(platform, uid, redirectUri);
1381
+ if (effectiveRedirectUri) {
1382
+ loginUrl.searchParams.set('redirect_uri', effectiveRedirectUri);
1383
+ }
1384
+ return {
1385
+ loginUrl: loginUrl.toString(),
1386
+ redirectUri: effectiveRedirectUri
1387
+ };
1388
+ };
1389
+
1362
1390
  const getLoggedInState = (state, response) => {
1363
1391
  const accessToken = typeof response.accessToken === 'string' ? response.accessToken : '';
1364
1392
  return {
@@ -1379,6 +1407,58 @@ const isLoginResponse = value => {
1379
1407
  return true;
1380
1408
  };
1381
1409
 
1410
+ const getBackendNativeExchangeUrl = backendUrl => {
1411
+ return getBackendAuthUrl(backendUrl, '/auth/native/exchange');
1412
+ };
1413
+
1414
+ const getExchangeErrorMessage = async response => {
1415
+ try {
1416
+ const payload = await response.json();
1417
+ if (payload && typeof payload === 'object' && typeof payload.error === 'string' && payload.error) {
1418
+ return payload.error;
1419
+ }
1420
+ } catch {
1421
+ // ignore
1422
+ }
1423
+ return 'Backend authentication failed.';
1424
+ };
1425
+ const exchangeElectronAuthorizationCode = async (backendUrl, code, redirectUri) => {
1426
+ const response = await fetch(getBackendNativeExchangeUrl(backendUrl), {
1427
+ body: JSON.stringify({
1428
+ code,
1429
+ redirectUri
1430
+ }),
1431
+ credentials: 'include',
1432
+ headers: {
1433
+ Accept: 'application/json',
1434
+ 'Content-Type': 'application/json'
1435
+ },
1436
+ method: 'POST'
1437
+ });
1438
+ if (!response.ok) {
1439
+ throw new Error(await getExchangeErrorMessage(response));
1440
+ }
1441
+ };
1442
+
1443
+ const hasAuthorizationCode = value => {
1444
+ return typeof value === 'string' && value.length > 0;
1445
+ };
1446
+ const waitForElectronBackendLogin = async (backendUrl, uid, redirectUri, timeoutMs = 30_000, pollIntervalMs = 1000) => {
1447
+ const started = Date.now();
1448
+ const deadline = started + timeoutMs;
1449
+ while (Date.now() < deadline) {
1450
+ const authorizationCode = await invoke('OAuthServer.getCode', String(uid));
1451
+ if (hasAuthorizationCode(authorizationCode)) {
1452
+ const elapsed = Date.now() - started;
1453
+ const remainingTime = Math.max(0, timeoutMs - elapsed);
1454
+ await exchangeElectronAuthorizationCode(backendUrl, authorizationCode, redirectUri);
1455
+ return waitForBackendLogin(backendUrl, remainingTime, pollIntervalMs);
1456
+ }
1457
+ await delay(pollIntervalMs);
1458
+ }
1459
+ return getLoggedOutBackendAuthState('Timed out waiting for backend login.');
1460
+ };
1461
+
1382
1462
  const handleClickLogin = async options => {
1383
1463
  const {
1384
1464
  backendUrl,
@@ -1411,8 +1491,14 @@ const handleClickLogin = async options => {
1411
1491
  }
1412
1492
  return getLoggedInState(signingInState, response);
1413
1493
  }
1414
- await openUrl(getBackendLoginUrl(backendUrl), platform);
1415
- const authState = await waitForBackendLogin(backendUrl);
1494
+ const uid = 0;
1495
+ const {
1496
+ loginUrl,
1497
+ redirectUri
1498
+ } = await getBackendLoginRequest(backendUrl, platform, uid);
1499
+ const authUseRedirect = false;
1500
+ await invoke$1('Open.openUrl', loginUrl, platform, authUseRedirect);
1501
+ const authState = platform === Electron ? await waitForElectronBackendLogin(backendUrl, uid, redirectUri) : await waitForBackendLogin(backendUrl);
1416
1502
  return {
1417
1503
  ...authState
1418
1504
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/auth-worker",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Auth Worker",
5
5
  "repository": {
6
6
  "type": "git",