@livedesk/client 0.1.59 → 0.1.60

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.
@@ -579,12 +579,16 @@ function renderOAuthCallbackPage({ title, message, tone = 'neutral' }) {
579
579
  </html>`;
580
580
  }
581
581
 
582
- function renderConnectionChoicePage({ error = '', pin = '', slot = '', startup = false, startupSupported = false } = {}) {
582
+ function renderConnectionChoicePage({ autoGoogle = false, error = '', pin = '', slot = '', startup = false, startupSupported = false } = {}) {
583
+ const shouldAutoGoogle = Boolean(autoGoogle && !error);
583
584
  const errorBlock = error
584
585
  ? `<div class="error">${escapeHtml(error)}</div>`
585
586
  : '';
586
587
  const normalizedSlot = normalizeSlotNumber(slot);
587
588
  const slotLabel = normalizedSlot ? `Slot ${String(normalizedSlot).padStart(3, '0')}` : 'First available';
589
+ const footerText = shouldAutoGoogle
590
+ ? 'Checking Google sign-in automatically. Enter a PIN to use the PIN path.'
591
+ : 'This tab can stay open until the connection is ready.';
588
592
  const startupBlock = startupSupported
589
593
  ? `<label class="startup-option">
590
594
  <input id="startup-toggle" type="checkbox" ${startup ? 'checked' : ''}>
@@ -926,7 +930,7 @@ function renderConnectionChoicePage({ error = '', pin = '', slot = '', startup =
926
930
  <input id="pin-startup" type="hidden" name="startup" value="${startup ? '1' : '0'}">
927
931
  <label class="field-label">
928
932
  Hub PIN
929
- <input class="pin-input" name="pin" value="${escapeHtml(pin)}" inputmode="numeric" autocomplete="one-time-code" pattern="[0-9]{6}" maxlength="6" placeholder="000000" autofocus>
933
+ <input class="pin-input" name="pin" value="${escapeHtml(pin)}" inputmode="numeric" autocomplete="one-time-code" pattern="[0-9]{6}" maxlength="6" placeholder="000000" ${shouldAutoGoogle ? '' : 'autofocus'}>
930
934
  </label>
931
935
  <button type="submit">Connect with PIN</button>
932
936
  </form>
@@ -936,7 +940,7 @@ function renderConnectionChoicePage({ error = '', pin = '', slot = '', startup =
936
940
  <strong>${escapeHtml(slotLabel)}</strong>
937
941
  </div>
938
942
  </section>
939
- <small>This tab can stay open until the connection is ready.</small>
943
+ <small>${escapeHtml(footerText)}</small>
940
944
  </div>
941
945
  </main>
942
946
  <aside aria-hidden="true">
@@ -969,6 +973,35 @@ function renderConnectionChoicePage({ error = '', pin = '', slot = '', startup =
969
973
  startupToggle.addEventListener('change', syncStartupFields);
970
974
  syncStartupFields();
971
975
  }
976
+ const autoGoogle = ${shouldAutoGoogle ? 'true' : 'false'};
977
+ let autoGoogleCanceled = false;
978
+ function cancelAutoGoogle() {
979
+ autoGoogleCanceled = true;
980
+ }
981
+ const pinInput = document.querySelector('.pin-input');
982
+ const pinForm = document.getElementById('pin-form');
983
+ if (pinInput) {
984
+ pinInput.addEventListener('focus', cancelAutoGoogle);
985
+ pinInput.addEventListener('input', cancelAutoGoogle);
986
+ pinInput.addEventListener('keydown', cancelAutoGoogle);
987
+ }
988
+ if (pinForm) {
989
+ pinForm.addEventListener('submit', cancelAutoGoogle);
990
+ }
991
+ if (startupToggle) {
992
+ startupToggle.addEventListener('change', cancelAutoGoogle);
993
+ }
994
+ if (autoGoogle) {
995
+ setTimeout(() => {
996
+ if (autoGoogleCanceled) return;
997
+ const googleForm = document.getElementById('google-form');
998
+ if (googleForm && typeof googleForm.requestSubmit === 'function') {
999
+ googleForm.requestSubmit();
1000
+ } else if (googleForm) {
1001
+ googleForm.submit();
1002
+ }
1003
+ }, 900);
1004
+ }
972
1005
  async function watchAutoConnection() {
973
1006
  try {
974
1007
  const response = await fetch('/api/state', { cache: 'no-store' });
@@ -1418,6 +1451,7 @@ async function startConnectionChoiceServer(supabase, options = {}) {
1418
1451
  const startupArgs = Array.isArray(options.startupArgs) ? options.startupArgs : [];
1419
1452
  const savedSession = options.savedSession?.access_token ? options.savedSession : null;
1420
1453
  const savedPin = normalizePairingPin(options.savedPin);
1454
+ const autoGoogle = options.autoGoogle === true;
1421
1455
  let pendingStartup = isWindowsStartupRegistered();
1422
1456
  let listeningPort = port;
1423
1457
  let completed = false;
@@ -1458,6 +1492,7 @@ async function startConnectionChoiceServer(supabase, options = {}) {
1458
1492
  }
1459
1493
  };
1460
1494
  const renderChoice = (props = {}) => renderConnectionChoicePage({
1495
+ autoGoogle,
1461
1496
  slot,
1462
1497
  startup: pendingStartup,
1463
1498
  startupSupported: isWindowsStartupSupported(),
@@ -1525,6 +1560,7 @@ async function startConnectionChoiceServer(supabase, options = {}) {
1525
1560
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
1526
1561
  res.end(renderChoice({
1527
1562
  error: error instanceof Error ? error.message : String(error),
1563
+ autoGoogle: false,
1528
1564
  pin
1529
1565
  }));
1530
1566
  };
@@ -1565,6 +1601,7 @@ async function startConnectionChoiceServer(supabase, options = {}) {
1565
1601
  }
1566
1602
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
1567
1603
  res.end(completed ? renderDashboard() : renderChoice({
1604
+ autoGoogle: false,
1568
1605
  error: 'Saved Google sign-in was cleared.'
1569
1606
  }));
1570
1607
  return;
@@ -1660,6 +1697,7 @@ async function startConnectionChoiceServer(supabase, options = {}) {
1660
1697
  if (!code) {
1661
1698
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
1662
1699
  res.end(renderChoice({
1700
+ autoGoogle: false,
1663
1701
  error: 'Google did not return an auth code. Try Google sign-in again.'
1664
1702
  }));
1665
1703
  return;
@@ -1691,6 +1729,7 @@ async function startConnectionChoiceServer(supabase, options = {}) {
1691
1729
 
1692
1730
  res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
1693
1731
  res.end(renderChoice({
1732
+ autoGoogle: false,
1694
1733
  error: 'Unknown LiveDesk connection route.'
1695
1734
  }));
1696
1735
  })().catch(err => {
@@ -1749,8 +1788,11 @@ async function startConnectionChoiceServer(supabase, options = {}) {
1749
1788
  async function chooseClientConnection(supabase, options = {}) {
1750
1789
  const connectionPage = await startConnectionChoiceServer(supabase, {
1751
1790
  authPort: options.authPort,
1791
+ autoGoogle: options.autoGoogle,
1752
1792
  slot: options.slot,
1753
- startupArgs: options.startupArgs
1793
+ startupArgs: options.startupArgs,
1794
+ savedSession: options.savedSession,
1795
+ savedPin: options.savedPin
1754
1796
  });
1755
1797
  console.log('Opening LiveDesk connection page...');
1756
1798
  openBrowser(connectionPage.url);
@@ -1901,6 +1943,7 @@ async function prepareLoginConnection(parsed) {
1901
1943
  if (!choice) {
1902
1944
  choice = await chooseClientConnection(supabase, {
1903
1945
  authPort: parsed.authPort,
1946
+ autoGoogle: !savedSession?.access_token && !savedPin,
1904
1947
  slot: parsed.slot,
1905
1948
  startupArgs,
1906
1949
  savedSession,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/client",
3
- "version": "0.1.59",
3
+ "version": "0.1.60",
4
4
  "description": "LiveDesk local remote client",
5
5
  "type": "module",
6
6
  "bin": {