0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 06:24:48 +08:00
discourse/plugins/discourse-calendar/app/views/discourse_post_event/events/index.ics.erb
Bannon Tanner f5203dfcca
FIX: Preserve URI delimiters in ICS URL properties, removing TEXT escaping (#42107)
## Summary

Correctly emit `URL` properties in ICS export without RFC 5545 TEXT
escaping by introducing `IcalEncoder.encode_uri`, which decodes HTML
entities, strips CR/LF characters, and leaves valid URI delimiters such
as commas and semicolons intact. This change is applied to both the
Discourse Events calendar feed and the user bookmarks ICS feed; all
textual properties (`SUMMARY`, `LOCATION`, `DESCRIPTION`) continue to
use the existing TEXT encoder.

## Source

- Patch Triage: https://patch.discourse.org/patch-triage/1547

Co-authored-by: discourse-patch-triage
<272280883+discourse-patch-triage[bot]@users.noreply.github.com>
2026-07-28 14:53:16 -05:00

28 lines
1.4 KiB
Text
Vendored

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Discourse//<%= Discourse.current_hostname %>//<%= Discourse.full_version %>//EN
X-WR-CALNAME:<%= IcalEncoder.encode(@calendar_name) %>
<%- @ics_events.each do |entry| -%>
<%- event = entry[:event] -%>
<%- starts_at = entry[:starts_at] -%>
<%- ends_at = entry[:ends_at] -%>
<%- next if starts_at.nil? -%>
BEGIN:VEVENT
UID:calendar_event_#<%= event.id %>_<%= starts_at.to_i %>@<%= Discourse.current_hostname %>
DTSTAMP:<%= Time.now.utc.strftime("%Y%m%dT%H%M%SZ") %>
<%- if event.all_day -%>
<%- last_day = (ends_at.present? ? ends_at.utc - 1.second : starts_at.utc).to_date -%>
DTSTART;VALUE=DATE:<%= starts_at.utc.strftime("%Y%m%d") %>
DTEND;VALUE=DATE:<%= (last_day + 1).strftime("%Y%m%d") %>
<%- else -%>
DTSTART:<%= starts_at.utc.strftime("%Y%m%dT%H%M%SZ") %>
DTEND:<%= ends_at.presence ? ends_at.utc.strftime("%Y%m%dT%H%M%SZ") : (starts_at + 1.hour).utc.strftime("%Y%m%dT%H%M%SZ") %>
<%- end -%>
SUMMARY:<%= IcalEncoder.encode(event.name.presence || event.post.topic.title) %>
<%- if event.location.present? -%>LOCATION:<%= IcalEncoder.encode(event.location) %>
<%- end -%>
DESCRIPTION:<%= IcalEncoder.encode([(event.description.presence || event.post.excerpt), event.post.full_url].compact.join("\n")) %>
URL:<%= IcalEncoder.encode_uri(event.url.presence || event.post.topic.url(event.post.post_number)) %>
END:VEVENT
<%- end -%>
END:VCALENDAR