license: relicense to AGPL-3.0-only with commercial dual-license

- LICENSE -> verbatim GNU AGPL-3.0; add LICENSE-COMMERCIAL.md + SECURITY.md
- CLA -> exclusive-license grant (contributors keep copyright); add README
  anti-rugpull covenant + relicense record
- NOTICE / README / CONTRIBUTING / CLAUDE.md / package.json x5 updated;
  contact routed through GitHub (no email placeholders)
- AGPL section 13 source offer: operator-configurable BACKSPACE_SOURCE_URL +
  build-injected commit; sourceCodeUrl+commit on /api/instance/info;
  SourceCodeLink on login/register/settings/desktop; docs + .env.example updated
This commit is contained in:
Jannis Braun
2026-07-01 16:38:22 +02:00
parent 16d75f2806
commit f481e1fe9e
34 changed files with 1084 additions and 165 deletions
+4
View File
@@ -169,6 +169,8 @@ No authentication. Returns:
version: string; // Hardcoded '1.0.0' in instance.ts
registrationOpen: boolean; // DB setting overrides env if non-null
federatedRegistrationOpen: boolean; // NOT NULL DEFAULT 1; gates federated-account creation
sourceCodeUrl: string; // AGPL § 13; config.sourceCodeUrl (env BACKSPACE_SOURCE_URL)
commit: string | null; // AGPL § 13; config.commit (env BACKSPACE_COMMIT, build-injected)
}
```
@@ -176,6 +178,8 @@ Registration resolution order: `instance_settings.registrationOpen` (if not null
`federatedRegistrationOpen` is consumed by the Connections UI (client-federation.md) to decide whether to surface the "create federated account on this instance" affordance.
`sourceCodeUrl` / `commit` implement the **AGPL-3.0 § 13 network-use source offer**. `sourceCodeUrl` defaults to the upstream repo and is overridable via `BACKSPACE_SOURCE_URL` — operators running a modified build MUST point it at their fork so network users get the source of the version actually running. `commit` is injected at Docker build time (`deploy.sh` passes `--build-arg BACKSPACE_COMMIT=$(git rev-parse --short HEAD)` → Dockerfile `ARG`/`ENV``config.commit`); it is `null` in local dev. These are not admin-editable settings — they are deployment/config values, deliberately exposed on this unauthenticated endpoint for transparency to anonymous users and federated peers.
### General Instance Settings
```
+3 -1
View File
@@ -227,10 +227,12 @@ Permissions checked: CONNECT, SPEAK, STREAM (space channels). DM calls: always f
## Instance (`routes/instance.ts`) — public
```
GET /instance/info → { name, version, registrationOpen, federatedRegistrationOpen }
GET /instance/info → { name, version, registrationOpen, federatedRegistrationOpen, sourceCodeUrl, commit }
```
`federatedRegistrationOpen` is a UX hint consumed by the Connections add-instance pre-flight (see `client-federation.md`). The 403 from `POST /auth/register` remains the security boundary.
`sourceCodeUrl` (`string`) and `commit` (`string | null`) implement the **AGPL-3.0 § 13 network-use source offer**: every network user (and federated peer) can obtain the Corresponding Source of the exact version this instance is running. `sourceCodeUrl` comes from `config.sourceCodeUrl` (env `BACKSPACE_SOURCE_URL`, default `https://github.com/TheZwiss/backspace`) — operators who modify Backspace MUST set it to their fork's source. `commit` comes from `config.commit` (env `BACKSPACE_COMMIT`, injected at Docker build via `deploy.sh --build-arg`; `null` in local dev). The web client surfaces `sourceCodeUrl`/`version` via the `SourceCodeLink` component on settings sidebars and the pre-auth login/register pages; the desktop app exposes it via the tray + app menus ("Source code (AGPL)") and the native About panel.
## Settings (`routes/settings.ts`)
```
GET /settings/streaming (auth) → { streamingLimits }
+3 -1
View File
@@ -342,9 +342,11 @@ The **Connections** panel (in user settings) allows managing remote instance con
The hostname-probe step calls `GET /api/instance/info` on the target. The response carries two registration fields:
```typescript
{ name, version, registrationOpen: boolean, federatedRegistrationOpen: boolean }
{ name, version, registrationOpen: boolean, federatedRegistrationOpen: boolean, sourceCodeUrl: string, commit: string | null }
```
`sourceCodeUrl` / `commit` are the AGPL § 13 source offer (see `api.md`). `probeInstance` returns the whole payload, and the connect/login/reconnect/autoConnect paths persist `version`, `sourceCodeUrl`, and `commit` onto each `ConnectedInstance` so the client can surface the source link per instance.
`federatedRegistrationOpen` is the gate for **creating a federated `username@thisInstance` account** via the Connections flow. When the probe returns `federatedRegistrationOpen === false`, `ConnectedInstances.tsx` (the AddInstanceFlow's password step) renders an amber-tinted banner above the password input:
> "This instance has disabled new federated registrations. Existing accounts can still sign in."
+2
View File
@@ -36,6 +36,8 @@ Backspace ships as a single application container fronted by Caddy. Everything i
The server is run through `tsx` (no separate transpile step); TypeScript is executed directly at runtime.
**AGPL § 13 commit injection.** The runtime stage declares `ARG BACKSPACE_COMMIT` + `ENV BACKSPACE_COMMIT=$BACKSPACE_COMMIT` so the running build's git commit is baked into the image and read by `config.commit` (exposed via `GET /api/instance/info`). `docker-compose.yml` forwards it through `build.args: { BACKSPACE_COMMIT: ${BACKSPACE_COMMIT:-} }`, and `deploy.sh` captures `git rev-parse --short HEAD` locally (the remote has no `.git` after rsync) and exports it inline before the remote `docker compose up -d --build`. Empty/unset → `config.commit` is `null` (local dev, or git unavailable). The source URL itself is `config.sourceCodeUrl` (env `BACKSPACE_SOURCE_URL`, default upstream) — operators running a modified build MUST set it to their fork.
### Run: `docker compose up -d --build`
`docker-compose.yml` defines: