ghostdock 0.0.11 → 0.0.12

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.
@@ -255,7 +255,7 @@ The private network: reach your sandboxes by address and name from this machine.
255
255
 
256
256
  ### `ghostdock network connect`
257
257
 
258
- Put this machine into the private network through one provider: WireGuard and split DNS. Asks for sudo once.
258
+ Put this machine into the private network through one provider: WireGuard and split DNS. The organization (--org, else the default) becomes this machine's short-name organization. Asks for sudo once.
259
259
 
260
260
  ```
261
261
  ghostdock network connect [provider] [flags]
package/dist/cli.md CHANGED
@@ -498,6 +498,8 @@ ghostdock network connect helsinki # or name a provider (name or id)
498
498
  ghostdock network ls --org acme # sandboxes, addresses, names, and what is reachable
499
499
  curl http://quiet-harbor.acme.ghostdock.internal:8080/
500
500
  open https://quiet-harbor--acme.ghostdock.net:8080/ # in a browser: HTTPS, any port
501
+ open https://quiet-harbor.ghostdock.net:8080/ # the short name, for the connect organization
502
+ ghostdock network connect --org beta # short names now mean beta's sandboxes
501
503
  ghostdock network status
502
504
  ghostdock network disconnect
503
505
  ```
@@ -528,6 +530,28 @@ ghostdock network disconnect
528
530
  sandbox sees the request from `198.18.0.0`, and your device's address in
529
531
  `X-Forwarded-For`. The desktop image's Desktop opens only this way, never on the raw
530
532
  address.
533
+ - **Short names** in a browser: `https://<sandbox>.ghostdock.net:<port>` means the sandbox of
534
+ this machine's organization: the one `network connect` resolved (`--org`, `GHOSTDOCK_ORG`,
535
+ the default from `organizations use`). `connect` says which; `network status` too, and
536
+ `network ls` shows a sandbox's short name next to its full one when it is that
537
+ organization's. With one organization you need nothing else. To use another organization's
538
+ short names, connect again with `--org <other>`: there is no other way to change it, so a
539
+ short name never changes meaning behind your back (`cd` into another project does not
540
+ change it). Full names (`<sandbox>--<org>`) keep working for every organization and never
541
+ change meaning: use them in scripts, CI, `.env` files and links you share.
542
+ - **When the organization changes,** each short-name site clears its browser data once
543
+ (local storage, cache, cookies) before the other organization's sandbox sees a request, so
544
+ it never reads the first one's data. Cookies are cleared for the whole site, not only the
545
+ short name: every site under the net domain's registrable domain (`ghostdock.net`: every
546
+ sandbox app there, full names included; a net domain under the app's domain, as on staging:
547
+ the Ghostdock app too). `connect` names the site when the organization changes. A tab opened on a short name before the
548
+ change keeps the old page until you reload it: reload or close those tabs (`connect` says
549
+ so). The page *Switching organization* is that clearing and reloads by itself; *Clear this
550
+ site's data* means your browser could not clear it (Safari before 17): clear the site's
551
+ data in its settings, or use the full name.
552
+ - Tools may use short names too (`curl https://quiet-harbor.ghostdock.net:8080/`), but a
553
+ short name in a script means whatever this machine is connected with: prefer the full
554
+ name.
531
555
  - **Browsers use the HTTPS name; tools keep the raw address.** A browser that opens
532
556
  `http://quiet-harbor.acme.ghostdock.internal:3000/app` (or the raw IPv6 address) gets a
533
557
  `308` to `https://quiet-harbor--acme.ghostdock.net:3000/app`. Any other browser request on
package/dist/index.js CHANGED
@@ -8588,7 +8588,7 @@ function getCliName(argv = process.argv) {
8588
8588
  return CLI_NAMES.find((name) => name === invoked) ?? "ghostdock";
8589
8589
  }
8590
8590
  // package.json
8591
- var version = "0.0.11";
8591
+ var version = "0.0.12";
8592
8592
  var package_default = {
8593
8593
  name: "ghostdock",
8594
8594
  description: "Ghostdock CLI — device login and agent tool invocation from the command line",
@@ -10060,9 +10060,10 @@ async function runNetworkConnect(args = {}, deps = defaultDeps()) {
10060
10060
  deps.error(`wg-quick exited ${code}. The config is in ${configPath(deps.dir)}.`);
10061
10061
  return 1;
10062
10062
  }
10063
- const { device, network, provider } = registered;
10063
+ const { device, network, provider, shortNameOrganizationChanged } = registered;
10064
+ const pinned = device.shortNameOrganization;
10064
10065
  const switched = wasUp && previous?.gatewayProvider && previous.gatewayProvider.id !== provider.id ? previous.gatewayProvider : null;
10065
- printResult({ device, network, provider, interface: INTERFACE, dns }, () => [
10066
+ printResult({ device, network, provider, shortNameOrganizationChanged, interface: INTERFACE, dns }, () => [
10066
10067
  eventLine("done", `Connected through ${provider.name}. This machine is ${device.address} in the private network.`),
10067
10068
  ...switched ? [
10068
10069
  ` Replaced the connection through ${switched.name}: its sandboxes are out of reach now.`
@@ -10070,6 +10071,11 @@ async function runNetworkConnect(args = {}, deps = defaultDeps()) {
10070
10071
  ` Reachable: the sandboxes on ${provider.name}. One provider at a time.`,
10071
10072
  ` Names: <sandbox>.<org>.${network.zone}`,
10072
10073
  ...network.netZone ? [` In a browser: https://<sandbox>--<org>.${network.netZone}:<port>`] : [],
10074
+ ...network.netZone && pinned ? [
10075
+ ` Short names: https://<sandbox>.${network.netZone}:<port> for ${pinned.slug}'s sandboxes, on this machine.`,
10076
+ ` Another organization: ${getCliName()} network connect --org <org>.`
10077
+ ] : [],
10078
+ ...network.netZone && pinned && shortNameOrganizationChanged ? clearingNotice(network.netCookieSite) : [],
10073
10079
  ...dns === "none" ? [
10074
10080
  " No split DNS on this machine (no systemd-resolved): use the addresses from",
10075
10081
  ` \`${getCliName()} network ls\`.`
@@ -10078,6 +10084,15 @@ async function runNetworkConnect(args = {}, deps = defaultDeps()) {
10078
10084
  ], deps.log);
10079
10085
  return 0;
10080
10086
  }
10087
+ function clearingNotice(cookieSite) {
10088
+ const site = cookieSite?.site ?? "the net domain";
10089
+ return [
10090
+ " Short names meant another organization's sandboxes before. The first short-name site each",
10091
+ ` browser opens now clears its data once: the site's storage, and every cookie of ${site}.`,
10092
+ ` That signs the browser out of every site under ${site}${cookieSite?.includesApp ? ", the Ghostdock app included" : ""}.`,
10093
+ " Reload or close browser tabs opened on short names before this connect."
10094
+ ];
10095
+ }
10081
10096
  async function runNetworkDisconnect(deps = defaultDeps()) {
10082
10097
  if (!deps.up()) {
10083
10098
  printResult({ connected: false }, () => [eventLine("item", "Not connected.")], deps.log);
@@ -10123,6 +10138,9 @@ async function runNetworkStatus(deps = defaultDeps()) {
10123
10138
  ];
10124
10139
  if (device) {
10125
10140
  lines.push(` Device ${device.name}, valid until ${device.expiresAt.slice(0, 10)}.`);
10141
+ if (device.shortNameOrganization) {
10142
+ lines.push(` Short names: ${device.shortNameOrganization.slug}'s sandboxes.`);
10143
+ }
10126
10144
  if (!device.gatewayProvider) {
10127
10145
  lines.push(` Its provider is gone, so no gateway serves it. Run \`${getCliName()} network connect\`.`);
10128
10146
  }
@@ -10146,8 +10164,10 @@ function unreachableNote(sandbox, connected) {
10146
10164
  async function runNetworkLs(args, deps = defaultDeps()) {
10147
10165
  try {
10148
10166
  const organization = await requireOrganizationRef(args.org, deps.notice);
10149
- const listed = await deps.request(`/api/v1/network/organizations/${encodeURIComponent(organization)}/sandboxes`);
10150
- const connected = (await readConnection(deps)).provider;
10167
+ const connection = await readConnection(deps);
10168
+ const deviceId = connection.device?.id;
10169
+ const listed = await deps.request(`/api/v1/network/organizations/${encodeURIComponent(organization)}/sandboxes${deviceId ? `?device=${encodeURIComponent(deviceId)}` : ""}`);
10170
+ const connected = connection.provider;
10151
10171
  const sandboxes = listed.sandboxes.map((sandbox) => ({
10152
10172
  ...sandbox,
10153
10173
  reachable: unreachableNote(sandbox, connected) === null
@@ -10159,6 +10179,7 @@ async function runNetworkLs(args, deps = defaultDeps()) {
10159
10179
  const width = Math.max(...listed.sandboxes.map((s) => s.name.length));
10160
10180
  const canonicalWidth = Math.max(...listed.sandboxes.map((s) => s.canonicalName.length));
10161
10181
  const httpsWidth = Math.max(...listed.sandboxes.map((s) => (s.httpsName?.length ?? 0) + 8));
10182
+ const shortWidth = Math.max(...listed.sandboxes.map((s) => (s.shortName?.length ?? 0) + 8));
10162
10183
  const lines = [
10163
10184
  connected ? eventLine("item", `Connected through ${connected.name}.`) : eventLine("item", `Not connected: nothing is reachable. Run \`${getCliName()} network connect [provider]\`.`)
10164
10185
  ];
@@ -10169,6 +10190,7 @@ async function runNetworkLs(args, deps = defaultDeps()) {
10169
10190
  s.address.padEnd(28),
10170
10191
  s.canonicalName.padEnd(canonicalWidth),
10171
10192
  ...s.httpsName ? [`https://${s.httpsName}`.padEnd(httpsWidth)] : [],
10193
+ ...s.shortName ? [`https://${s.shortName}`.padEnd(shortWidth)] : [],
10172
10194
  s.status,
10173
10195
  ...note ? [`(${note})`] : []
10174
10196
  ].join(" "));
@@ -10207,7 +10229,7 @@ async function runNetworkDevicesRemove(args, deps = defaultDeps()) {
10207
10229
  var connectCommand = defineCommand({
10208
10230
  meta: {
10209
10231
  name: "connect",
10210
- description: "Put this machine into the private network through one provider: WireGuard and split DNS. Asks for sudo once."
10232
+ description: "Put this machine into the private network through one provider: WireGuard and split DNS. The organization (--org, else the default) becomes this machine's short-name organization. Asks for sudo once."
10211
10233
  },
10212
10234
  args: {
10213
10235
  provider: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ghostdock",
3
3
  "description": "Ghostdock CLI — device login and agent tool invocation from the command line",
4
- "version": "0.0.11",
4
+ "version": "0.0.12",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "ghostdock": "dist/index.js",