1+ import { createContext , useContext , useState , ReactNode , useEffect } from 'react' ;
2+ import { WebFuzzingCommonsReport } from "@/types/GeneratedTypes.tsx" ;
3+ import { ITestFiles } from "@/types/General.tsx" ;
4+ import { fetchFileContent , ITransformedReport , transformWebFuzzingReport } from "@/lib/utils.tsx" ;
5+
6+ type AppContextType = {
7+ data : WebFuzzingCommonsReport | null ;
8+ loading : boolean ;
9+ error : string | null ;
10+ testFiles : ITestFiles [ ] ;
11+ transformedReport : ITransformedReport [ ] ;
12+ filterEndpoints : ( activeFilters : Record < number , string > ) => ITransformedReport [ ] ;
13+ filteredEndpoints : ITransformedReport [ ] ;
14+ } ;
15+
16+ const AppContext = createContext < AppContextType | undefined > ( undefined ) ;
17+
18+ type AppProviderProps = {
19+ children : ReactNode ;
20+ } ;
21+
22+ export const AppProvider = ( { children } : AppProviderProps ) => {
23+
24+ const [ data , setData ] = useState < WebFuzzingCommonsReport | null > ( null ) ;
25+ const [ loading , setLoading ] = useState ( true ) ;
26+ const [ error , setError ] = useState < string | null > ( null ) ;
27+ const [ testFiles , setTestFiles ] = useState < ITestFiles [ ] > ( [ ] ) ;
28+ const transformedReport = transformWebFuzzingReport ( data ) ;
29+
30+ useEffect ( ( ) => {
31+ const fetchData = async ( ) => {
32+ try {
33+ const jsonData = await fetchFileContent ( './report.json' ) as WebFuzzingCommonsReport ;
34+ setData ( jsonData ) ;
35+ } catch ( error : Error | unknown ) {
36+ if ( error instanceof Error ) {
37+ setError ( "Could not load the report file. Please check if the file exists and is accessible in /public folder." ) ;
38+ } else {
39+ console . error ( error ) ;
40+ }
41+ } finally {
42+ setLoading ( false ) ;
43+ }
44+ } ;
45+
46+ fetchData ( ) ;
47+ } , [ ] ) ;
48+
49+ useEffect ( ( ) => {
50+ if ( data ?. test_file_paths ) {
51+ data . test_file_paths . map ( file => {
52+ fetchFileContent ( file ) . then ( ( content ) => {
53+ if ( typeof content === "string" ) {
54+ setTestFiles ( prev => [ ...prev , {
55+ name : file ,
56+ code : content
57+ } ] ) ;
58+ } else {
59+ setError ( "Could not load the test file. Please check if the file exists and is accessible." ) ;
60+ }
61+ } ) . catch ( ( error ) => {
62+ console . error ( error ) ;
63+ setError ( "Could not load the test file. Please check if the file exists and is accessible." ) ;
64+ } )
65+ } )
66+ }
67+ } , [ data ] ) ;
68+
69+ const [ filteredEndpoints , setFilteredEndpoints ] = useState ( transformedReport ) ;
70+
71+ useEffect ( ( ) => {
72+ // Transform the report data into a format suitable for filtering
73+ if ( data ) {
74+ const transformed = transformWebFuzzingReport ( data ) ;
75+ setFilteredEndpoints ( transformed ) ;
76+ }
77+ } , [ data ] ) ;
78+
79+ const filterEndpoints = ( activeFilters : Record < number , string > ) => {
80+ // Filter the endpoints based on the active filters
81+ const filtered = transformedReport . filter ( endpoint => {
82+ // If no filters are active, show all endpoints
83+ if ( Object . keys ( activeFilters ) . length === 0 ) {
84+ return true ;
85+ }
86+
87+ // Check if any status code or fault code is marked as "removed"
88+ const hasRemovedStatusCode = endpoint . http_status_codes . some ( code =>
89+ activeFilters [ code . code ] === "removed"
90+ ) ;
91+ const hasRemovedFaultCode = endpoint . faults . some ( code =>
92+ activeFilters [ - code . code ] === "removed"
93+ ) ;
94+
95+ // Check if any status code or fault code is marked as "active"
96+ const hasActiveStatusCode = endpoint . http_status_codes . some ( code =>
97+ activeFilters [ code . code ] === "active"
98+ ) ;
99+ const hasActiveFaultCode = endpoint . faults . some ( code =>
100+ activeFilters [ - code . code ] === "active"
101+ ) ;
102+
103+ const hasActiveFilter = activeFilters && Object . values ( activeFilters ) . some ( ( value ) => value === "active" ) ;
104+ const hasRemovedFilter = activeFilters && Object . values ( activeFilters ) . some ( ( value ) => value === "removed" ) ;
105+
106+ if ( ! hasActiveFilter && ! hasRemovedFilter ) {
107+ // If no filters are active, show all endpoints
108+ return true ;
109+ }
110+
111+ if ( hasActiveFilter ) {
112+ if ( hasRemovedFilter ) {
113+ // If there are both active and removed filters, check if the endpoint matches any of them
114+ if ( hasRemovedFaultCode || hasRemovedStatusCode ) {
115+ return false ;
116+ }
117+
118+ return ! ! ( hasActiveStatusCode || hasActiveFaultCode ) ;
119+
120+ } else {
121+ // If there are only active filters, check if the endpoint matches any of them
122+ return ! ! ( hasActiveStatusCode || hasActiveFaultCode ) ;
123+
124+ }
125+ } else if ( hasRemovedFilter ) {
126+ // If there are only removed filters, check if the endpoint matches any of them
127+ return ! ( hasRemovedStatusCode || hasRemovedFaultCode ) ;
128+
129+ } else {
130+ // If there are no active or removed filters, show all endpoints
131+ return true ;
132+ }
133+ } ) ;
134+ setFilteredEndpoints ( filtered )
135+ return filtered ;
136+ }
137+
138+ const value : AppContextType = { data, loading, error, testFiles, transformedReport, filterEndpoints, filteredEndpoints } ;
139+
140+ return (
141+ < AppContext . Provider value = { value } >
142+ { children }
143+ </ AppContext . Provider >
144+ ) ;
145+ } ;
146+
147+ export const useAppContext = ( ) : AppContextType => {
148+ const context = useContext ( AppContext ) ;
149+ if ( ! context ) {
150+ throw new Error ( 'useAppContext must be used within AppProvider' ) ;
151+ }
152+ return context ;
153+ } ;
0 commit comments