Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@tiptap/starter-kit": "^3.13.0",
"classnames": "^2.5.1",
"date-fns": "^3.6.0",
"dompurify": "^3.4.12",
"file-saver": "^2.0.5",
"html-to-docx": "^1.8.0",
"lodash-es": "^4.17.21",
Expand All @@ -34,6 +35,7 @@
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.0",
"@types/dompurify": "^3.0.5",
"@types/file-saver": "^2.0.7",
"@types/html-to-docx": "^1.8.0",
"@types/lodash-es": "^4.17.12",
Expand Down
6 changes: 4 additions & 2 deletions src/components/CitationBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { useState, useEffect, useCallback, useMemo } from 'react';
import DOMPurify from 'dompurify';
import {
Search,
Filter,
Expand Down Expand Up @@ -47,6 +48,7 @@ import {
} from '../utils/citationService';
import type { CitationStyle } from '../utils/citationTypes';
import { formatCitation, citationToHtml } from '../utils/citationFormatter';
import { safeHref } from '../utils/safeHref';

// ============================================
// Type Icons
Expand Down Expand Up @@ -207,7 +209,7 @@ function CitationPreview({ citation, style, onInsert, onClose, onCopyToClipboard
</button>
</div>
<div className="p-3 bg-slate-50 rounded-lg text-sm">
<span dangerouslySetInnerHTML={{ __html: citationToHtml(citation, style) }} />
<span dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(citationToHtml(citation, style)) }} />
</div>
<button
onClick={() => onInsert('full')}
Expand Down Expand Up @@ -290,7 +292,7 @@ function CitationPreview({ citation, style, onInsert, onClose, onCopyToClipboard
{citation.url && (
<div className="pt-4 border-t border-slate-200">
<a
href={citation.url}
href={safeHref(citation.url)}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 text-sm text-primary-600 hover:text-primary-700"
Expand Down
3 changes: 2 additions & 1 deletion src/components/CitationManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
getCitationTypeCounts,
} from '../utils/citationService';
import { buildCitationString, parseCitationString, validateCitation } from '../utils/citationFormatter';
import { safeHref } from '../utils/safeHref';

// ============================================
// Type Icons
Expand Down Expand Up @@ -760,7 +761,7 @@ export function CitationManager() {
<div className="flex items-center justify-end gap-1">
{citation.url && (
<a
href={citation.url}
href={safeHref(citation.url)}
target="_blank"
rel="noopener noreferrer"
className="p-1.5 text-slate-400 hover:text-slate-600 hover:bg-slate-100 rounded"
Expand Down
5 changes: 3 additions & 2 deletions src/components/ClauseBrowser.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState, useCallback, useEffect } from 'react';
import DOMPurify from 'dompurify';
import { useAppDispatch, useAppSelector } from '../store';
import { setShowClauseBrowser } from '../features/uiSlice';
import {
Expand Down Expand Up @@ -290,9 +291,9 @@ export function ClauseBrowser({ onInsert }: ClauseBrowserProps) {
</div>

<div className="flex-1 overflow-y-auto p-4">
<div
<div
className="prose prose-sm max-w-none text-slate-700"
dangerouslySetInnerHTML={{ __html: selectedClause.content }}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(selectedClause.content) }}
/>

{selectedClause.placeholders && selectedClause.placeholders.length > 0 && (
Expand Down
5 changes: 3 additions & 2 deletions src/components/ClauseIntegration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { useState, useEffect, useCallback } from 'react';
import DOMPurify from 'dompurify';
import {
Bookmark,
Search,
Expand Down Expand Up @@ -138,9 +139,9 @@ function ClauseCard({ clause, relevance, onInsert, onInsertAsSupport }: ClauseCa
<p className="text-sm text-slate-600 mb-3">{clause.description}</p>
)}

<div
<div
className="text-sm text-slate-700 bg-white p-3 rounded border border-slate-200 mb-3 max-h-40 overflow-y-auto"
dangerouslySetInnerHTML={{ __html: clause.content }}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(clause.content) }}
/>

<div className="flex items-center gap-2">
Expand Down
3 changes: 2 additions & 1 deletion src/components/ClauseLibrary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { useState, useEffect, useCallback, useMemo } from 'react';
import DOMPurify from 'dompurify';
import {
Search,
Filter,
Expand Down Expand Up @@ -239,7 +240,7 @@ function ClausePreview({ clause, onInsert, onClose }: ClausePreviewProps) {
<div className="flex-1 overflow-y-auto p-4">
<div
className="prose prose-sm max-w-none"
dangerouslySetInnerHTML={{ __html: displayContent }}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(displayContent) }}
/>
</div>

Expand Down
7 changes: 4 additions & 3 deletions src/components/DocumentFormatter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { useState, useEffect, useCallback, useMemo } from 'react';
import DOMPurify from 'dompurify';
import {
FileText,
Eye,
Expand Down Expand Up @@ -859,11 +860,11 @@ export function DocumentFormatter({
<h4 className="text-sm font-medium text-slate-700 mb-2">Document Preview</h4>
<div
className="border border-slate-200 rounded-lg p-6 bg-white max-h-96 overflow-y-auto prose prose-sm"
dangerouslySetInnerHTML={{
__html: [
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize([
formattedDoc.caption,
formattedDoc.body.substring(0, 2000) + (formattedDoc.body.length > 2000 ? '...' : ''),
].join('<hr/>')
].join('<hr/>'))
}}
/>
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/components/RightPanel/SuggestionsPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import DOMPurify from 'dompurify';
import { useAppDispatch, useAppSelector } from '../../store';
import { onProxyStatus } from '../../demo/proxyClient';
import { safeHref } from '../../utils/safeHref';
import {
generateSuggestions,
setSignals,
Expand Down Expand Up @@ -569,9 +571,9 @@ function SuggestionCard({ suggestion, isCollapsed, isArchived, onPin, onToggleCo
</button>
)}
</div>
<div
<div
className="text-sm text-amber-800 prose prose-sm max-w-none line-clamp-4"
dangerouslySetInnerHTML={{ __html: suggestion.clauseContent }}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(suggestion.clauseContent) }}
/>
</div>
)}
Expand All @@ -594,7 +596,7 @@ function SuggestionCard({ suggestion, isCollapsed, isArchived, onPin, onToggleCo
return (
<a
key={i}
href={ref}
href={safeHref(ref)}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 p-2 rounded-md bg-slate-50 hover:bg-primary-50 border border-slate-100 hover:border-primary-200 transition-colors group"
Expand Down
5 changes: 3 additions & 2 deletions src/components/TemplateEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { useState, useCallback, useMemo, useEffect } from 'react';
import DOMPurify from 'dompurify';
import { useEditor, EditorContent } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import {
Expand Down Expand Up @@ -822,9 +823,9 @@ export function TemplateEditor({
)}

{/* Preview Content */}
<div
<div
className="prose prose-sm max-w-none"
dangerouslySetInnerHTML={{ __html: previewContent }}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(previewContent) }}
/>

{/* Placeholder Styling */}
Expand Down
Loading
Loading