this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: include protocol in BaseURL config for SSL support

Updates configuration and templates to include protocol (http/https) in
BaseURL setting, enabling proper SSL support in production while maintaining
HTTP for local development.

Changes:
- Config files now specify full URL with protocol (http://localhost:8080)
- Templates and handlers use BaseURL directly without protocol prefix
- Bookmarklets will work correctly with HTTPS in production
- Fixes modern browser mixed content security issues

This approach makes protocol configuration explicit and environment-specific,
supporting both dev (HTTP) and production (HTTPS) deployments.

+21 -21
+1 -1
conf/config-dev-mysql.yaml
··· 2 2 database: tumble 3 3 username: tumble 4 4 host: 127.0.0.1:13306 5 - baseurl: localhost:8080 5 + baseurl: http://localhost:8080 6 6 mode: dev 7 7 logging: 8 8 level: debug
+1 -1
conf/config-test-mysql.yaml
··· 3 3 username: tumble 4 4 password: password 5 5 host: localhost 6 - baseurl: localhost:8080 6 + baseurl: http://localhost:8080 7 7 port: "8080" 8 8 logging: 9 9 level: debug
+1 -1
conf/config-test.yaml
··· 1 1 driver: sqlite 2 2 database: tumble-test.sqlite 3 3 port: "8080" 4 - baseurl: localhost:8080 4 + baseurl: http://localhost:8080 5 5 logging: 6 6 level: debug 7 7 output: stdout
+2 -2
internal/assets/buttons/button.cgi
··· 31 31 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 32 32 })(); 33 33 </script> 34 - <link rel="stylesheet" href="https://$url/css/screen.css" type="text/css" media="screen" /> 34 + <link rel="stylesheet" href="$url/css/screen.css" type="text/css" media="screen" /> 35 35 </head> 36 36 37 37 <body> ··· 54 54 <div class="tumble_item_ircLink"> 55 55 <div class="tumble_item_top"></div> 56 56 <span class="tumble_item_ircLink_title">); 57 - print qq(Drag this link: <a href="javascript:location.href='https://$url/irclink/?user=$user&source=web&url='+encodeURIComponent(location.href)" onclick="window.alert('No clicky! Drag this link to your Bookmarks toolbar or menu, or right-click it and choose Bookmark This Link...');return false;">post to tumblefish!</a> up to your Bookmarks toolbar or menu.); 57 + print qq(Drag this link: <a href="javascript:location.href='$url/irclink/?user=$user&source=web&url='+encodeURIComponent(location.href)" onclick="window.alert('No clicky! Drag this link to your Bookmarks toolbar or menu, or right-click it and choose Bookmark This Link...');return false;">post to tumblefish!</a> up to your Bookmarks toolbar or menu.); 58 58 print qq(</span> 59 59 <div class="tumble_item_bottom"></div> 60 60 <div>
+1 -1
internal/handler/handlers.go
··· 73 73 if len(l.Title) > 30 { 74 74 l.Title = l.Title[:30] + "..." 75 75 } 76 - content := fmt.Sprintf(`<a href="https://%s/irclink/?%d" target="_blank">%s</a>`, h.Config.BaseURL, l.ID, l.Title) 76 + content := fmt.Sprintf(`<a href="%s/irclink/?%d" target="_blank">%s</a>`, h.Config.BaseURL, l.ID, l.Title) 77 77 data := map[string]interface{}{ 78 78 "Content": template.HTML(content), 79 79 }
+5 -5
internal/service/content.go
··· 130 130 // Detect and hide Imgur placeholder to maintain zero-tolerance requirement 131 131 embed := fmt.Sprintf( 132 132 `<span class="imgur-gallery-card"> 133 - <a href="https://%s/irclink/?%d" target="_blank"> 133 + <a href="%s/irclink/?%d" target="_blank"> 134 134 <span class="gallery-image-container"> 135 135 <img src="%s" 136 136 onload="if(this.naturalWidth===161 && this.naturalHeight===81){this.style.display='none'; this.nextElementSibling.style.display='block';}" ··· 152 152 // No valid preview - gallery is likely deleted/unavailable 153 153 // Render as 404 error with gray link, same as other broken images 154 154 d.Content = template.HTML(fmt.Sprintf( 155 - `<a href="https://%s/irclink/?%d" target="_blank"><span class='http-error-badge'>404</span> <span class='missing-link'>%s</span></a>`, 155 + `<a href="%s/irclink/?%d" target="_blank"><span class='http-error-badge'>404</span> <span class='missing-link'>%s</span></a>`, 156 156 baseURL, item.ID, item.URL)) 157 157 isImgur = true 158 158 d.SuppressOG = true ··· 175 175 // Use visibility toggle pattern (same as gallery) to avoid race conditions 176 176 // Detect Imgur placeholder by dimensions (161x81px) or true 404 errors 177 177 embed := fmt.Sprintf( 178 - `<a href="https://%s/irclink/?%d" target="_blank" style="display: inline-block; position: relative;"> 178 + `<a href="%s/irclink/?%d" target="_blank" style="display: inline-block; position: relative;"> 179 179 <img src="%s" class="imgur-image" 180 180 onload="if(this.naturalWidth===161 && this.naturalHeight===81){this.style.display='none'; this.nextElementSibling.style.display='inline';}" 181 181 onerror="this.style.display='none'; this.nextElementSibling.style.display='inline';" /> ··· 224 224 // If we have an image URL, render inline 225 225 if imgURL != "" { 226 226 embed := fmt.Sprintf( 227 - `<a href="https://%s/irclink/?%d" target="_blank"><img src="%s" style="max-width: 500px;" /></a>`, 227 + `<a href="%s/irclink/?%d" target="_blank"><img src="%s" style="max-width: 500px;" /></a>`, 228 228 baseURL, item.ID, imgURL) 229 229 d.Content = template.HTML(embed) 230 230 isFlickr = true ··· 239 239 240 240 if !isYoutube && !isTwitter && !isImgur && !isFlickr { 241 241 baseURL := s.Config.BaseURL 242 - content := fmt.Sprintf(`<a href="https://%s/irclink/?%d" target="_blank">%s</a>`, baseURL, item.ID, linkFiller) 242 + content := fmt.Sprintf(`<a href="%s/irclink/?%d" target="_blank">%s</a>`, baseURL, item.ID, linkFiller) 243 243 d.Content = template.HTML(content) 244 244 } 245 245
+4 -4
internal/service/content_test.go
··· 11 11 ) 12 12 13 13 func TestProcessIRCLink_Flickr(t *testing.T) { 14 - cfg := &config.Config{BaseURL: "tumble.test"} 14 + cfg := &config.Config{BaseURL: "http://tumble.test"} 15 15 svc := NewContentService(cfg, nil) 16 16 17 17 tests := []struct { ··· 80 80 } 81 81 82 82 func TestProcessImage_Flickr(t *testing.T) { 83 - cfg := &config.Config{BaseURL: "tumble.test"} 83 + cfg := &config.Config{BaseURL: "http://tumble.test"} 84 84 svc := NewContentService(cfg, nil) 85 85 86 86 tests := []struct { ··· 144 144 } 145 145 146 146 func TestProcessIRCLink_Imgur(t *testing.T) { 147 - cfg := &config.Config{BaseURL: "tumble.test"} 147 + cfg := &config.Config{BaseURL: "http://tumble.test"} 148 148 svc := NewContentService(cfg, nil) 149 149 150 150 tests := []struct { ··· 249 249 250 250 // CRITICAL: Verify IRC link handler routing (click tracking) 251 251 if tt.wantIRCLinkHandler { 252 - expectedIRCLink := fmt.Sprintf("https://%s/irclink/?%d", cfg.BaseURL, tt.item.ID) 252 + expectedIRCLink := fmt.Sprintf("%s/irclink/?%d", cfg.BaseURL, tt.item.ID) 253 253 if !strings.Contains(html, expectedIRCLink) { 254 254 t.Errorf("ProcessIRCLink() html should contain IRC link handler %v, got %v", expectedIRCLink, html) 255 255 }
+2 -2
internal/templates/views/index.xml
··· 2 2 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> 3 3 <channel> 4 4 <title>tumblefish.</title> 5 - <link>https://{{.BaseURL}}</link> 6 - <atom:link href="https://{{.BaseURL}}/index.xml" rel="self" type="application/rss+xml" /> 5 + <link>{{.BaseURL}}</link> 6 + <atom:link href="{{.BaseURL}}/index.xml" rel="self" type="application/rss+xml" /> 7 7 <description>tumblefish.</description> 8 8 <language>en-us</language> 9 9 <generator>lsrfsh v2.00</generator>
+2 -2
internal/templates/views/tumble_buttons.html
··· 14 14 })(); 15 15 </script> 16 16 <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" /> 17 - <link rel="stylesheet" href="https://{{.BaseURL}}/css/screen.css" type="text/css" media="screen" /> 17 + <link rel="stylesheet" href="{{.BaseURL}}/css/screen.css" type="text/css" media="screen" /> 18 18 <!-- Theme Init --> 19 19 <script> 20 20 (function () { ··· 55 55 <div class="tumble_item_ircLink"> 56 56 <div class="tumble_item_top"></div> 57 57 <span class="tumble_item_ircLink_title"> 58 - Drag this link: <a href="javascript:location.href='https://{{.BaseURL}}/irclink/?user={{.User}}&source=web&url='+encodeURIComponent(location.href)" onclick="window.alert('No clicky! Drag this link to your Bookmarks toolbar or menu, or right-click it and choose Bookmark This Link...');return false;">post to tumblefish!</a> up to your Bookmarks toolbar or menu. 58 + Drag this link: <a href="javascript:location.href='{{.BaseURL}}/irclink/?user={{.User}}&source=web&url='+encodeURIComponent(location.href)" onclick="window.alert('No clicky! Drag this link to your Bookmarks toolbar or menu, or right-click it and choose Bookmark This Link...');return false;">post to tumblefish!</a> up to your Bookmarks toolbar or menu. 59 59 </span> 60 60 <div class="tumble_item_bottom"></div> 61 61 </div>
+1 -1
internal/templates/views/tumble_item_ircLink.xml
··· 1 1 <item> 2 2 <title>{{.Title}}</title> 3 - <link>https://{{.BaseURL}}/irclink/?{{.ID}}</link> 3 + <link>{{.BaseURL}}/irclink/?{{.ID}}</link> 4 4 <guid isPermaLink="false">tumble-{{.ID}}</guid> 5 5 <description><![CDATA[{{.Content}}]]></description> 6 6 <pubDate>{{.Timestamp}}</pubDate>
+1 -1
internal/templates/views/tumble_item_quote.xml
··· 1 1 <item> 2 2 <title>{{.Quote}}</title> 3 - <link>https://{{.BaseURL}}/</link> 3 + <link>{{.BaseURL}}/</link> 4 4 <guid isPermaLink="false">tumble-quote-{{.ID}}</guid> 5 5 <description>{{.Description}}</description> 6 6 <pubDate>{{.Timestamp}}</pubDate>