Address CodeRabbit review on the live-lookup change:
- Resolve the redirect URI live in LoginURL and return it so the caller
persists it in the session; ExchangeOIDCToken reuses that stored value
instead of resolving again. The token exchange redirect_uri must match
the one in the auth request (RFC 6749 4.1.3); resolving twice would let
a Root URL change between login and callback produce a mismatch the IdP
rejects.
- Propagate the redirect URL resolution error out of LoginURL rather
than discarding it, so a setting read failure fails the login loudly
instead of sending an empty redirect_uri.
- Pass rootURL as a formatting argument in oidc.RedirectURL instead of
concatenating it into the format string, so a root URL containing a
%-sequence (e.g. %2F) is not interpreted as a verb.
Auth providers captured the redirect URL as a string at build time, so
changing app.root_url in General settings left OIDC providers sending
the old redirect_uri until the process restarted. The identity provider
then rejected login with "redirect_uri is missing in the client
configuration" even though the database and the IdP client both held the
right value.
Make auth.Provider.RedirectURL a closure and resolve it in LoginURL and
ExchangeOIDCToken from the current root URL, matching the media store's
existing rootURL closure. The redirect URL is computed by a new
oidc.Manager.RedirectURL(id) helper so the path format stays in one
place. Other provider fields (client ID, provider URL) remain snapshotted
and are refreshed by reloadAuth on OIDC changes, as before.
This removes the reload requirement for Root URL entirely; the settings
handler no longer needs to know that auth depends on it.
Final review pass before taking the AI agent branch live.
Knowledge base:
- Text not wrapped in a block tag was never collected, so prose around a
table or list never reached the index. The assistant answered "no
relevant information" for questions the snippet covered.
- Blocks over the token limit were truncated and the remainder dropped. They
are split into several chunks now.
- Trimming an oversized block ran one rune at a time and re-tokenized the
whole string each step. A large table took minutes. It uses a binary
search now.
- Overlap text was not escaped, so a sentence containing markup swallowed
the rest of the chunk.
- SVG and template text no longer reaches the index.
AI agent:
- Verification codes are capped per address and per conversation. The cap
was per conversation only, so a customer correcting a mistyped email was
told to check an inbox that never got a code.
- Livechat verification sends synchronously. A queued send returned nil even
when SMTP failed, so a failure counted as a sent code.
- Queued jobs drain on shutdown and hand off to a human instead of being
dropped with no reply.
- Deleting an assistant no longer moves resolved and closed conversations
into the fallback team.
- Image decode is capped at 25 MP. The old bound allowed a 400 MB decode per
attachment.
Auth and admin:
- A blank OIDC client secret no longer overwrites the stored one. Blank id
or secret is rejected instead.
- OIDC token exchange uses the SSRF guarded client with a timeout.
- Renaming a tool auth header no longer attaches the secret of whichever row
now sits at that position.
- Clearing embedding dimensions no longer refills 1536 on the next load,
which pushed a wrong value to the provider on the next save.
- Copilot conversation lookups filter by access before capping at 10.
handleAiPromptSelected now captures the conversation uuid and bails if it changed while the completion was in flight, and uses convertTextToHtml with a null guard, matching handleGenerateReply. This stops a generated prompt from landing in the wrong conversation's draft or crashing on an empty response.
Add ssrf.NewTransport that clones http.DefaultTransport (keeping proxy and connection-pool defaults) and applies the dial guard, then use it for the OIDC, AI, OpenAI, and webhook clients. The bare transports were dropping HTTP_PROXY handling and pool defaults.
The earlier SSRF work covered the provider, custom-tool, webhook, and OIDC
outbound calls but missed the knowledge base URL import path, which still used
http.DefaultClient. An admin importing a URL could reach loopback, link-local,
or RFC1918 hosts. Renamed the Manager's toolClient to httpClient (it is a
general SSRF-guarded outbound client now) and pointed fetchURL at it. The guard
sits on the dialer's Control, so it also runs on redirect targets, not just the
first hop.
Also fixed the OIDC discovery client. Its hand-built transport dropped two
defaults that http.DefaultTransport sets. Added Proxy: http.ProxyFromEnvironment
so it honors HTTP_PROXY/HTTPS_PROXY (SSO discovery now works behind an egress
proxy) and ForceAttemptHTTP2 so HTTP/2 is negotiated.
Move the webhook SSRF guard into a shared internal/ssrf package and wire it
into every place the server fetches an admin-set URL: webhooks, OIDC discovery,
the AI provider base URL, and custom AI tool calls. Add a global [ssrf] config
block, off by default with an allowed_cidrs bypass, so single-tenant self-hosters
keep reaching internal hosts while multi-tenant or hosted deploys can turn it on.
The old [webhook] allowed_hosts key is still read for backward compat and folds
into the guard.
- feat: new flag for idempotent installation `--idempotent-install`
- feat: new flag to skip yes/no prompt `--yes`
- feat: new flag for upgrades `--upgrade`
- refactor: update doc strings and sample toml file.
- chore: update .gitignore.
- feat: adds filters support on conversations list
- refactor middlewares.go
- Adds new paginate.go for generating filtered paginated SQL queries this removes sql generation code from the conversations package.
- rename some components
- removes hardcoded `/uploads/`
- adds /compact apis for fetching teams and users
- adds form field to allow admin to set user password.
- fix: inline images for incoming email.
- save content id & disposition for each media.
- Update to schema.sql
- fixes issues in auth redirect to login, by making simple session cookie auto create = true.
- fixes issues with conversation tab filters WS subscription.
- fixes nulls returned for empty team list in handlers
- fixes logout btn not working.
- fixes charts error when there's no data returned from the API.
- Updates schema.sql