@dshn/agent 0.1.5 → 0.1.7

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/client.js +39 -26
  2. package/package.json +1 -1
package/client.js CHANGED
@@ -279,7 +279,7 @@ window.__ModuleLoader__.load({
279
279
  border: 1px solid var(--dsw-alias-border-l1, rgba(128,134,142,.25)); }
280
280
  .dshn-panel[data-mode="modal"] { width: min(400px, 92vw); padding: 20px 22px 18px; box-shadow: 0 24px 64px rgba(0,0,0,.34); }
281
281
  .dshn-panel[data-mode="card"] { width: 308px; margin-top: 8px; padding: 14px 15px 13px; box-shadow: 0 8px 24px rgba(0,0,0,.16); }
282
- .dshn-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
282
+ .dshn-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 9px; }
283
283
  .dshn-htitle { font-size: 14.5px; font-weight: 650; }
284
284
  .dshn-hsub { color: var(--dsw-alias-label-tertiary, #8b9099); font-size: 11.5px; margin-top: 2px; }
285
285
  .dshn-x { border: 0; background: transparent; cursor: pointer; font-size: 17px; line-height: 1; padding: 2px 4px;
@@ -289,7 +289,7 @@ window.__ModuleLoader__.load({
289
289
  .dshn-status { display: flex; align-items: center; gap: 7px; margin-bottom: 11px; font-size: 12px; }
290
290
  .dshn-url { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
291
291
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
292
- .dshn-addr { display: flex; align-items: center; gap: 6px; margin-bottom: 12px; padding: 8px 8px 8px 11px;
292
+ .dshn-addr { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; padding: 6px 8px 6px 11px;
293
293
  border: 1px solid var(--dsw-alias-border-l2, rgba(128,134,142,.25)); border-radius: 10px;
294
294
  background: var(--dsw-alias-bg-layer-2, #f4f5f7); }
295
295
  .dshn-addr-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--dsw-alias-label-tertiary, #8b9099); }
@@ -303,10 +303,10 @@ window.__ModuleLoader__.load({
303
303
  color: var(--dsw-alias-label-tertiary, #8b9099); text-decoration: none; }
304
304
  .dshn-addr-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(128,134,142,.16)); color: var(--dsw-alias-label-primary, #1c1e21); }
305
305
 
306
- .dshn-field { display: block; margin-bottom: 11px; }
307
- .dshn-field > span { display: block; color: var(--dsw-alias-label-tertiary, #8b9099); font-size: 11px; margin-bottom: 4px; }
306
+ .dshn-field { display: block; margin-bottom: 7px; }
307
+ .dshn-field > span { display: block; color: var(--dsw-alias-label-tertiary, #8b9099); font-size: 11px; margin-bottom: 3px; }
308
308
  .dshn-prefixwrap { display: flex; align-items: stretch; }
309
- .dshn-input { width: 100%; box-sizing: border-box; padding: 8px 10px; font-size: 13.5px;
309
+ .dshn-input { width: 100%; box-sizing: border-box; padding: 6px 10px; font-size: 13.5px;
310
310
  border: 1px solid var(--dsw-alias-border-l1, rgba(128,134,142,.35)); border-radius: 8px; background: transparent; color: inherit; }
311
311
  .dshn-input:focus { outline: 2px solid var(--dsw-alias-label-primary-bluish, #4176e6); outline-offset: -1px; }
312
312
  .dshn-input[data-bad="1"] { border-color: var(--dsw-alias-state-error-primary, #e5484d); }
@@ -325,24 +325,27 @@ window.__ModuleLoader__.load({
325
325
  .dshn-strength { font-size: 10.5px; margin-top: 3px; }
326
326
 
327
327
  .dshn-actions { display: flex; gap: 8px; align-items: center; margin-top: 3px; }
328
- .dshn-primary { flex: 1; padding: 9px; border: 0; border-radius: 8px; cursor: pointer; background: #4176e6; color: #fff; font-size: 13.5px; }
328
+ .dshn-primary { flex: 1; padding: 7px; border: 0; border-radius: 8px; cursor: pointer; background: #4176e6; color: #fff; font-size: 13.5px; }
329
329
  .dshn-primary:disabled { opacity: .5; cursor: default; }
330
- .dshn-ghost { border: 0; background: transparent; cursor: pointer; color: var(--dsw-alias-label-tertiary, #8b9099); font-size: 12.5px; padding: 9px 8px; }
330
+ .dshn-ghost { border: 0; background: transparent; cursor: pointer; color: var(--dsw-alias-label-tertiary, #8b9099); font-size: 12.5px; padding: 7px 8px; }
331
331
  .dshn-err { color: var(--dsw-alias-state-error-primary, #e5484d); font-size: 11.5px; margin-bottom: 9px; }
332
332
  .dshn-hint { color: var(--dsw-alias-label-tertiary, #8b9099); font-size: 10.5px; margin-top: 3px; }
333
- .dshn-note { color: var(--dsw-alias-state-warn-primary, #d98324); font-size: 10.5px; margin: 2px 0 10px; }
334
- .dshn-modeseg { display: flex; gap: 4px; padding: 3px; border-radius: 9px; background: var(--dsw-alias-bg-layer-2, #f4f5f7);
333
+ .dshn-note { color: var(--dsw-alias-state-warn-primary, #d98324); font-size: 10.5px; margin: 2px 0 8px; }
334
+ .dshn-modeseg { display: flex; gap: 4px; padding: 2px; border-radius: 9px; background: var(--dsw-alias-bg-layer-2, #f4f5f7);
335
335
  border: 1px solid var(--dsw-alias-border-l2, rgba(128,134,142,.22)); }
336
- .dshn-modebtn { flex: 1; padding: 6px 10px; border: 0; border-radius: 6px; cursor: pointer; font-size: 12.5px; font-family: inherit;
336
+ .dshn-modebtn { flex: 1; padding: 5px 10px; border: 0; border-radius: 6px; cursor: pointer; font-size: 12.5px; font-family: inherit;
337
337
  background: transparent; color: var(--dsw-alias-label-secondary, #4a4f57); }
338
338
  .dshn-modebtn.dshn-on { background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-primary, #1c1e21);
339
339
  box-shadow: 0 1px 2px rgba(0,0,0,.08); }
340
- .dshn-ca { min-height: 54px; resize: vertical; font-family: ui-monospace, Menlo, monospace; font-size: 11px; line-height: 1.4; }
341
- .dshn-e2e-box { margin: 4px 0 12px; padding: 11px 12px; border-radius: 10px;
340
+ .dshn-ca { min-height: 46px; resize: vertical; font-family: ui-monospace, Menlo, monospace; font-size: 11px; line-height: 1.4; }
341
+ .dshn-catoggle { border: 0; background: transparent; cursor: pointer; padding: 2px 0; font-size: 11px; font-family: inherit;
342
+ color: var(--dsw-alias-label-tertiary, #8b9099); }
343
+ .dshn-catoggle:hover { color: var(--dsw-alias-label-primary, #1c1e21); }
344
+ .dshn-e2e-box { margin: 2px 0 8px; padding: 9px 11px; border-radius: 10px;
342
345
  border: 1px solid var(--dsw-alias-border-l2, rgba(128,134,142,.25)); background: var(--dsw-alias-bg-layer-2, #f4f5f7); }
343
- .dshn-e2e-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px;
346
+ .dshn-e2e-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px;
344
347
  color: var(--dsw-alias-label-tertiary, #8b9099); font-size: 11px; }
345
- .dshn-e2e-actions { display: flex; gap: 8px; align-items: center; margin-top: 9px; }
348
+ .dshn-e2e-actions { display: flex; gap: 8px; align-items: center; margin-top: 7px; }
346
349
  .dshn-btn-sm { padding: 6px 12px; border: 0; border-radius: 7px; cursor: pointer; font-size: 12px;
347
350
  background: #4176e6; color: #fff; }
348
351
  .dshn-btn-sm:disabled { opacity: .5; cursor: default; }
@@ -350,16 +353,16 @@ window.__ModuleLoader__.load({
350
353
  border: 1px solid var(--dsw-alias-border-l1, rgba(128,134,142,.3)); }
351
354
  .dshn-btn-warn:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #e5484d) 10%, transparent); }
352
355
  .dshn-info { border: 1px solid var(--dsw-alias-border-l2, rgba(128,134,142,.22)); border-radius: 9px;
353
- padding: 8px 10px; margin-bottom: 12px; }
354
- .dshn-info-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; font-size: 11.5px; padding: 3px 0; }
356
+ padding: 6px 10px; margin-bottom: 8px; }
357
+ .dshn-info-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; font-size: 11.5px; padding: 1.5px 0; }
355
358
  .dshn-info-k { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-tertiary, #8b9099); }
356
359
  .dshn-info-k svg { flex: none; opacity: .85; }
357
360
  .dshn-info-v { font-family: ui-monospace, Menlo, monospace; text-align: right; font-variant-numeric: tabular-nums; }
358
361
  .dshn-dcwarn { border: 1px solid var(--dsw-alias-state-error-primary, #e5484d); background: rgba(229,72,77,.08);
359
- border-radius: 9px; padding: 10px 11px; margin-bottom: 11px; }
360
- .dshn-dcwarn-title { font-weight: 640; font-size: 12.5px; margin-bottom: 5px; }
362
+ border-radius: 9px; padding: 8px 10px; margin-bottom: 8px; }
363
+ .dshn-dcwarn-title { font-weight: 640; font-size: 12.5px; margin-bottom: 3px; }
361
364
  .dshn-dcwarn-body { font-size: 11.5px; color: var(--dsw-alias-label-secondary, #4a4f57); }
362
- .dshn-danger { flex: 1; padding: 9px; border: 0; border-radius: 8px; cursor: pointer;
365
+ .dshn-danger { flex: 1; padding: 7px; border: 0; border-radius: 8px; cursor: pointer;
363
366
  background: var(--dsw-alias-state-error-primary, #e5484d); color: #fff; font-size: 13px; }
364
367
  `
365
368
  const cssId = ID + '/widget.css'
@@ -500,6 +503,9 @@ window.__ModuleLoader__.load({
500
503
  const [mode, setMode] = react.useState(rs0.relayHost ? 'selfhost' : 'official')
501
504
  const [relayHost, setRelayHost] = react.useState(rs0.relayHost || '')
502
505
  const [originCa, setOriginCa] = react.useState(rs0.originCa || '')
506
+ // The self-signed CA is rarely needed (valid cert / Cloudflare cover most);
507
+ // hidden behind a toggle, auto-shown only if one is already saved.
508
+ const [showCa, setShowCa] = react.useState(!!rs0.originCa)
503
509
 
504
510
  // When the saved passwords arrive from a later status poll, fill them once.
505
511
  react.useEffect(() => {
@@ -514,7 +520,7 @@ window.__ModuleLoader__.load({
514
520
  const rs = s.relaySettings
515
521
  if (!rs) return
516
522
  if (rs.relayHost && relayHost === '') { setRelayHost(rs.relayHost); setMode('selfhost') }
517
- if (rs.originCa && originCa === '') setOriginCa(rs.originCa)
523
+ if (rs.originCa && originCa === '') { setOriginCa(rs.originCa); setShowCa(true) }
518
524
  }, [s.relaySettings && s.relaySettings.relayHost])
519
525
 
520
526
  // The domain suffix reflects the self-hosted relay AS YOU TYPE it (a
@@ -623,6 +629,11 @@ window.__ModuleLoader__.load({
623
629
 
624
630
  liveErr ? h('div', { className: 'dshn-err' }, liveErr) : null,
625
631
 
632
+ // While confirming a disconnect, hide the whole editable form (you're
633
+ // leaving it) so the confirmation stays short and fully visible instead of
634
+ // growing the panel past its container.
635
+ confirmDc ? null : h(react.Fragment, null,
636
+
626
637
  // Mode: official ds.hn vs self-hosted. The subdomain + password + e2e
627
638
  // below are shared; self-hosted just adds where your own relay lives.
628
639
  h('div', { className: 'dshn-field' },
@@ -636,11 +647,13 @@ window.__ModuleLoader__.load({
636
647
  h('input', { className: 'dshn-input', value: relayHost, placeholder: 'wss://tunnel.example.com',
637
648
  autoComplete: 'off', spellCheck: false, autoFocus: !configured, onChange: (ev) => setRelayHost(ev.target.value) }),
638
649
  h('div', { className: 'dshn-hint' }, T.relayHostHint)) : null,
639
- mode === 'selfhost' ? h('label', { className: 'dshn-field' },
640
- h('span', null, T.relayCa),
641
- h('textarea', { className: 'dshn-input dshn-ca', value: originCa, rows: 3, spellCheck: false,
642
- placeholder: '-----BEGIN CERTIFICATE-----', onChange: (ev) => setOriginCa(ev.target.value) }),
643
- h('div', { className: 'dshn-hint' }, T.relayCaHint)) : null,
650
+ // Self-signed CA hidden behind a toggle; only the rare self-signed relay
651
+ // needs it (valid cert / behind Cloudflare needs nothing).
652
+ mode === 'selfhost' ? h('div', { className: 'dshn-field' },
653
+ h('button', { type: 'button', className: 'dshn-catoggle', onClick: () => setShowCa(!showCa) }, (showCa ? '▾ ' : '▸ ') + T.relayCa),
654
+ showCa ? h('textarea', { className: 'dshn-input dshn-ca', value: originCa, rows: 3, spellCheck: false, style: { marginTop: '6px' },
655
+ placeholder: '-----BEGIN CERTIFICATE-----', onChange: (ev) => setOriginCa(ev.target.value) }) : null,
656
+ showCa ? h('div', { className: 'dshn-hint' }, T.relayCaHint) : null) : null,
644
657
 
645
658
  h('label', { className: 'dshn-field' },
646
659
  h('span', null, T.prefix),
@@ -717,7 +730,7 @@ window.__ModuleLoader__.load({
717
730
  e2eBusy ? T.connecting2 : (s.e2eEnabled ? T.e2eUpdate : T.e2eApply)),
718
731
  s.e2eEnabled ? h('button', { className: 'dshn-btn-sm dshn-btn-warn', disabled: e2eBusy, onClick: () => { setE2e(''); applyE2E('') } }, T.e2eDisable) : null),
719
732
  h('div', { className: 'dshn-hint', style: { marginTop: '7px' } }, T.e2eHint + ' ' + T.e2eIndep))
720
- })() : null,
733
+ })() : null),
721
734
 
722
735
  // Disconnecting severs public access and the password is unrecoverable
723
736
  // from the cloud — so it takes an explicit, spelled-out confirmation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dshn/agent",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Forward a local dsh web service to the public internet over ds.hn (bundled).",
5
5
  "keywords": [
6
6
  "dsh",