escape more things

This commit is contained in:
Echo 2025-07-02 19:37:03 -04:00
parent ee81f3fbe0
commit 0cea69daed
No known key found for this signature in database
8 changed files with 29 additions and 20 deletions

View file

@ -186,12 +186,21 @@ export default class extends Controller {
const v = p.repo_url ?
p.repo_url.replace(/^https:\/\/github\.com\//, 'https://tkww0gcc0gkwwo4gc8kgs0sw.a.selfhosted.hackclub.com/') : ''
const out = this.esc(p.name)
return `
<div class="text-sm italic text-muted ml-2">
working on
${p.repo_url ? `<a href="${p.repo_url}" target="_blank" class="text-accent hover:text-cyan-400 transition-colors">${p.name}</a>` : p.name}
${p.repo_url ? `<a href="${p.repo_url}" target="_blank" class="text-accent hover:text-cyan-400 transition-colors">${out}</a>` : out}
${v ? `<a href="${v}" target="_blank" class="ml-1">🌌</a>` : ''}
</div>
`
}
esc(str) {
if (str === null || str === undefined) return '';
return str.toString().replace(/[&<>"']/g, function (match) {
return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[match];
});
}
}

View file

@ -30,7 +30,7 @@
<tr class="hover:bg-darkless">
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-white">
<%= api_key.name %>
<%= h(api_key.name) %>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
@ -39,7 +39,7 @@
<img class="h-6 w-6 rounded-full mr-2" src="<%= api_key.user.avatar_url %>" alt="">
<% end %>
<div>
<div class="text-sm text-white"><%= api_key.user.display_name %></div>
<div class="text-sm text-white"><%= h(api_key.user.display_name) %></div>
<div class="text-xs text-gray-400">ID: <%= api_key.user.id %></div>
</div>
</div>

View file

@ -167,7 +167,7 @@
<div class="absolute top-0 p-3 rounded-lg shadow-lg <%= trust_level_bg %>"
data-user-id="<%= user.id %>"
style="left: <%= column_left + 2 %>px; width: <%= min_column_width_px - 4 %>px;"
title="User ID: <%= user.id %> - <%= user.respond_to?(:username) && user.username.present? ? user.username : user.email_addresses.first&.email %> | Total Coded: <%= total_coded_time_seconds && total_coded_time_seconds > 0 ? short_time_detailed(total_coded_time_seconds) : '0m' %> | TZ: <%= user.timezone %>">
title="User ID: <%= user.id %> - <%= user.respond_to?(:username) && user.username.present? ? h(user.username) : h(user.email_addresses.first&.email) %> | Total Coded: <%= total_coded_time_seconds && total_coded_time_seconds > 0 ? short_time_detailed(total_coded_time_seconds) : '0m' %> | TZ: <%= h(user.timezone) %>">
<div class="flex items-center space-x-1 mb-1">
<%= render "shared/user_mention", user: user %>
</div>
@ -291,9 +291,9 @@
<% if project_detail[:repo_url].present? %>
<a href="<%= project_detail[:repo_url] %>" target="_blank" rel="noopener noreferrer"
class="text-white hover:text-gray-200 underline"
title="Open <%= project_detail[:name] %> on GitHub"><%= project_detail[:name].truncate(20) %></a>
title="Open <%= h(project_detail[:name]) %> on GitHub"><%= h(project_detail[:name]).truncate(20) %></a>
<% else %>
<span title="<%= project_detail[:name] %> - No GitHub Repo Mapped"><%= project_detail[:name].truncate(20) %> 🚫</span>
<span title="<%= h(project_detail[:name]) %> - No GitHub Repo Mapped"><%= h(project_detail[:name]).truncate(20) %> 🚫</span>
<% end %>
<% if p_idx < props[:projects_to_display].length - 1 && props[:height_px] > 20 %>
<%= " / " %>

View file

@ -23,16 +23,16 @@
<div class="bg-darkless rounded-lg p-6 border-l-4 border-primary">
<div class="space-y-2 text-lg">
<p class="font-semibold text-white">
<%= @user.mailing_address.first_name %> <%= @user.mailing_address.last_name %>
<%= h(@user.mailing_address.first_name) %> <%= h(@user.mailing_address.last_name) %>
</p>
<p class="text-secondary"><%= @user.mailing_address.line_1 %></p>
<p class="text-secondary"><%= h(@user.mailing_address.line_1) %></p>
<% if @user.mailing_address.line_2.present? %>
<p class="text-secondary"><%= @user.mailing_address.line_2 %></p>
<p class="text-secondary"><%= h(@user.mailing_address.line_2) %></p>
<% end %>
<p class="text-secondary">
<%= @user.mailing_address.city %>, <%= @user.mailing_address.state %> <%= @user.mailing_address.zip_code %>
<%= h(@user.mailing_address.city) %>, <%= h(@user.mailing_address.state) %> <%= h(@user.mailing_address.zip_code) %>
</p>
<p class="text-secondary font-semibold"><%= @user.mailing_address.country %></p>
<p class="text-secondary font-semibold"><%= h(@user.mailing_address.country) %></p>
</div>
</div>
</section>

View file

@ -86,7 +86,7 @@
<% @project_durations.each do |project, duration| %>
<div class="bar-row">
<div class="bar-label"><%= (project.presence || "Unknown") %></div>
<div class="bar-label"><%= h(project.presence || "Unknown") %></div>
<div class="bar-container">
<div class="bar" style="width: <%= log_scale(duration, max_duration) %>%">
<span class="bar-value"><%= ApplicationController.helpers.short_time_simple(duration) %></span>

View file

@ -7,8 +7,8 @@
<div class="bg-dark border border-primary rounded-xl p-6 shadow-lg transition-all duration-300 flex flex-col gap-4 hover:border-primary/40 hover:-translate-y-1 hover:shadow-xl backdrop-blur-sm">
<div class="flex justify-between items-start gap-3">
<div class="flex flex-col gap-2 flex-1 min-w-0">
<h3 class="text-lg font-semibold text-white truncate" title="<%= project[:project] %>">
<%= (project[:project].presence || "Unknown") %>
<h3 class="text-lg font-semibold text-white truncate" title="<%= h(project[:project]) %>">
<%= h(project[:project].presence || "Unknown") %>
</h3>
<% if project[:repository]&.stars.present? %>
<div class="flex items-center gap-1 text-sm text-yellow-400">
@ -59,7 +59,7 @@
<% if project[:repository]&.description.present? %>
<div class="text-sm text-white/70 leading-relaxed line-clamp-2">
<%= project[:repository].description %>
<%= h(project[:repository].description) %>
</div>
<% end %>

View file

@ -68,10 +68,10 @@
<% @ssp_users_recent.each_with_index do |user, index| %>
<div class="relative cursor-pointer transition-transform duration-200 hover:-translate-y-1 hover:z-10 group <%= index > 0 ? '-ml-4' : '' %>">
<div class="absolute -top-9 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-2 py-1 rounded text-xs whitespace-nowrap opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-20">
<%= user[:display_name] %>
<%= h(user[:display_name]) %>
<div class="absolute top-full left-1/2 -ml-1 border-l-2 border-r-2 border-t-2 border-transparent border-t-gray-800"></div>
</div>
<img src="<%= user[:avatar_url] %>" alt="<%= user[:display_name] %>" class="w-10 h-10 rounded-full border-2 border-primary object-cover shadow-sm" />
<img src="<%= user[:avatar_url] %>" alt="<%= h(user[:display_name]) %>" class="w-10 h-10 rounded-full border-2 border-primary object-cover shadow-sm" />
</div>
<% end %>
<% if @ssp_users_size && @ssp_users_size > 5 %>
@ -82,8 +82,8 @@
<div class="flex flex-col gap-2">
<% @ssp_users_recent.each do |user| %>
<div class="flex items-center p-1 rounded hover:bg-gray-700 transition-colors duration-200">
<img src="<%= user[:avatar_url] %>" alt="<%= user[:display_name] %>" class="w-8 h-8 rounded-full mr-2 border border-primary" />
<span class="font-medium text-sm"><%= user[:display_name] %></span>
<img src="<%= user[:avatar_url] %>" alt="<%= h(user[:display_name]) %>" class="w-8 h-8 rounded-full mr-2 border border-primary" />
<span class="font-medium text-sm"><%= h(user[:display_name]) %></span>
</div>
<% end %>
</div>

View file

@ -246,7 +246,7 @@
<select name="project" id="project-select" onchange="up2(this.value)"
class="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white focus:border-primary focus:ring-1 focus:ring-primary">
<% @projects.each do |project| %>
<option value="<%= project %>"><%= project %></option>
<option value="<%= h(project) %>"><%= h(project) %></option>
<% end %>
</select>
<div class="mt-3 p-4 bg-gray-800 border border-gray-600 rounded">