Commit Graph
9 Commits
Author SHA1 Message Date
clawbot b9ec91c0f7 Use one name for each thing the UI shows (closes #399)
check / check (push) Successful in 3m21s
The UI gave one thing several names. The `database` type is now Archive in the type list, on its badge and on the edit page, and its settings read "Archive expiry" and "Archive rotation" everywhere. The retry field is "Delivery attempts", with help text, errors and the target list saying it counts every attempt; a stored 0 shows as one attempt. The target list uses one capitalisation. The navbar says "Sign out", the sign-in page "Sign in", and the resubmit notice "webhook" instead of "source". The README follows. Stored values, their meaning, routes and form field names are unchanged.

Model: opus-5-5
2026-10-03 05:07:41 +02:00
clawbot 8b617efa63 Rotate a database target's archive monthly, daily or hourly (closes #379)
check / check (push) Successful in 3m27s
A database target's rotation setting (none, monthly, daily or hourly) puts the UTC period of each event's receive time in its archive file name, so each file holds exactly its period's events. It is on the new webhook page and both target forms, and shown in the target list. Renames move every one of a target's files and move them all back if one fails. The sweep prunes one file at a time under the target's lock and deletes a rotated file it leaves empty. Download opens one file at a time, oldest period first, finding each again under the target's current name. The target list names the current file and totals all of them.

Model: opus-5-5
2026-10-03 04:18:37 +02:00
clawbot 22fa502638 Remove an http target's max_queue_size (closes #477)
check / check (push) Successful in 3m18s
An http target's max_queue_size was stored and shown in the target list as "Max Queue Size", but nothing in the delivery engine read it, so an operator who set it expecting deliveries to be bounded got nothing. It is removed from the target, the target list and the README's target table; neither form had a field for it. Nothing checks for a leftover value. An existing database keeps its old column, which is no longer read.

Model: opus-5-5
2026-10-03 01:39:13 +02:00
clawbot 3489d6909a Offer archive expiry choices on the target forms, show plain units (closes #396)
check / check (push) Successful in 3m11s
A database target's archive expiry was typed by hand as never or a raw duration such as 720h, and the target list showed it back raw. Adding or editing a database target now offers the new-webhook page's list of choices (never, 1h, 12h, 24h, 30d, 90d, 365d), defined once and shared by all three forms. The edit form starts on the stored expiry, or on the submitted one after a refused save; a stored value outside the choices is listed under its own value, so saving unchanged keeps it. The target list shows the expiry in plain units: "30 days", "12 hours", "never".

Model: opus-5-5
2026-10-03 01:16:14 +02:00
clawbot 93911f28f9 Show a slack target's retry setting in the target list (closes #395)
check / check (push) Successful in 3m24s
A slack target's edit page offers Max Retries and the delivery engine honours it, but the target list showed only its masked webhook URL, so setting retries changed nothing visible. The list now shows a slack target's Max Retries line exactly as an http target's, from the one function both use, so the label and the "0 (fire-and-forget)" wording cannot drift apart. The Max Queue Size line stays on http targets only. Tests cover a slack target with retries set, and one with a queue size stored that shows no queue-size line.

Model: opus-5-5
2026-10-03 00:19:13 +02:00
clawbot 5fda446c71 Name a deleted target on its historical deliveries (closes #211)
check / check (push) Successful in 3m13s
2026-08-24 02:03:23 +02:00
clawbot 9ae19159a3 Mask the http target's destination URL in the UI (closes #115)
check / check (push) Superseded by a newer commit; never tested
The http target's destination URL can itself be a bearer credential, and
the source detail page rendered it in full. Render it through the
existing MaskURL instead, matching the rule already applied to slack
targets.

Independently reviewed: mutation-verified (reverting to the raw value
fails the absence assertions, not merely the masked-form ones), MaskURL
probed against userinfo, query, fragment, port, IPv6 literal and
non-http schemes, and every sibling path that surfaces target data
re-walked and found clean.
2026-08-17 22:50:26 +02:00
clawbot 7c43e095a6 Mask the webhook credential in delivery errors and logs (closes #118)
check / check (push) Successful in 9s
Go embeds the request URL in *url.Error, so any transport failure — DNS,
TLS, refused, timeout, SSRF dial block — persisted the full Slack webhook
URL into the per-webhook SQLite database via DeliveryResult.Error. That
field is tagged json:"error,omitempty", so a future REST API would have
served it.

maskURLError rebuilds the error preserving Op and the wrapped cause, so DNS
vs TLS vs timeout still read differently and errors.Is/As and Timeout()
keep working; only path, query and userinfo are dropped. Applied where the
errors are born, which covers both the Slack and HTTP targets. url.Parse
embeds the URL too, so ValidateTargetURL's parse branch gets the same
treatment.

The SSRF rejection log now logs the masked URL, and source_logs.html
receives view types rather than raw rows, so no config blob is reachable
from that template.

MaskURL is now the single masker for the whole tree.
2026-08-11 15:11:57 +02:00
clawbot 15a61173fc Mask target config on the source detail page (closes #113)
check / check (push) Superseded by a newer commit; never tested
The page rendered the stored target config verbatim, exposing the Slack
incoming-webhook URL, which is a bearer credential: anyone holding it can
post to the channel indefinitely, and it cannot be scoped or revoked
per-holder.

Target config now reaches the template only as a TargetView carrying
labelled fields, so no code path can render the raw blob. maskURL keeps
scheme and host and elides the path, and drops query, fragment and
userinfo; every parse failure yields a neutral placeholder rather than
falling back to the stored string. HTTP header values are never rendered,
only a count.

Rendering change only: the stored config format and the delivery path are
unchanged.
2026-08-11 14:37:09 +02:00