Workflow improvements on the invite page and a self-hoster bug fix that affected anyone running calrs without SMTP configured.
Added
- Bulk private invites (closes #58) — the per-recipient invite form is replaced with a paste textarea (one email per line, capped at 100). Each row becomes its own single-use invite token, with a shared optional message and the existing expires/single-use settings. The result page summarizes counts of sent, invalid, duplicate, and failed rows
- Copy-link button on each active sent invite — surfaces the invite URL through the UI so it can be re-shared via Slack, a separate email client, or any out-of-band channel. URL is pre-computed server-side using
CALRS_BASE_URLand the existing team/user route patterns. Hidden on expired and used invites since the link is no longer actionable
Fixed
- Auto-confirm bookings now write back to CalDAV regardless of SMTP availability (closes #65) — across the four booking-creation handlers (
handle_booking_for_user,handle_group_booking,handle_dynamic_group_booking,handle_booking),caldav_push_booking()was nested inside theif let Ok(Some(smtp_config)) = ...block. When SMTP was not configured the entire block was skipped, taking the CalDAV write-back down with it. The host-approval path was already correct, which is why require-confirmation bookings showed in CalDAV but auto-confirm bookings silently didn't. Affected anyone who deployed calrs and tried it before configuring SMTP, which is most first-time self-hosters.BookingDetailsconstruction (and the host-info lookup it depends on) is now hoisted out of the SMTP gate, withcaldav_push_bookingandnotify_watchersrunning as siblings of the SMTP block instead of children.notify_watchersalready self-gated on SMTP for its email part, so its behaviour is unchanged
Internal
- 575 tests total (up from 569 in 1.8.0), all green on pre-commit