Merge pull request #179 from shanelord01/audit/remediation-clean
Automated Security & Quality Audit via Claude Code
This commit is contained in:
@@ -3,7 +3,6 @@ import { Routes, Route, Navigate, useLocation } from 'react-router-dom'
|
||||
import { useAuthStore } from './store/authStore'
|
||||
import { useSettingsStore } from './store/settingsStore'
|
||||
import LoginPage from './pages/LoginPage'
|
||||
import RegisterPage from './pages/RegisterPage'
|
||||
import DashboardPage from './pages/DashboardPage'
|
||||
import TripPlannerPage from './pages/TripPlannerPage'
|
||||
import FilesPage from './pages/FilesPage'
|
||||
@@ -14,7 +13,6 @@ import AtlasPage from './pages/AtlasPage'
|
||||
import SharedTripPage from './pages/SharedTripPage'
|
||||
import { ToastContainer } from './components/shared/Toast'
|
||||
import { TranslationProvider, useTranslation } from './i18n'
|
||||
import DemoBanner from './components/Layout/DemoBanner'
|
||||
import { authApi } from './api/client'
|
||||
|
||||
interface ProtectedRouteProps {
|
||||
|
||||
@@ -72,11 +72,15 @@ export default function GitHubPanel() {
|
||||
}
|
||||
}
|
||||
|
||||
const escapeHtml = (str) => str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
||||
const inlineFormat = (text) => {
|
||||
return text
|
||||
return escapeHtml(text)
|
||||
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
||||
.replace(/`(.+?)`/g, '<code style="font-size:11px;padding:1px 4px;border-radius:4px;background:var(--bg-secondary)">$1</code>')
|
||||
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener noreferrer" style="color:#3b82f6;text-decoration:underline">$1</a>')
|
||||
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => {
|
||||
const safeUrl = url.startsWith('http://') || url.startsWith('https://') ? url : '#'
|
||||
return `<a href="${escapeHtml(safeUrl)}" target="_blank" rel="noopener noreferrer" style="color:#3b82f6;text-decoration:underline">${label}</a>`
|
||||
})
|
||||
}
|
||||
|
||||
for (const line of lines) {
|
||||
|
||||
@@ -13,7 +13,7 @@ export async function calculateRoute(
|
||||
}
|
||||
|
||||
const coords = waypoints.map((p) => `${p.lng},${p.lat}`).join(';')
|
||||
const url = `${OSRM_BASE}/driving/${coords}?overview=full&geometries=geojson&steps=false`
|
||||
const url = `${OSRM_BASE}/${profile}/${coords}?overview=full&geometries=geojson&steps=false`
|
||||
|
||||
const response = await fetch(url, { signal })
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -29,7 +29,7 @@ interface AuthState {
|
||||
|
||||
login: (email: string, password: string) => Promise<LoginResult>
|
||||
completeMfaLogin: (mfaToken: string, code: string) => Promise<AuthResponse>
|
||||
register: (username: string, email: string, password: string) => Promise<AuthResponse>
|
||||
register: (username: string, email: string, password: string, invite_token?: string) => Promise<AuthResponse>
|
||||
logout: () => void
|
||||
/** Pass `{ silent: true }` to refresh the user without toggling global isLoading (avoids unmounting protected routes). */
|
||||
loadUser: (opts?: { silent?: boolean }) => Promise<void>
|
||||
@@ -126,6 +126,11 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
logout: () => {
|
||||
disconnect()
|
||||
localStorage.removeItem('auth_token')
|
||||
// Clear service worker caches containing sensitive data
|
||||
if ('caches' in window) {
|
||||
caches.delete('api-data').catch(() => {})
|
||||
caches.delete('user-uploads').catch(() => {})
|
||||
}
|
||||
set({
|
||||
user: null,
|
||||
token: null,
|
||||
@@ -151,13 +156,20 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
})
|
||||
connect(token)
|
||||
} catch (err: unknown) {
|
||||
localStorage.removeItem('auth_token')
|
||||
set({
|
||||
user: null,
|
||||
token: null,
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
})
|
||||
// Only clear auth state on 401 (invalid/expired token), not on network errors
|
||||
const isAuthError = err && typeof err === 'object' && 'response' in err &&
|
||||
(err as { response?: { status?: number } }).response?.status === 401
|
||||
if (isAuthError) {
|
||||
localStorage.removeItem('auth_token')
|
||||
set({
|
||||
user: null,
|
||||
token: null,
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
})
|
||||
} else {
|
||||
set({ isLoading: false })
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user