Each account may store 5 GB of attachments; admins have no limit
CI & Build / Build now, or wait for Android? (push) Successful in 3s
Android / Build, or is the channel already serving this? (push) Successful in 4s
Android / Core and FFI clippy and tests (push) Skipped
Android / Kotlin + Rust (APK) (push) Skipped
Android / Build the server image (push) Skipped
CI & Build / Python lint (push) Successful in 2s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / Web typecheck and unit tests (push) Successful in 10s
CI & Build / Python tests (push) Successful in 12s
CI & Build / integration (push) Successful in 1m33s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Successful in 2m12s
CI & Build / Build & push image (push) Successful in 55s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m43s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m32s
Desktop (Tauri) / Update manifest (push) Successful in 5s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
Android / Build, or is the channel already serving this? (push) Successful in 4s
Android / Core and FFI clippy and tests (push) Skipped
Android / Kotlin + Rust (APK) (push) Skipped
Android / Build the server image (push) Skipped
CI & Build / Python lint (push) Successful in 2s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / Web typecheck and unit tests (push) Successful in 10s
CI & Build / Python tests (push) Successful in 12s
CI & Build / integration (push) Successful in 1m33s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Successful in 2m12s
CI & Build / Build & push image (push) Successful in 55s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m43s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m32s
Desktop (Tauri) / Update manifest (push) Successful in 5s
#2939 §4. max_attachment_mb capped one file, so any account could fill the
volume. The new Settings → Attachments → storage_quota_gb (default 5, 0 for
no limit) caps an account's total. That total is every attachment on every
note the account owns, trash included, since trashed files stay on disk until
emptied. Admins are exempt.
storage.upload_refusal is now the one check every upload makes: per file, then
per account. It is used by:
- the web upload route;
- the sync PUT, which judges the declared Content-Length before reading the
bytes;
- the importer, which learns the room left up front and refuses the whole
archive if its attachments don't fit (nothing is committed).
Over the limit is answered 507 Insufficient Storage, not 413. The core treats
a 4xx as a permanent refusal it never retries, and a 5xx as worth another try.
So a file refused for want of room syncs by itself once space is freed. The
cost is that an over-limit device re-sends that file each cycle until then.
GET /api/auth/storage returns used and limit, and the Account page shows it as
a Storage row ("1.2 GB of 5 GB used").
docs/public-hosting.md drops the quota gap and gains a section on the limit.
Its Android paragraph still said a public http:// address was only warned
about; since 1dd6fc1 it is refused, and the paragraph now says so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+16
-5
@@ -143,6 +143,17 @@ at the same speed, whether or not an address has an account, and
|
||||
`reset_emails_per_account` (Settings → Security) caps how many reset emails one
|
||||
address can be sent.
|
||||
|
||||
## Storage per account
|
||||
|
||||
Each account may store up to `storage_quota_gb` of attachments (Settings →
|
||||
Attachments, 5 GB by default; 0 means no limit). Admins have no limit. Trashed notes
|
||||
count until the trash is emptied, because their files are still on disk. An upload
|
||||
past the limit is refused with 507 Insufficient Storage, and a phone or desktop
|
||||
retries that file on each sync, so it goes through once there is room. The Account
|
||||
page shows how much an account uses.
|
||||
|
||||
`max_attachment_mb` still caps any single file.
|
||||
|
||||
## What it does not do
|
||||
|
||||
Know these before you decide who gets an account.
|
||||
@@ -154,8 +165,6 @@ Know these before you decide who gets an account.
|
||||
- **An admin who forgets their own password**, with email off and no other admin,
|
||||
still needs a hand on the database.
|
||||
- **No second factor.** A password is the whole of it.
|
||||
- **No per-user storage quota.** Any account can upload attachments until the volume
|
||||
is full. `max_attachment_mb` caps a single file, not a total.
|
||||
- **No audit TABLE.** Credential events — sign-ins, failures, throttle trips, new
|
||||
accounts, device tokens issued — are written to the application log and readable
|
||||
with `docker compose logs app`, which is enough to see whether anyone is knocking.
|
||||
@@ -170,9 +179,11 @@ know. They are the reason not to hand out open registration to strangers.
|
||||
The app allows plain HTTP so a self-hosted server on a LAN is usable at all — Android
|
||||
blocks cleartext by default from API 28, and `http://192.168.1.10:8000` is exactly the
|
||||
case Inkwell is built for. Over the public internet, link the phone to the
|
||||
**HTTPS** hostname. The sync screen shows a warning before any credential field
|
||||
whenever the address it probed was `http://`; on a public network that warning means
|
||||
what it says.
|
||||
**HTTPS** hostname. The phone and desktop apps refuse a plain `http://` address that
|
||||
isn't on a private network, before any password or token is sent. Allowed: private
|
||||
and Tailscale IPs, single-label names like `nas`, and LAN names such as `.local` or
|
||||
`.home.arpa`. A device already linked to a public `http://` address stops syncing
|
||||
and says why.
|
||||
|
||||
The APK the server hands out is signed with the project release key, and the in-app
|
||||
updater installs over the existing app only because the signature matches. A build
|
||||
|
||||
Reference in New Issue
Block a user