feat: publish local calendars via two-way CalDAV (opt-in, secret token URL)
Backend:
- LocalCalendar gains caldav_published + dav_token + dav_ctag; LocalEvent gains
etag (migrations in main.py). bump_dav() refreshes ctag/etag on every local
event write (create/update/delete/import).
- local_router: PUT /calendars/{id} accepts caldav_published (mints/revokes
token), new POST /calendars/{id}/dav-token/rotate, _cal_dict exposes
caldav_published + caldav_url.
- New dav_router mounted at root (/dav/{token}/...): a minimal two-way CalDAV
server (OPTIONS/PROPFIND/REPORT/GET/PUT/DELETE) reusing ical_io build/parse,
ctag-based change detection. Secret token = auth, no login.
Frontend:
- Settings calendar table: per-local-calendar publish toggle + subscribe URL
with copy and token-rotate; i18n (de/en) and styling.
Note: reverse proxy must allow WebDAV methods (PROPFIND/REPORT/PUT/DELETE).
VALARM/reminders are not round-tripped via CalDAV.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1462,6 +1462,16 @@ a { color: var(--primary); text-decoration: none; }
|
||||
.ct-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; margin-right: 5px; vertical-align: middle; flex-shrink: 0; }
|
||||
.ct-empty { color: var(--text-3); font-size: 13px; padding: 16px 0; text-align: center; }
|
||||
.ct-toggle { cursor: pointer; }
|
||||
.ct-dav-toggle.on { color: var(--primary); }
|
||||
.ct-dav-row td { padding-top: 4px; padding-bottom: 12px; }
|
||||
.ct-dav-box { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.ct-dav-label { font-size: 12px; color: var(--text-3); }
|
||||
.ct-dav-url {
|
||||
flex: 1; min-width: 220px; font-size: 12px; padding: 5px 8px;
|
||||
border: 1px solid var(--border); border-radius: 6px;
|
||||
background: var(--surface-2); color: var(--text-1);
|
||||
}
|
||||
.ct-dav-hint { font-size: 11px; color: var(--text-3); margin-top: 6px; max-width: 640px; }
|
||||
.ct-eye, .ct-bell { opacity: .45; transition: opacity .15s; }
|
||||
.ct-eye[data-ct-visible="1"], .ct-bell[data-ct-on="1"] { opacity: 1; }
|
||||
.ct-eye:hover, .ct-bell:hover { opacity: 1; }
|
||||
|
||||
Reference in New Issue
Block a user