Makes components itteratable

This commit is contained in:
Alicia Sykes 2023-06-28 05:57:50 +01:00
parent 595a6833db
commit c83419cfd2
11 changed files with 54 additions and 126 deletions

View File

@ -47,9 +47,8 @@ const ListRow = (props: { list: Technology[], title: string }) => {
);
}
const BuiltWithCard = (props: { technologies: TechnologyGroup[] }): JSX.Element => {
const BuiltWithCard = (technologies: TechnologyGroup[]): JSX.Element => {
// const { created, updated, expires, nameservers } = whois;
const { technologies } = props;
return (
<Outer>
<Heading as="h3" align="left" color={colors.primary}>Technologies</Heading>

View File

@ -7,16 +7,15 @@ import { ExpandableRow } from 'components/Form/Row';
const Outer = styled(Card)``;
const CookiesCard = (props: { cookies: any }): JSX.Element => {
const cookies = props.cookies;
const CookiesCard = (cookies: { cookies: any }): JSX.Element => {
return (
<Outer>
<Heading as="h3" align="left" color={colors.primary}>Cookies</Heading>
{
cookies.length === 0 && <p>No cookies found.</p>
cookies.cookies.length === 0 && <p>No cookies found.</p>
}
{
cookies.map((cookie: any, index: number) => {
cookies.cookies.map((cookie: any, index: number) => {
const attributes = Object.keys(cookie.attributes).map((key: string) => {
return { lbl: key, val: cookie.attributes[key] }
});
@ -24,7 +23,7 @@ const CookiesCard = (props: { cookies: any }): JSX.Element => {
<ExpandableRow key={`cookie-${index}`} lbl={cookie.name} val={cookie.value} rowList={attributes} />
)
})
}
}
</Outer>
);
}

View File

@ -3,7 +3,7 @@ import styled from 'styled-components';
import colors from 'styles/colors';
import Card from 'components/Form/Card';
import Heading from 'components/Form/Heading';
import Row, { ListRow, RowProps } from 'components/Form/Row';
import Row, { ListRow } from 'components/Form/Row';
const Outer = styled(Card)`
.content {
@ -12,8 +12,7 @@ const Outer = styled(Card)`
}
`;
const DnsRecordsCard = (props: { dnsRecords: any }): JSX.Element => {
const dnsRecords = props.dnsRecords;
const DnsRecordsCard = (dnsRecords: any): JSX.Element => {
return (
<Outer>
<Heading as="h3" align="left" color={colors.primary}>DNS Records</Heading>

View File

@ -9,8 +9,7 @@ const Outer = styled(Card)`
grid-row: span 2;
`;
const HeadersCard = (props: { headers: any }): JSX.Element => {
const headers = props.headers;
const HeadersCard = (headers: any): JSX.Element => {
return (
<Outer>
<Heading as="h3" align="left" color={colors.primary}>Headers</Heading>

View File

@ -32,8 +32,7 @@ const HostListSection = (props: { list: string[], title: string }) => {
);
}
const HostNamesCard = (props: { hosts: HostNames }): JSX.Element => {
const hosts = props.hosts;
const HostNamesCard = (hosts: HostNames): JSX.Element => {
return (
<Outer>
{ hosts.domains.length > 0 &&

View File

@ -12,44 +12,6 @@ const processScore = (percentile: number) => {
const Outer = styled(Card)``;
const Row = styled.div`
details summary {
display: flex;
justify-content: space-between;
padding: 0.25rem;
cursor: pointer;
}
&:not(:last-child) { border-bottom: 1px solid ${colors.primary}; }
span.lbl {
font-weight: bold;
text-transform: capitalize;
}
span.val {
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
`;
const ScoreRow = styled.li`
list-style: none;
margin: 0;
display: flex;
gap: 0.25rem;
padding: 0.25rem 0;
justify-content: space-between;
span { min-width: 5rem; max-width: 8rem; }
border-bottom: 1px dashed ${colors.primaryTransparent};
`;
const ScoreList = styled.ul`
margin: 0;
padding: 0.25rem;
border-top: 1px solid ${colors.primary};
background: ${colors.primaryTransparent};
`;
interface Audit {
id: string,
score?: number | string,
@ -59,26 +21,6 @@ interface Audit {
displayValue?: string,
};
const ScoreItem = (props: { scoreId: any, audits: Audit[] }) => {
const { scoreId, audits } = props;
const audit = audits[scoreId];
if (!audit.score) return null;
let score = audit.score;
if (audit.displayValue) {
score = audit.displayValue;
} else if (audit.scoreDisplayMode) {
score = audit.score === 1 ? '✅ Pass' : '❌ Fail';
}
return (
<ScoreRow title={audit.description}>
<b>{ audit.title }</b>
<span>{score}</span>
</ScoreRow>
);
};
const makeValue = (audit: Audit) => {
let score = audit.score;
if (audit.displayValue) {
@ -89,9 +31,9 @@ const makeValue = (audit: Audit) => {
return score;
};
const LighthouseCard = (props: { lighthouse: any }): JSX.Element => {
const categories = props.lighthouse?.categories || {};
const audits = props.lighthouse?.audits || [];
const LighthouseCard = (lighthouse: any): JSX.Element => {
const categories = lighthouse?.categories || {};
const audits = lighthouse?.audits || [];
return (
<Outer>

View File

@ -12,16 +12,16 @@ const Outer = styled(Card)`
}
`;
const RobotsTxtCard = (props: { robotTxt: RowProps[] }): JSX.Element => {
const RobotsTxtCard = ( robots: { robots: RowProps[]}): JSX.Element => {
return (
<Outer>
<Heading as="h3" align="left" color={colors.primary}>Crawl Rules</Heading>
<div className="content">
{
props.robotTxt.length === 0 && <p>No crawl rules found.</p>
robots.robots.length === 0 && <p>No crawl rules found.</p>
}
{
props.robotTxt.map((row: RowProps, index: number) => {
robots.robots.map((row: RowProps, index: number) => {
return (
<Row key={`${row.lbl}-${index}`} lbl={row.lbl} val={row.val} />
)

View File

@ -14,11 +14,11 @@ img {
}
`;
const ScreenshotCard = (props: { screenshot: string }): JSX.Element => {
const ScreenshotCard = (screenshot: string): JSX.Element => {
return (
<Outer>
<Heading as="h3" align="left" color={colors.primary}>Screenshot</Heading>
<img src={props.screenshot} alt="Full page screenshot" />
<img src={screenshot} alt="Full page screenshot" />
</Outer>
);
}

View File

@ -79,8 +79,8 @@ const ListRow = (props: { list: string[], title: string }) => {
);
}
const SslCertCard = (props: { sslCert: any }): JSX.Element => {
const { subject, issuer, fingerprint, serialNumber, asn1Curve, nistCurve, valid_to, valid_from, ext_key_usage } = props.sslCert;
const SslCertCard = (sslCert: any): JSX.Element => {
const { subject, issuer, fingerprint, serialNumber, asn1Curve, nistCurve, valid_to, valid_from, ext_key_usage } = sslCert;
return (
<Outer>
<Heading as="h3" align="left" color={colors.primary}>SSL Info</Heading>

View File

@ -1,4 +1,4 @@
import { useState, useEffect, useCallback, SetStateAction, Dispatch } from 'react';
import { useState, useEffect, useCallback } from 'react';
import { useParams } from "react-router-dom";
import styled from 'styled-components';
@ -121,7 +121,7 @@ const Results = (): JSX.Element => {
});
// Fetch and parse cookies info
const [cookieResults] = useMotherHook<Cookie[]>({
const [cookieResults] = useMotherHook<{cookies: Cookie[]}>({
jobId: 'cookies',
updateLoadingJobs,
addressInfo: { address, addressType, expectedAddressTypes: urlTypeOnly },
@ -131,7 +131,7 @@ const Results = (): JSX.Element => {
});
// Fetch and parse crawl rules from robots.txt
const [robotsTxtResults] = useMotherHook<RowProps[]>({
const [robotsTxtResults] = useMotherHook<{robots: RowProps[]}>({
jobId: 'robots-txt',
updateLoadingJobs,
addressInfo: { address, addressType, expectedAddressTypes: urlTypeOnly },
@ -229,6 +229,22 @@ const Results = (): JSX.Element => {
return address;
}
}
// A list of state sata, corresponding component and title for each card
const resultCardData = [
{ title: 'Server Location', result: locationResults, Component: ServerLocationCard },
{ title: 'SSL Info', result: sslResults, Component: SslCertCard },
{ title: 'Headers', result: headersResults, Component: HeadersCard },
{ title: 'Host Names', result: shoadnResults?.hostnames, Component: HostNamesCard },
{ title: 'Domain Info', result: whoIsResults, Component: WhoIsCard },
{ title: 'DNS Records', result: dnsResults, Component: DnsRecordsCard },
{ title: 'Performance', result: lighthouseResults, Component: LighthouseCard },
{ title: 'Cookies', result: cookieResults, Component: CookiesCard },
{ title: 'Screenshot', result: lighthouseResults?.fullPageScreenshot?.screenshot?.data, Component: ScreenshotCard },
{ title: 'Technologies', result: technologyResults, Component: BuiltWithCard },
{ title: 'Crawl Rules', result: robotsTxtResults, Component: RobotsTxtCard },
{ title: 'Server Info', result: shoadnResults?.serverInfo, Component: ServerInfoCard },
];
return (
<ResultsOuter>
@ -244,43 +260,17 @@ const Results = (): JSX.Element => {
}
</Header>
<ProgressBar loadStatus={loadingJobs} />
<ResultsContent>
<ErrorBoundary title="Server Location">
{ locationResults && <ServerLocationCard {...locationResults} />}
</ErrorBoundary>
<ErrorBoundary title="SSL Info">
{ sslResults && <SslCertCard sslCert={sslResults} />}
</ErrorBoundary>
<ErrorBoundary title="Headers">
{ headersResults && <HeadersCard headers={headersResults} />}
</ErrorBoundary>
<ErrorBoundary title="Host Names">
{ shoadnResults?.hostnames && <HostNamesCard hosts={shoadnResults.hostnames} />}
</ErrorBoundary>
<ErrorBoundary title="Domain Info">
{ whoIsResults && <WhoIsCard {...whoIsResults} />}
</ErrorBoundary>
<ErrorBoundary title="DNS Records">
{ dnsResults && <DnsRecordsCard dnsRecords={dnsResults} />}
</ErrorBoundary>
<ErrorBoundary title="Performance">
{ lighthouseResults && <LighthouseCard lighthouse={lighthouseResults} />}
</ErrorBoundary>
<ErrorBoundary title="Cookies">
{ cookieResults && <CookiesCard cookies={cookieResults} />}
</ErrorBoundary>
<ErrorBoundary title="Screenshot">
{ lighthouseResults?.fullPageScreenshot?.screenshot?.data && <ScreenshotCard screenshot={lighthouseResults.fullPageScreenshot.screenshot.data} />}
</ErrorBoundary>
<ErrorBoundary title="Technologies">
{ technologyResults && <BuiltWithCard technologies={technologyResults} />}
</ErrorBoundary>
<ErrorBoundary title="Crawl Rules">
{ robotsTxtResults && <RobotsTxtCard robotTxt={robotsTxtResults} />}
</ErrorBoundary>
<ErrorBoundary title="Server Info">
{ shoadnResults?.serverInfo && <ServerInfoCard {...shoadnResults.serverInfo} />}
</ErrorBoundary>
{
resultCardData.map(({ title, result, Component }) => (
(result) ? (
<ErrorBoundary title={title} key={title}>
<Component {...result} />
</ErrorBoundary>
) : <></>
))
}
</ResultsContent>
<Footer />
</ResultsOuter>

View File

@ -140,9 +140,9 @@ export type Cookie = {
attributes: Record<string, string>;
};
export const parseCookies = (cookiesHeader: string): Cookie[] => {
if (!cookiesHeader) return [];
return cookiesHeader.split(/,(?=\s[A-Za-z0-9]+=)/).map(cookieString => {
export const parseCookies = (cookiesHeader: string): {cookies: Cookie[]} => {
if (!cookiesHeader) return {cookies: []};
const cookies = cookiesHeader.split(/,(?=\s[A-Za-z0-9]+=)/).map(cookieString => {
const [nameValuePair, ...attributePairs] = cookieString.split('; ').map(part => part.trim());
const [name, value] = nameValuePair.split('=');
const attributes: Record<string, string> = {};
@ -152,9 +152,10 @@ export const parseCookies = (cookiesHeader: string): Cookie[] => {
});
return { name, value, attributes };
});
return { cookies }
}
export const parseRobotsTxt = (content: string): RowProps[] => {
export const parseRobotsTxt = (content: string): { robots: RowProps[] } => {
const lines = content.split('\n');
const rules: RowProps[] = [];
@ -182,7 +183,7 @@ export const parseRobotsTxt = (content: string): RowProps[] => {
}
});
return rules;
return { robots: rules };
}
export const applyWhoIsResults = (response: any) => {