From 640529ccba7530bee7f72f18be5884b4618537f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 15 Aug 2026 18:42:06 +0000 Subject: [PATCH] offscale in the catalogue, and the comments the rename falsified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin half is in gitea.officer.dev/plugins/offscale (95b84ea). This is what the platform owed it. - marketplace: offscale now ships assets/icon.png, so the catalogue carries an iconUrl and a `bare` tile like music's. The lucide `icon` stays as the fallback for a failed asset publish — a glyph beats the generic box. - Four schema files cited `headscale_servers` as the shape they copied. The table is `offscale_servers` as of today, so those sentences named a table that no longer exists. Same for secret-store.ts's list of purposes. The crypto purpose moved with it: `decryptSecret('headscale', …)` in the plugin is now `'offscale'`, and the secret-store row was renamed rather than abandoned, so the key material is preserved and the change is reversible. Safe only because offscale_servers held 0 rows — one stored API key and this would have been a re-encryption, not a rename. Verified: offscale_servers, uq_offscale_servers_one_active and uq_offscale_servers_user_url all exist in Postgres and nothing named headscale does. Dropped the empty table by hand first, because drizzle-kit push treats a rename as an interactive prompt and would have hung. tsgo clean. 808 pass / 7 fail — +21 from offscale's first tests, same 7 failures. Co-Authored-By: Claude Opus 5 --- src/databases/officer_db/src/invoiceshelf/schema.ts | 2 +- src/databases/officer_db/src/jellyfin/schema.ts | 2 +- src/databases/officer_db/src/photos/schema.ts | 2 +- src/databases/officer_db/src/secret-store.ts | 2 +- src/databases/officer_db/src/wallet/schema.ts | 4 ++-- src/servers/plugins/marketplace.ts | 4 ++++ 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/databases/officer_db/src/invoiceshelf/schema.ts b/src/databases/officer_db/src/invoiceshelf/schema.ts index 129dd7d6..82261399 100644 --- a/src/databases/officer_db/src/invoiceshelf/schema.ts +++ b/src/databases/officer_db/src/invoiceshelf/schema.ts @@ -10,7 +10,7 @@ import { users } from '../auth/schema'; // instance was a shell task on the server rather than something the owner could do from the app. // // It is a REGISTRY, not a single row: the owner adds any number of accounts and switches between them, the -// same shape headscale_servers and photos_config use. Uniqueness is on the label rather than the URL, +// same shape offscale_servers and photos_config use. Uniqueness is on the label rather than the URL, // because the same instance with a different company is a different account here, and two of those share // a URL AND a token. // diff --git a/src/databases/officer_db/src/jellyfin/schema.ts b/src/databases/officer_db/src/jellyfin/schema.ts index adbf4465..736dacd6 100644 --- a/src/databases/officer_db/src/jellyfin/schema.ts +++ b/src/databases/officer_db/src/jellyfin/schema.ts @@ -6,7 +6,7 @@ import { users } from '../auth/schema'; // // A REGISTRY rather than a single row, and here that is not speculative: this machine runs four Jellyfin // instances on separate ports (video, albums, DJ sets, and a second person's), and the owner switches -// between them. Same shape as invoiceshelf_accounts and headscale_servers. +// between them. Same shape as invoiceshelf_accounts and offscale_servers. // // `accessToken` is encrypted at rest via ../crypto.ts. A Jellyfin access token can read every item, every // watch history and every stream on the instance, so a DB dump must not hand it over. Encryption is confined diff --git a/src/databases/officer_db/src/photos/schema.ts b/src/databases/officer_db/src/photos/schema.ts index 363a8cfb..f19528ee 100644 --- a/src/databases/officer_db/src/photos/schema.ts +++ b/src/databases/officer_db/src/photos/schema.ts @@ -10,7 +10,7 @@ import { users } from '../auth/schema'; // than something the owner could do from the app. // // It is a REGISTRY, not a single row: the owner adds any number of accounts and switches between them, the -// same shape headscale_servers uses. Two accounts on the same instance is the normal case (one key per +// same shape offscale_servers uses. Two accounts on the same instance is the normal case (one key per // Immich user), which is why the uniqueness below is on the label and not on the URL. // // `api_key` is encrypted at rest via ../crypto.ts. An Immich key can read and delete the entire library, so a diff --git a/src/databases/officer_db/src/secret-store.ts b/src/databases/officer_db/src/secret-store.ts index 63d82e01..b7e54a6d 100644 --- a/src/databases/officer_db/src/secret-store.ts +++ b/src/databases/officer_db/src/secret-store.ts @@ -117,7 +117,7 @@ function readActive(purpose: string): string | null { /** * The active key for a purpose, created on first use. * - * Purposes are plain strings and belong to whoever owns the data they protect: `jwt`, `headscale`, + * Purposes are plain strings and belong to whoever owns the data they protect: `jwt`, `offscale`, * `wallet`, `photos`, `jellyfin`, `invoiceshelf`, `vault`, `service-connections`. A plugin asks for its * own and never another's — same rule `service_connections` rows already follow. * diff --git a/src/databases/officer_db/src/wallet/schema.ts b/src/databases/officer_db/src/wallet/schema.ts index c92fa0ed..40ebf6f6 100644 --- a/src/databases/officer_db/src/wallet/schema.ts +++ b/src/databases/officer_db/src/wallet/schema.ts @@ -9,7 +9,7 @@ import { users } from '../auth/schema'; // TWO COLUMNS HOLD SPENDING AUTHORITY AND THEY ARE PROTECTED DIFFERENTLY. This asymmetry is deliberate: // // `config` — node credentials (macaroon, rune, LNDHub password, NWC URI). Encrypted at rest with -// the 'wallet' store key via ../crypto.ts, the way headscale_servers.api_key uses its +// the 'wallet' store key via ../crypto.ts, the way offscale_servers.api_key uses its // own. It CANNOT be // passphrase-protected: background balance polling needs it without the owner present. // @@ -58,7 +58,7 @@ export const walletWallets = pgTable( (t) => [ uniqueIndex('uq_wallet_wallets_user_name').on(t.userId, t.name), // At most one active wallet per owner, enforced by the DB rather than convention — a partial unique - // index over active rows only, mirroring uq_headscale_servers_one_active. + // index over active rows only, mirroring uq_offscale_servers_one_active. uniqueIndex('uq_wallet_wallets_one_active') .on(t.userId) .where(sql`${t.isActive}`), diff --git a/src/servers/plugins/marketplace.ts b/src/servers/plugins/marketplace.ts index 6e74fe20..2d2619a2 100644 --- a/src/servers/plugins/marketplace.ts +++ b/src/servers/plugins/marketplace.ts @@ -124,6 +124,10 @@ const CATALOGUE: CatalogueEntry[] = [ label: 'Offscale', summary: 'Your tailnet — machines, users, pre-auth keys, access policy and device invites', color: '#818cf8', + // Ships artwork as of 2026-08-15, so the tile is `bare` like music's. `icon` stays as the fallback + // for the case the assets fail to publish — the glyph is strictly better than the generic box. + tile: 'bare', + iconUrl: 'https://gitea.officer.dev/plugins/offscale/raw/branch/main/assets/icon.png', icon: 'Network', source: 'https://gitea.officer.dev/plugins/offscale.git', permissions: [