diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2025-01-26 00:29:46 +0000 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2025-01-26 00:29:46 +0000 |
| commit | dd49c9205bb04844b686b9c3396c40eb49d25826 (patch) | |
| tree | babd1d90a939a7928ef02e9656ddf6ee22104f92 | |
| parent | 0d0a02766a59729f61c48f00e71bdae91ed64482 (diff) | |
Add alarms to calendar events
| -rw-r--r-- | api/handlers/ical.go | 1 | ||||
| -rw-r--r-- | api/router.go | 16 | ||||
| -rw-r--r-- | pkg/ical/service.go | 37 |
3 files changed, 40 insertions, 14 deletions
diff --git a/api/handlers/ical.go b/api/handlers/ical.go index c4b3989..52dfcdb 100644 --- a/api/handlers/ical.go +++ b/api/handlers/ical.go @@ -38,6 +38,7 @@ func GetIcal(icalService ical.Service, calendarService calendar.Service) fiber.H return err } + c.Set("Content-Type", "text/calendar") return c.SendString(ical) } } diff --git a/api/router.go b/api/router.go index dc7e487..99c79c7 100644 --- a/api/router.go +++ b/api/router.go @@ -1,6 +1,8 @@ package api import ( + "crypto/rand" + "encoding/hex" "errors" "log/slog" "time" @@ -27,9 +29,11 @@ type ApiServices struct { func NewServer(apiServices ApiServices, baseURL string) *fiber.App { sessionStore := session.New(session.Config{ - Expiration: 24 * time.Hour, + Expiration: 7 * 24 * time.Hour, + KeyGenerator: generateSessionToken, KeyLookup: "cookie:confplanner_session", - CookieSameSite: "None", + CookieSameSite: "Strict", + CookieSecure: true, }) app := fiber.New(fiber.Config{ @@ -74,3 +78,11 @@ func NewServer(apiServices ApiServices, baseURL string) *fiber.App { return app } + +func generateSessionToken() string { + b := make([]byte, 100) + if _, err := rand.Read(b); err != nil { + return "" + } + return hex.EncodeToString(b) +} diff --git a/pkg/ical/service.go b/pkg/ical/service.go index a90183f..d93c846 100644 --- a/pkg/ical/service.go +++ b/pkg/ical/service.go @@ -2,6 +2,7 @@ package ical import ( "errors" + "strconv" "strings" "time" @@ -48,26 +49,38 @@ func (s *service) GenerateIcalForCalendar(calendar sqlc.Calendar) (string, error } now := time.Now() + counter := 0 // https://www.rfc-editor.org/rfc/rfc5545.html - ret := "BEGIN:VCALENDAR\n" - ret += "VERSION:2.0\n" - ret += "METHOD:PUBLISH\n" - ret += "X-WR-CALNAME:confplanner calendar\n" + ret := "BEGIN:VCALENDAR\r\n" + ret += "PRODID:-//LMBishop//confplanner//EN\r\n" + ret += "VERSION:2.0\r\n" + ret += "METHOD:PUBLISH\r\n" + ret += "X-WR-CALNAME:confplanner calendar\r\n" for _, event := range events { utcStart := event.Start.UTC() utcEnd := event.End.UTC() - ret += "BEGIN:VEVENT\n" - ret += "SUMMARY:" + event.Title + "\n" - ret += "DTSTART:" + utcStart.Format("20060102T150405Z") + "\n" - ret += "DTEND:" + utcEnd.Format("20060102T150405Z") + "\n" - ret += "LOCATION:" + event.Room + "\n" - ret += "DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + bluemonday.StrictPolicy().Sanitize(strings.Replace(event.Abstract, "\n", "\\n", -1)) + "\\n\\nconfplanner: last synchronised: " + now.Format(time.RFC1123) + "\n" - ret += "END:VEVENT\n" + ret += "BEGIN:VEVENT\r\n" + ret += "SUMMARY:" + event.Title + "\r\n" + ret += "UID:" + now.Format("20060102T150405Z") + "-" + strconv.Itoa(counter) + "\r\n" + ret += "DTSTAMP:" + now.Format("20060102T150405Z") + "\r\n" + ret += "DTSTART:" + utcStart.Format("20060102T150405Z") + "\r\n" + ret += "DTEND:" + utcEnd.Format("20060102T150405Z") + "\r\n" + ret += "LOCATION:" + event.Room + "\r\n" + ret += "DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + bluemonday.StrictPolicy().Sanitize(strings.Replace(event.Abstract, "\n", "\\n\\n", -1)) + "\\n\\nconfplanner: last synchronised: " + now.Format(time.RFC1123) + "\r\n" + + ret += "BEGIN:VALARM\r\n" + ret += "TRIGGER:-PT10M\r\n" + ret += "ACTION:AUDIO\r\n" + ret += "END:VALARM\r\n" + + ret += "END:VEVENT\r\n" + + counter++ } - ret += "END:VCALENDAR\n" + ret += "END:VCALENDAR\r\n" return ret, nil } |
