Repository navigation
v1.8: multi-user, API tokens, audit log - #337
Merged
Merged
Conversation
test_route_access fails if a new route forgets. Also HealthResponse was stale, so fixed that while I was there.
Migration makes existing users admins. Members get 403 on admin routes and only see source names, and the admin pages are hidden for them. The token carries a session version now so sessions can be ended later.
They're signed with the same key as sessions, and get_current_user never checked what a token was for, so a 60s download token was accepted as a full login. Session tokens now say purpose=session and anything else gets 401. Tokens from before this have no purpose and still work.
New users get a temporary password and can't do anything until they change it, except sign out. Changing your password ends your other sessions and any download links you made. There's an Account page for it, and login records last_login_at.
Run it with docker exec. It switches to the onesearch user first so it doesn't leave root-owned sqlite files behind.
Change role, disable/enable, reset password, delete. You can't do any of that to yourself, and the last active admin can't be removed. That check runs under a write lock now, so two admins demoting each other at once can't leave nobody in charge. begin_immediate moved to app/db/locks.py.
Make them on the Account page. They start with os_, only the hash is kept, and they get 403 on anything that isn't search or opening a document. Works with onesearch login --token as is.
The old one got clipped on the last row and dropped focus on close.
Records sign-ins (failed ones too, with the name tried and the IP) and every user change. Entries are written in the same transaction as the change and every text field is cut to fit, so a weird X-Forwarded-For can't break a login.
Also the 1.8.0 upgrade notes, a locked-out section in troubleshooting, and the changelog entry for the download link fix.
…ntries Settings entries only list which keys changed. Old entries are deleted in batches once a day and at startup; the number of days is a setting.
The rate limit keyed on the leftmost X-Forwarded-For entry, but nginx appends to whatever the client sends, so every request could pick a fresh bucket. Forwarding headers are only trusted from loopback now (the bundled nginx) and the rightmost hop wins. Without SESSION_SECRET, tokens were signed with a string that's sitting in the source. Now a random key is generated on first start and kept in session_secret next to the database. Installs that never set SESSION_SECRET get signed out once on upgrade.
The meilisearch client had no timeout, and the async health route called it directly, so a stuck Meili froze the whole event loop. Requests now time out (5s for health, 30s otherwise) and health runs in a thread. Also in here, all found by the e2e run: - a file that changes and then fails to index no longer matches its old text - camera EXIF fields get read from the Exif sub-IFD, plus GPS from real files - snippets are cut on visible text so a <mark> never gets chopped
Sources page shows reindex/delete errors instead of swallowing them, Status shows Next scan for interval and default schedules, Clear filters actually sticks after a reload, and the header buttons keep their names on a phone. Result cards can be opened from the keyboard.
Pillow gives GPS coordinates back as IFDRational, which can't be serialised, so the batch blew up and took the full reindex with it. Convert them to floats, and check each document serialises before it goes in the batch so one bad file only fails itself.
Revoking your only token used to drop it from the list, and the page went back to "You haven't made any API tokens yet." Both lists (your own and the admin view) now return every token with a status and revoked_at, and the UI greys out revoked/expired rows with the date.
The header had Account, Admin, your name and Logout on search pages, and Back to Search on admin pages with no Account at all. Now it's the gear (Settings) and Logout everywhere. Inside, Account comes first in the sidebar. Members get Account plus their browser-side Appearance and Search settings, admins get Account plus everything they had before. AdminLayout is renamed to SettingsLayout, and the docs say Settings instead of Admin.
- Account lines up with the other settings pages instead of sitting in a narrow centred column, and the token table stops wrapping headers - the gear goes to Account for everyone (it used to send admins to Sources, which didn't match the "Settings" label) - Results per page gets a 20 option, since 20 is the default - document dates don't wrap mid-value, and task lists lose the extra bullet
GFM renders them disabled and the browser greys disabled checkboxes out, so done items looked faded. They're read-only now instead, in the brand colour. Also lines up the password card with the token card on Account.
Used to be top only, so you had to scroll back up after reading a page. Pulled the pager into one TextPager component and render it top and bottom; the bottom one scrolls you back to the start of the new page. closes #333
They start the backend without SESSION_SECRET, so on CI (no .env) it tried to write the key to /app/data and blew up.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is 1.8. The big one is multi-user: admin and member roles, the Account page, search-only API tokens for scripts, and an audit log. There's also a reset-password command for when you get locked out.
Some fixes went in along the way. Sign-in rate limiting could be bypassed with a fake X-Forwarded-For header, and the fallback session key was hardcoded. Those two are security fixes and have their own commit. The health check could hang forever when Meili stopped responding, EXIF exposure/lens/GPS was mostly missing, and
--jsonoutput from the CLI could break when piped. Plus some document page polish: a pager under long text, the metadata card collapsed by default, the extension always shown, and readable task checkboxes.Upgrading from 1.7 needs nothing if SESSION_SECRET is set. Without it, people get signed out once. The changelog has the full list.
closes #332, closes #333, closes #334, closes #335, closes #336