From 86cf4ccba7b306bfc81d3707801739f8f4bef3ac Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 22 Nov 2024 11:23:15 +1100 Subject: [PATCH] FIX: automatically bust cache for share ai assets (#942) * FIX: automatically bust cache for share ai assets CDNs can be configured to strip query params in Discourse hosting. This is generally safe, but in this case we had no way of busting the cache using the path. New design properly caches and properly breaks busts the cache if asset changes so we don't need to worry about versions * one day I will set up conditional lint on save :) --- .../shared_ai_conversations_controller.rb | 27 +++++++++++++++++- .../ai_bot/shared_ai_conversations_helper.rb | 28 +++++++++++++++---- .../shared_ai_conversations/show.html.erb | 4 +-- config/routes.rb | 1 + plugin.rb | 4 +++ ...hared_ai_conversations_controller_spec.rb} | 24 ++++++++++++++++ 6 files changed, 79 insertions(+), 9 deletions(-) rename spec/requests/ai_bot/{shared_ai_conversations_spec.rb => shared_ai_conversations_controller_spec.rb} (94%) diff --git a/app/controllers/discourse_ai/ai_bot/shared_ai_conversations_controller.rb b/app/controllers/discourse_ai/ai_bot/shared_ai_conversations_controller.rb index 6308fbd4..f58d350c 100644 --- a/app/controllers/discourse_ai/ai_bot/shared_ai_conversations_controller.rb +++ b/app/controllers/discourse_ai/ai_bot/shared_ai_conversations_controller.rb @@ -7,7 +7,8 @@ module DiscourseAi requires_login only: %i[create update destroy] before_action :require_site_settings! - skip_before_action :preload_json, :check_xhr, only: %i[show] + skip_before_action :preload_json, :check_xhr, only: %i[show asset] + skip_before_action :verify_authenticity_token, only: ["asset"] def create ensure_allowed_create! @@ -50,6 +51,30 @@ module DiscourseAi end end + def asset + no_cookies + + name = params[:name] + path, content_type = + if name == "share" + %w[share.css text/css] + elsif name == "highlight" + %w[highlight.min.js application/javascript] + else + raise Discourse::NotFound + end + + content = File.read(DiscourseAi.public_asset_path("ai-share/#{path}")) + + # note, path contains a ":version" which automatically busts the cache + # based on file content, so this is safe + response.headers["Last-Modified"] = 10.years.ago.httpdate + response.headers["Content-Length"] = content.bytesize.to_s + immutable_for 1.year + + render plain: content, disposition: :nil, content_type: content_type + end + def preview ensure_allowed_preview! data = SharedAiConversation.build_conversation_data(@topic, include_usernames: true) diff --git a/app/helpers/discourse_ai/ai_bot/shared_ai_conversations_helper.rb b/app/helpers/discourse_ai/ai_bot/shared_ai_conversations_helper.rb index 6d064683..6fb89d58 100644 --- a/app/helpers/discourse_ai/ai_bot/shared_ai_conversations_helper.rb +++ b/app/helpers/discourse_ai/ai_bot/shared_ai_conversations_helper.rb @@ -2,13 +2,29 @@ module DiscourseAi module AiBot module SharedAiConversationsHelper - # bump up version when assets change - # long term we may want to change this cause it is hard to remember - # to bump versions, but for now this does the job - VERSION = "1" + # keeping it here for caching + def self.share_asset_url(asset_name) + if !%w[share.css highlight.js].include?(asset_name) + raise StandardError, "unknown asset type #{asset_name}" + end - def share_asset_url(short_path) - ::UrlHelper.absolute("/plugins/discourse-ai/ai-share/#{short_path}?#{VERSION}") + @urls ||= {} + url = @urls[asset_name] + return url if url + + path = asset_name + path = "highlight.min.js" if asset_name == "highlight.js" + + content = File.read(DiscourseAi.public_asset_path("ai-share/#{path}")) + sha1 = Digest::SHA1.hexdigest(content) + + url = "/discourse-ai/ai-bot/shared-ai-conversations/asset/#{sha1}/#{asset_name}" + + @urls[asset_name] = GlobalPath.cdn_path(url) + end + + def share_asset_url(asset_name) + DiscourseAi::AiBot::SharedAiConversationsHelper.share_asset_url(asset_name) end end end diff --git a/app/views/discourse_ai/ai_bot/shared_ai_conversations/show.html.erb b/app/views/discourse_ai/ai_bot/shared_ai_conversations/show.html.erb index b72ea2b5..2981ab13 100644 --- a/app/views/discourse_ai/ai_bot/shared_ai_conversations/show.html.erb +++ b/app/views/discourse_ai/ai_bot/shared_ai_conversations/show.html.erb @@ -10,7 +10,7 @@ "> - "> + ">