mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-09 08:47:11 -05:00
Fix potential xss
This commit is contained in:
parent
4aa6edc3cc
commit
fa4e368003
3 changed files with 55 additions and 13 deletions
|
|
@ -177,8 +177,10 @@ export class PlacesManager {
|
|||
}
|
||||
|
||||
createPlaceIcon(place) {
|
||||
const emoji = place.icon || place.tags[0]?.icon || '📍';
|
||||
const color = place.color || place.tags[0]?.color || '#4CAF50';
|
||||
const rawEmoji = place.icon || place.tags[0]?.icon || '📍';
|
||||
const emoji = this.escapeHtml(rawEmoji);
|
||||
const rawColor = place.color || place.tags[0]?.color || '#4CAF50';
|
||||
const color = this.sanitizeColor(rawColor);
|
||||
|
||||
const iconHtml = `
|
||||
<div class="place-marker" style="
|
||||
|
|
@ -207,18 +209,24 @@ export class PlacesManager {
|
|||
}
|
||||
|
||||
createPopupContent(place) {
|
||||
const tags = place.tags.map(tag =>
|
||||
`<span class="badge badge-sm" style="background-color: ${tag.color}">
|
||||
${tag.icon} #${tag.name}
|
||||
</span>`
|
||||
).join(' ');
|
||||
const tags = place.tags.map(tag => {
|
||||
const safeIcon = this.escapeHtml(tag.icon || '');
|
||||
const safeName = this.escapeHtml(tag.name || '');
|
||||
const safeColor = this.sanitizeColor(tag.color);
|
||||
return `<span class="badge badge-sm" style="background-color: ${safeColor}">
|
||||
${safeIcon} #${safeName}
|
||||
</span>`;
|
||||
}).join(' ');
|
||||
|
||||
const safeName = this.escapeHtml(place.name || '');
|
||||
const safeVisitsCount = place.visits_count ? parseInt(place.visits_count, 10) : 0;
|
||||
|
||||
return `
|
||||
<div class="place-popup" style="min-width: 200px;">
|
||||
<h3 class="font-bold text-lg mb-2">${place.name}</h3>
|
||||
<h3 class="font-bold text-lg mb-2">${safeName}</h3>
|
||||
${tags ? `<div class="mb-2">${tags}</div>` : ''}
|
||||
${place.note ? `<p class="text-sm text-gray-600 mb-2 italic">${this.escapeHtml(place.note)}</p>` : ''}
|
||||
${place.visits_count ? `<p class="text-sm">Visits: ${place.visits_count}</p>` : ''}
|
||||
${safeVisitsCount > 0 ? `<p class="text-sm">Visits: ${safeVisitsCount}</p>` : ''}
|
||||
<div class="mt-2 flex gap-2">
|
||||
<button class="btn btn-xs btn-primary" data-place-id="${place.id}" data-action="edit-place">
|
||||
Edit
|
||||
|
|
@ -237,6 +245,20 @@ export class PlacesManager {
|
|||
return div.innerHTML;
|
||||
}
|
||||
|
||||
sanitizeColor(color) {
|
||||
// Validate hex color format (#RGB or #RRGGBB)
|
||||
if (!color || typeof color !== 'string') {
|
||||
return '#4CAF50'; // Default green
|
||||
}
|
||||
|
||||
const hexColorRegex = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
||||
if (hexColorRegex.test(color)) {
|
||||
return color;
|
||||
}
|
||||
|
||||
return '#4CAF50'; // Default green for invalid colors
|
||||
}
|
||||
|
||||
setupMapClickHandler() {
|
||||
this.map.on('click', (e) => {
|
||||
if (this.creationMode) {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,10 @@ export function createPlacesControl(placesManager, tags, userTheme = 'dark') {
|
|||
FILTER BY TAG
|
||||
</div>
|
||||
<div style="max-height: 250px; overflow-y: auto; margin-right: -5px; padding-right: 5px;">
|
||||
${this.tags.map(tag => `
|
||||
${this.tags.map(tag => {
|
||||
const safeIcon = tag.icon ? this.escapeHtml(tag.icon) : '📍';
|
||||
const safeColor = this.sanitizeColor(tag.color);
|
||||
return `
|
||||
<label style="display: flex; align-items: center; padding: 6px; cursor: pointer; border-radius: 4px; margin-bottom: 2px;"
|
||||
class="places-control-item"
|
||||
onmouseover="this.style.backgroundColor='rgba(128,128,128,0.2)'"
|
||||
|
|
@ -110,11 +113,12 @@ export function createPlacesControl(placesManager, tags, userTheme = 'dark') {
|
|||
data-tag-id="${tag.id}"
|
||||
style="margin-right: 8px; cursor: pointer;"
|
||||
${this.activeFilters.has(tag.id) ? 'checked' : ''}>
|
||||
<span style="font-size: 18px; margin-right: 6px;">${tag.icon || '📍'}</span>
|
||||
<span style="font-size: 18px; margin-right: 6px;">${safeIcon}</span>
|
||||
<span style="flex: 1;">#${this.escapeHtml(tag.name)}</span>
|
||||
${tag.color ? `<span style="width: 12px; height: 12px; border-radius: 50%; background-color: ${tag.color}; margin-left: 4px;"></span>` : ''}
|
||||
${tag.color ? `<span style="width: 12px; height: 12px; border-radius: 50%; background-color: ${safeColor}; margin-left: 4px;"></span>` : ''}
|
||||
</label>
|
||||
`).join('')}
|
||||
`;
|
||||
}).join('')}
|
||||
</div>
|
||||
</div>
|
||||
` : '<div style="font-size: 12px; opacity: 0.6; padding: 8px; text-align: center;">No tags created yet</div>'}
|
||||
|
|
@ -209,6 +213,20 @@ export function createPlacesControl(placesManager, tags, userTheme = 'dark') {
|
|||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
},
|
||||
|
||||
sanitizeColor: function(color) {
|
||||
// Validate hex color format (#RGB or #RRGGBB)
|
||||
if (!color || typeof color !== 'string') {
|
||||
return '#4CAF50'; // Default green
|
||||
}
|
||||
|
||||
const hexColorRegex = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
||||
if (hexColorRegex.test(color)) {
|
||||
return color;
|
||||
}
|
||||
|
||||
return '#4CAF50'; // Default green for invalid colors
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ OMNIAUTH_PROVIDERS =
|
|||
providers << :github if ENV['GITHUB_OAUTH_CLIENT_ID'].present? && ENV['GITHUB_OAUTH_CLIENT_SECRET'].present?
|
||||
|
||||
providers << :google_oauth2 if ENV['GOOGLE_OAUTH_CLIENT_ID'].present? && ENV['GOOGLE_OAUTH_CLIENT_SECRET'].present?
|
||||
|
||||
providers
|
||||
end
|
||||
|
||||
# Custom OIDC provider display name
|
||||
|
|
|
|||
Loading…
Reference in a new issue