Scoped API tokens for the random endpoint, with a management page
Backend: a GreetingToken model stores only a SHA-256 hash of a j621r_…
key (shown once at creation) plus label, prefix, created/last-used. A
dedicated GreetingTokenAuthentication understands the usual
'Authorization: Token …' header but is registered only on RandomItemView
(alongside the normal token auth), so a greeting token authenticates
/api/random/ and is rejected with 401 everywhere else — exactly the scope
shell greetings need. Endpoints: GET/POST /api/auth/greeting-tokens/ and
DELETE /api/auth/greeting-tokens/{id}/ (own tokens only; the list never
returns keys or hashes).
Frontend: /tokens page (Account → Shell tokens card, command palette entry)
lists tokens with label, prefix, created/last-used and revoke (shared
confirm dialog). Creating one shows the key with Copy and 'Copy for fish'
buttons plus a pointer to extras/fish_greeting.
Tests: apps/accounts/tests/test_greeting_tokens.py — 9 tests covering
create-once semantics and hashing, hidden keys in listings, the scope
guarantee (random 200 with a signed URL; 401 on files, storage, me, tags
cloud, delete and the token list itself), unknown/revoked keys, cross-user
revocation, last-used tracking and label limits.
Verified live: created a token, rolled /random (signed URL), got 401 from
four other endpoints, saw the list omit secrets, revoked it (204) and the
same key then 401'd on /random. Full suite: 39 tests green.
This commit is contained in:
@@ -27,7 +27,22 @@ cd extras/fish_greeting
|
||||
fish install.fish
|
||||
```
|
||||
|
||||
Then edit `~/.config/j621Greeting/config.fish` (at least `J621_BASE`) and test:
|
||||
The installer copies the function into `~/.config/fish/functions/`, **asks for
|
||||
your API origin** (and an optional scoped token — see below), writes
|
||||
`~/.config/j621Greeting/config.fish` (mode 600, it may hold the token), checks
|
||||
the tools it needs and then verifies the backend: `/health` must answer and a
|
||||
random roll is attempted. It exits non-zero when the backend cannot be
|
||||
reached.
|
||||
|
||||
Non-interactive / re-install:
|
||||
|
||||
```fish
|
||||
fish install.fish --url https://j621.example.ts.net --token <api-token>
|
||||
fish install.fish --no-prompt # defaults, never asks
|
||||
fish install.fish --force # rewrite an existing config
|
||||
```
|
||||
|
||||
Then test:
|
||||
|
||||
```fish
|
||||
fish_greeting
|
||||
@@ -37,6 +52,14 @@ Requirements: `curl` (or `wget`), `fastfetch`, `file`. Optional: `gifsicle`
|
||||
(GIF downscaling), `jq` or `python3` (JSON parsing — without either it falls
|
||||
back to grep/sed).
|
||||
|
||||
## No token? That is fine
|
||||
|
||||
The greeting is meant to run **without** a token: it then behaves like a
|
||||
guest of your instance — unsigned image links and only items that are visible
|
||||
to guests. Adding a token to the config unlocks signed links (useful when
|
||||
something else fetches the URL for you) and items that are hidden from
|
||||
guests.
|
||||
|
||||
## Configuration
|
||||
|
||||
Any of these work; the config file is read by the function on every run:
|
||||
@@ -49,10 +72,12 @@ set -g J621_TOKEN <api token> # signed URLs + hidden it
|
||||
set -g J621_FASTFETCH_CONFIG jake # fastfetch config name
|
||||
```
|
||||
|
||||
`J621_TOKEN` is the same token the SPA uses (`Authorization: Token …`). With
|
||||
it the API signs the image URL for your account, so you also get items that
|
||||
are hidden from guests. Without it the greeting runs as a guest and sees the
|
||||
public library only.
|
||||
`J621_TOKEN` is optional. The recommended value is a **scoped greeting
|
||||
token**: open the app, go to *Account → Shell tokens* (or `/tokens`), create
|
||||
one and copy the `j621r_…` key — it only works with `/api/random/`, so it is
|
||||
safe to keep in this config. It also gives you signed image URLs and access
|
||||
to items that are hidden from guests. Without a token the greeting runs as a
|
||||
guest and sees the public library only.
|
||||
|
||||
## Rating filters
|
||||
|
||||
|
||||
Reference in New Issue
Block a user