@lvce-editor/auth-worker 1.3.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.
@@ -407,6 +407,100 @@ const IpcChildWithModuleWorkerAndMessagePort$1 = {
407
407
  listen: listen$6,
408
408
  wrap: wrap$e
409
409
  };
410
+ const addListener = (emitter, type, callback) => {
411
+ if ('addEventListener' in emitter) {
412
+ emitter.addEventListener(type, callback);
413
+ } else {
414
+ emitter.on(type, callback);
415
+ }
416
+ };
417
+ const removeListener = (emitter, type, callback) => {
418
+ if ('removeEventListener' in emitter) {
419
+ emitter.removeEventListener(type, callback);
420
+ } else {
421
+ emitter.off(type, callback);
422
+ }
423
+ };
424
+ const getFirstEvent = (eventEmitter, eventMap) => {
425
+ const {
426
+ promise,
427
+ resolve
428
+ } = Promise.withResolvers();
429
+ const listenerMap = Object.create(null);
430
+ const cleanup = value => {
431
+ for (const event of Object.keys(eventMap)) {
432
+ removeListener(eventEmitter, event, listenerMap[event]);
433
+ }
434
+ resolve(value);
435
+ };
436
+ for (const [event, type] of Object.entries(eventMap)) {
437
+ const listener = event => {
438
+ cleanup({
439
+ event,
440
+ type
441
+ });
442
+ };
443
+ addListener(eventEmitter, event, listener);
444
+ listenerMap[event] = listener;
445
+ }
446
+ return promise;
447
+ };
448
+ const Message$1 = 3;
449
+ const create$5$1 = async ({
450
+ isMessagePortOpen,
451
+ messagePort
452
+ }) => {
453
+ if (!isMessagePort(messagePort)) {
454
+ throw new IpcError('port must be of type MessagePort');
455
+ }
456
+ if (isMessagePortOpen) {
457
+ return messagePort;
458
+ }
459
+ const eventPromise = getFirstEvent(messagePort, {
460
+ message: Message$1
461
+ });
462
+ messagePort.start();
463
+ const {
464
+ event,
465
+ type
466
+ } = await eventPromise;
467
+ if (type !== Message$1) {
468
+ throw new IpcError('Failed to wait for ipc message');
469
+ }
470
+ if (event.data !== readyMessage) {
471
+ throw new IpcError('unexpected first message');
472
+ }
473
+ return messagePort;
474
+ };
475
+ const signal$1 = messagePort => {
476
+ messagePort.start();
477
+ };
478
+ class IpcParentWithMessagePort extends Ipc {
479
+ getData = getData$2;
480
+ send(message) {
481
+ this._rawIpc.postMessage(message);
482
+ }
483
+ sendAndTransfer(message) {
484
+ const transfer = getTransferrables(message);
485
+ this._rawIpc.postMessage(message, transfer);
486
+ }
487
+ dispose() {
488
+ this._rawIpc.close();
489
+ }
490
+ onMessage(callback) {
491
+ this._rawIpc.addEventListener('message', callback);
492
+ }
493
+ onClose(callback) {}
494
+ }
495
+ const wrap$5 = messagePort => {
496
+ return new IpcParentWithMessagePort(messagePort);
497
+ };
498
+ const IpcParentWithMessagePort$1 = {
499
+ __proto__: null,
500
+ create: create$5$1,
501
+ signal: signal$1,
502
+ wrap: wrap$5
503
+ };
410
504
 
411
505
  class CommandNotFoundError extends Error {
412
506
  constructor(command) {
@@ -643,7 +737,7 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
643
737
  const errorProperty = getErrorProperty(error, prettyError);
644
738
  return create$1$1(id, errorProperty);
645
739
  };
646
- const create$6 = (message, result) => {
740
+ const create$9 = (message, result) => {
647
741
  return {
648
742
  id: message.id,
649
743
  jsonrpc: Two$1,
@@ -652,7 +746,7 @@ const create$6 = (message, result) => {
652
746
  };
653
747
  const getSuccessResponse = (message, result) => {
654
748
  const resultProperty = result ?? null;
655
- return create$6(message, resultProperty);
749
+ return create$9(message, resultProperty);
656
750
  };
657
751
  const getErrorResponseSimple = (id, error) => {
658
752
  return {
@@ -746,7 +840,7 @@ const handleJsonRpcMessage = async (...args) => {
746
840
 
747
841
  const Two = '2.0';
748
842
 
749
- const create$5 = (method, params) => {
843
+ const create$8 = (method, params) => {
750
844
  return {
751
845
  jsonrpc: Two,
752
846
  method,
@@ -754,7 +848,7 @@ const create$5 = (method, params) => {
754
848
  };
755
849
  };
756
850
 
757
- const create$4 = (id, method, params) => {
851
+ const create$7 = (id, method, params) => {
758
852
  const message = {
759
853
  id,
760
854
  jsonrpc: Two,
@@ -765,12 +859,12 @@ const create$4 = (id, method, params) => {
765
859
  };
766
860
 
767
861
  let id = 0;
768
- const create$3 = () => {
862
+ const create$6 = () => {
769
863
  return ++id;
770
864
  };
771
865
 
772
866
  const registerPromise = map => {
773
- const id = create$3();
867
+ const id = create$6();
774
868
  const {
775
869
  promise,
776
870
  resolve
@@ -787,7 +881,7 @@ const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer)
787
881
  id,
788
882
  promise
789
883
  } = registerPromise(callbacks);
790
- const message = create$4(id, method, params);
884
+ const message = create$7(id, method, params);
791
885
  if (useSendAndTransfer && ipc.sendAndTransfer) {
792
886
  ipc.sendAndTransfer(message);
793
887
  } else {
@@ -823,7 +917,7 @@ const createRpc = ipc => {
823
917
  * @deprecated
824
918
  */
825
919
  send(method, ...params) {
826
- const message = create$5(method, params);
920
+ const message = create$8(method, params);
827
921
  ipc.send(message);
828
922
  }
829
923
  };
@@ -863,6 +957,83 @@ const listen$1 = async (module, options) => {
863
957
  return ipc;
864
958
  };
865
959
 
960
+ const create$5 = async ({
961
+ commandMap,
962
+ isMessagePortOpen = true,
963
+ messagePort
964
+ }) => {
965
+ // TODO create a commandMap per rpc instance
966
+ register(commandMap);
967
+ const rawIpc = await IpcParentWithMessagePort$1.create({
968
+ isMessagePortOpen,
969
+ messagePort
970
+ });
971
+ const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
972
+ handleIpc(ipc);
973
+ const rpc = createRpc(ipc);
974
+ messagePort.start();
975
+ return rpc;
976
+ };
977
+
978
+ const create$4 = async ({
979
+ commandMap,
980
+ isMessagePortOpen,
981
+ send
982
+ }) => {
983
+ const {
984
+ port1,
985
+ port2
986
+ } = new MessageChannel();
987
+ await send(port1);
988
+ return create$5({
989
+ commandMap,
990
+ isMessagePortOpen,
991
+ messagePort: port2
992
+ });
993
+ };
994
+
995
+ const createSharedLazyRpc = factory => {
996
+ let rpcPromise;
997
+ const getOrCreate = () => {
998
+ if (!rpcPromise) {
999
+ rpcPromise = factory();
1000
+ }
1001
+ return rpcPromise;
1002
+ };
1003
+ return {
1004
+ async dispose() {
1005
+ const rpc = await getOrCreate();
1006
+ await rpc.dispose();
1007
+ },
1008
+ async invoke(method, ...params) {
1009
+ const rpc = await getOrCreate();
1010
+ return rpc.invoke(method, ...params);
1011
+ },
1012
+ async invokeAndTransfer(method, ...params) {
1013
+ const rpc = await getOrCreate();
1014
+ return rpc.invokeAndTransfer(method, ...params);
1015
+ },
1016
+ async send(method, ...params) {
1017
+ const rpc = await getOrCreate();
1018
+ rpc.send(method, ...params);
1019
+ }
1020
+ };
1021
+ };
1022
+
1023
+ const create$3 = async ({
1024
+ commandMap,
1025
+ isMessagePortOpen,
1026
+ send
1027
+ }) => {
1028
+ return createSharedLazyRpc(() => {
1029
+ return create$4({
1030
+ commandMap,
1031
+ isMessagePortOpen,
1032
+ send
1033
+ });
1034
+ });
1035
+ };
1036
+
866
1037
  const create$2 = async ({
867
1038
  commandMap,
868
1039
  messagePort
@@ -909,7 +1080,7 @@ const createMockRpc = ({
909
1080
  };
910
1081
 
911
1082
  const rpcs = Object.create(null);
912
- const set$1 = (id, rpc) => {
1083
+ const set$2 = (id, rpc) => {
913
1084
  rpcs[id] = rpc;
914
1085
  };
915
1086
  const get = id => {
@@ -942,7 +1113,7 @@ const create = rpcId => {
942
1113
  const mockRpc = createMockRpc({
943
1114
  commandMap
944
1115
  });
945
- set$1(rpcId, mockRpc);
1116
+ set$2(rpcId, mockRpc);
946
1117
  // @ts-ignore
947
1118
  mockRpc[Symbol.dispose] = () => {
948
1119
  remove(rpcId);
@@ -951,23 +1122,41 @@ const create = rpcId => {
951
1122
  return mockRpc;
952
1123
  },
953
1124
  set(rpc) {
954
- set$1(rpcId, rpc);
1125
+ set$2(rpcId, rpc);
955
1126
  }
956
1127
  };
957
1128
  };
958
1129
 
1130
+ const Electron = 2;
1131
+
959
1132
  const OpenerWorker = 4561;
960
1133
  const RendererWorker = 1;
961
1134
 
962
1135
  const {
963
- invoke} = create(OpenerWorker);
964
- const openUrl = async (url, platform) => {
965
- return invoke('Open.openUrl', url, platform);
966
- };
1136
+ invoke: invoke$1,
1137
+ set: set$1
1138
+ } = create(OpenerWorker);
967
1139
 
968
1140
  const {
1141
+ invoke,
1142
+ invokeAndTransfer,
969
1143
  set
970
1144
  } = create(RendererWorker);
1145
+ const sendMessagePortToOpenerWorker$1 = async (port, rpcId) => {
1146
+ const command = 'HandleMessagePort.handleMessagePort';
1147
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToOpenerWorker', port, command, rpcId);
1148
+ };
1149
+
1150
+ const sendMessagePortToOpenerWorker = async port => {
1151
+ await sendMessagePortToOpenerWorker$1(port, 0);
1152
+ };
1153
+ const initializeOpenerWorker = async () => {
1154
+ const rpc = await create$3({
1155
+ commandMap: {},
1156
+ send: sendMessagePortToOpenerWorker
1157
+ });
1158
+ set$1(rpc);
1159
+ };
971
1160
 
972
1161
  const handleMessagePort = async port => {
973
1162
  await create$2({
@@ -989,10 +1178,6 @@ const getBackendAuthUrl = (backendUrl, path) => {
989
1178
  return `${trimTrailingSlashes(backendUrl)}${path}`;
990
1179
  };
991
1180
 
992
- const getBackendLoginUrl = backendUrl => {
993
- return getBackendAuthUrl(backendUrl, '/auth/login');
994
- };
995
-
996
1181
  const getLoggedOutBackendAuthState = (authErrorMessage = '') => {
997
1182
  return {
998
1183
  authAccessToken: '',
@@ -1170,6 +1355,38 @@ const waitForBackendLogin = async (backendUrl, timeoutMs = 30_000, pollIntervalM
1170
1355
  return getLoggedOutBackendAuthState(lastErrorMessage);
1171
1356
  };
1172
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
+
1173
1390
  const getLoggedInState = (state, response) => {
1174
1391
  const accessToken = typeof response.accessToken === 'string' ? response.accessToken : '';
1175
1392
  return {
@@ -1190,6 +1407,58 @@ const isLoginResponse = value => {
1190
1407
  return true;
1191
1408
  };
1192
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
+
1193
1462
  const handleClickLogin = async options => {
1194
1463
  const {
1195
1464
  backendUrl,
@@ -1222,8 +1491,14 @@ const handleClickLogin = async options => {
1222
1491
  }
1223
1492
  return getLoggedInState(signingInState, response);
1224
1493
  }
1225
- await openUrl(getBackendLoginUrl(backendUrl), platform);
1226
- 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);
1227
1502
  return {
1228
1503
  ...authState
1229
1504
  };
@@ -1271,7 +1546,7 @@ const initializeRendererWorker = async () => {
1271
1546
  };
1272
1547
 
1273
1548
  const listen = async () => {
1274
- await initializeRendererWorker();
1549
+ await Promise.all([initializeRendererWorker(), initializeOpenerWorker()]);
1275
1550
  };
1276
1551
 
1277
1552
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/auth-worker",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "Auth Worker",
5
5
  "repository": {
6
6
  "type": "git",