Fix code scanning findings

This commit is contained in:
rcourtman 2026-03-28 10:58:57 +00:00
parent fda03c531b
commit a8ee51fb99
16 changed files with 53 additions and 29 deletions

View file

@ -125,7 +125,7 @@ export function ThresholdSlider(props: ThresholdSliderProps) {
<div class="relative">
<div class="w-9 h-4 bg-white dark:bg-gray-800 rounded-full shadow-md border-2 border-current flex items-center justify-center">
<span class="text-[9px] font-semibold">
{props.type === 'temperature' ? `${props.value}${getTemperatureSymbol().replace('°', '°')}` : `${props.value}%`}
{props.type === 'temperature' ? `${props.value}${getTemperatureSymbol()}` : `${props.value}%`}
</span>
</div>
</div>

View file

@ -43,14 +43,13 @@ export const SetupWizard: Component<SetupWizardProps> = (props) => {
const raw = sessionStorage.getItem(STORAGE_KEYS.SETUP_CREDENTIALS);
if (!raw) return null;
const parsed = JSON.parse(raw) as Partial<WizardState>;
if (!parsed.username || !parsed.password || !parsed.apiToken) {
if (!parsed.username || !parsed.apiToken) {
sessionStorage.removeItem(STORAGE_KEYS.SETUP_CREDENTIALS);
return null;
}
return {
...defaultWizardState,
username: parsed.username,
password: parsed.password,
apiToken: parsed.apiToken,
};
} catch (_err) {

View file

@ -143,6 +143,9 @@ export const CompleteStep: Component<CompleteStepProps> = (props) => {
const handleCopy = async (type: 'password' | 'token' | 'install', value?: string) => {
const copyValue = value || (type === 'password' ? props.state.password : props.state.apiToken);
if (!copyValue) {
return;
}
const success = await copyToClipboard(copyValue);
if (success) {
setCopied(type);
@ -165,6 +168,9 @@ export const CompleteStep: Component<CompleteStepProps> = (props) => {
const downloadCredentials = () => {
const baseUrl = getPulseBaseUrl();
const passwordSection = props.state.password
? `Password: ${props.state.password}\n`
: 'Password: not stored after reload; use the password you chose during setup or reset it in Settings.\n';
const content = `Pulse Credentials
==================
Generated: ${new Date().toISOString()}
@ -173,7 +179,7 @@ Web Login:
----------
URL: ${baseUrl}
Username: ${props.state.username}
Password: ${props.state.password}
${passwordSection}
API Token:
----------

View file

@ -83,7 +83,6 @@ export const SecurityStep: Component<SecurityStepProps> = (props) => {
STORAGE_KEYS.SETUP_CREDENTIALS,
JSON.stringify({
username: username(),
password: finalPassword,
apiToken: token,
createdAt: new Date().toISOString(),
}),

View file

@ -17,18 +17,6 @@ interface TooltipProps extends TooltipOptions {
visible: boolean;
}
// Sanitize tooltip content to prevent XSS
function sanitizeContent(content: string): string {
// Remove any HTML tags and encode special characters
return content
.replace(/<[^>]*>/g, '') // Remove HTML tags
.replace(/&/g, '&amp;') // Encode ampersands
.replace(/</g, '&lt;') // Encode less than
.replace(/>/g, '&gt;') // Encode greater than
.replace(/"/g, '&quot;') // Encode quotes
.replace(/'/g, '&#x27;'); // Encode apostrophes
}
const Tooltip: Component<TooltipProps> = (props) => {
let tooltipRef: HTMLDivElement | undefined;
const [position, setPosition] = createSignal({ left: 0, top: 0 });
@ -75,7 +63,7 @@ const Tooltip: Component<TooltipProps> = (props) => {
opacity: props.visible ? '1' : '0',
transition: 'opacity 120ms ease-out',
}}
textContent={sanitizeContent(props.content)}
textContent={props.content}
/>
</Portal>
</Show>

View file

@ -3,7 +3,7 @@ const isDev = import.meta.env.DEV;
export const logger = {
debug: (message: string, data?: unknown) => {
if (isDev) console.log(`[DEBUG] ${message}`, data || '');
if (isDev) console.log('[DEBUG]', message, data ?? '');
},
info: (message: string, data?: unknown) => {
@ -14,16 +14,16 @@ export const logger = {
message.includes('error') ||
message.includes('failed')
) {
console.log(`[INFO] ${message}`, data || '');
console.log('[INFO]', message, data ?? '');
}
},
warn: (message: string, data?: unknown) => {
console.warn(`[WARN] ${message}`, data || '');
console.warn('[WARN]', message, data ?? '');
},
error: (message: string, error?: unknown) => {
console.error(`[ERROR] ${message}`, error || '');
console.error('[ERROR]', message, error ?? '');
},
};

View file

@ -5,7 +5,7 @@ type DisplayableNode = Pick<Node, 'name'> &
const sanitize = (value: string): string => value.trim().toLowerCase().replace(/[^a-z0-9]/g, '');
const escapeRegExp = (value: string): string => value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\$&');
const escapeRegExp = (value: string): string => value.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
const extractHostname = (value: string): string => {
if (!value) return '';