Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
229 changes: 217 additions & 12 deletions packages/web2/app/components/profile/errorScan.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,229 @@
import { FC } from "react";
import { FC, ReactNode } from "react";
import { Scan, ScanProfile } from "../../api/types.js";
import { DnsErrorView } from "./errorScans/dnsErrorView.js";
import { CertificateErrorView } from "./errorScans/certificateErrorView.js";
import { DefaultErrorView } from "./errorScans/defaultErrorView.js";
import { ErrorViewWithEditDomain } from "./errorScans/ErrorViewWithEditDomain.js";
import { ErrorViewWithoutEditDomain } from "./errorScans/ErrorViewWithoutEditDomain.js";

export const ErrorScan: FC<{
profile: ScanProfile;
lastScan: Scan;
}> = ({ lastScan, profile }) => {
if (lastScan.error?.startsWith("net::ERR_NAME_NOT_RESOLVED")) {
return <DnsErrorView profile={profile} scanId={lastScan._id} />;
interface ErrorTexts {
headline: string;
description: ReactNode;
showEditDomain: boolean;
}

const getErrorTexts = (
error: string,
profile: ScanProfile,
): ErrorTexts | undefined => {
if (error.includes("ERR_NAME_NOT_RESOLVED")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da die Website nicht gefunden werden konnte.
Bitte überprüfe die eingegebene Adresse und versuche es erneut.
</>
),
showEditDomain: true,
};
}

if (error.includes("ERR_CERT_COMMON_NAME_INVALID")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da das SSL-Zertifikat nicht zur aufgerufenen Adresse passt.
Bitte überprüfe die Adresse sowie das Zertifikat der Website und versuche es erneut.
</>
),
showEditDomain: true,
};
}

if (error.includes("ERR_CONNECTION_REFUSED")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da die Verbindung zur Website vom Server abgelehnt wurde.
Bitte überprüfe die Adresse und starte den Scan erneut.
</>
),
showEditDomain: true,
};
}

if (error.includes("ERR_TOO_MANY_REDIRECTS")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da die Website zu viele Weiterleitungen enthält.
Bitte überprüfe die Adresse und starte den Scan erneut.
</>
),
showEditDomain: true,
};
}

if (error.includes("ERR_TIMED_OUT")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da beim Verbindungsaufbau keine Antwort von der Website eingegangen ist.
Bitte überprüfe die Adresse und starte den Scan erneut.
</>
),
showEditDomain: true,
};
}

if (error.includes("ERR_INVALID_AUTH_CREDENTIALS")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da die Website durch einen Passwortschutz oder eine Zugangsbeschränkung gesichert ist.
Bitte nutze eine öffentlich erreichbare Adresse oder entferne die Zugriffsbeschränkung und starte den Scan erneut.
</>
),
showEditDomain: false,
};
}

if (error.includes("ERR_CERT_AUTHORITY_INVALID")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da die Zertifizierungsstelle (CA) des SSL-Zertifikates nicht vertrauenswürdig oder das Zertifikat abgelaufen ist.
Bitte überprüfe das Zertifikat und starte den Scan erneut.
</>
),
showEditDomain: false,
};
}

if (error.includes("ERR_BLOCKED_BY_CLIENT")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da eine Ressource der Website blockiert wurde – zum Beispiel durch einen Werbe-, Tracking- oder Script-Blocker im Browser.
Bitte überprüfe die Ursache und versuche es anschließend erneut.
</>
),
showEditDomain: false,
};
}

if (error.includes("ERR_SSL_PROTOCOL_ERROR")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da keine sichere Verbindung zur Website hergestellt werden konnte.
Bitte überprüfe das SSL-Zertifikat sowie die Servereinstellungen und starte den Scan erneut.
</>
),
showEditDomain: false,
};
}

if (error.includes("ERR_CERT_DATE_INVALID")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da das SSL-Zertifikat der Website abgelaufen oder ungültig ist.
Bitte überprüfe das Zertifikat und versuche es erneut.
</>
),
showEditDomain: false,
};
}

if (error.includes("ERR_SSL_UNRECOGNIZED_NAME_ALERT")) {
return {
headline: "Domain nicht erreichbar",
description: (
<>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.
{" "}
<br />
Der Scan wurde abgebrochen, da das SSL-Zertifikat der Website nicht erkannt oder validiert werden konnte.
Bitte überprüfe das Zertifikat und starte den Scan erneut.
</>
),
showEditDomain: false,
};
}

return undefined;
};

export const ErrorScan: FC<{ profile: ScanProfile; lastScan: Scan }> = ({
lastScan,
profile,
}) => {
const errorInfos = lastScan.error ? getErrorTexts(lastScan.error, profile) : undefined;

if (errorInfos?.showEditDomain) {
return (
<ErrorViewWithEditDomain
profile={profile}
scanId={lastScan._id}
headline={errorInfos.headline}
description={errorInfos.description}
/>
);
}
if (lastScan.error?.startsWith("net::ERR_CERT_")) {
return <CertificateErrorView profile={profile} scanId={lastScan._id} />;
if (errorInfos) {
return (
<ErrorViewWithoutEditDomain
profile={profile}
scanId={lastScan._id}
headline={errorInfos.headline}
description={errorInfos.description}
/>
);
}

return (
<DefaultErrorView
profile={profile}
message={lastScan.error!}
message={lastScan.error ?? ""}
scanId={lastScan._id}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,37 @@ import {
import { RestartScanButton } from "./restartScanButton.js";
import { ChangeDomainModal } from "../modals/changeDomainModal.js";

export const DnsErrorView: FC<Props> = ({ profile, scanId }) => {
export const ErrorViewWithEditDomain: FC<Props> = ({
profile,
scanId,
headline,
description,
}) => {
const controller = useOverlayController("Modal");
const editLabel = "Domain bearbeiten";
const content =
description ?? (
<>
Kontrolliere die Domain auf Richtigkeit und versuche es erneut.
</>
);

return (
<IllustratedMessage color="danger">
<IconDanger />
<Heading>Domain nicht erreichbar</Heading>
<Text>
Die Domain <strong>{profile.domain}</strong> ist nicht erreichbar.{" "}
<br /> Bitte überprüfe die Schreibweise oder versuche es erneut.
</Text>
<Heading>{headline ?? editLabel}</Heading>
<Text>{content}</Text>
<ActionGroup>
<RestartScanButton profile={profile} scanId={scanId} />
<Action onAction={() => controller.open()}>
<Button color="primary">Domain bearbeiten</Button>
<Button color="primary">{editLabel}</Button>
</Action>
</ActionGroup>
<ChangeDomainModal profile={profile} controller={controller} />
<ChangeDomainModal
profile={profile}
controller={controller}
title={editLabel}
/>
</IllustratedMessage>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@ import {
} from "@mittwald/flow-remote-react-components";
import { RestartScanButton } from "./restartScanButton.js";

export const CertificateErrorView: FC<Props> = ({ profile, scanId }) => {
export const ErrorViewWithoutEditDomain: FC<Props> = ({
profile,
headline,
description,
scanId,
}) => {
return (
<IllustratedMessage color="danger">
<IconDanger />
<Heading>SSL-Zertifikat ungültig</Heading>
<Heading>{headline ?? "Letzter Scan fehlgeschlagen"}</Heading>
<Text>
Das SSL-Zertifikat der Domain <strong>{profile.domain}</strong> ist
ungültig. <br /> Binde ein gültiges Zertifikat ein und starte den Scan
erneut.
{description ?? (
<>
Beim Scan ist folgender Fehler aufgetreten.
<br />
Bitte versuche es erneut.
</>
)}
</Text>
<RestartScanButton profile={profile} scanId={scanId} />
</IllustratedMessage>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ export const DefaultErrorView: FC<Props & { message: string }> = ({
</IllustratedMessage>
);
};




3 changes: 3 additions & 0 deletions packages/web2/app/components/profile/errorScans/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ReactNode } from "react";
import { ScanProfile } from "../../../api/types.js";

export interface Props {
profile: ScanProfile;
scanId: string;
headline?: string;
description?: ReactNode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ interface FormValues {
domain: string;
}

interface ChangeDomainModalProps {
controller: OverlayController;
profile: ScanProfile;
title?: string;
}

export const ChangeDomainModal = ({
controller,
profile,
}: {
controller: OverlayController;
profile: ScanProfile;
}) => {
title = "Domain bearbeiten",
}: ChangeDomainModalProps) => {
const router = useRouter();

const form = useForm<FormValues>({
Expand All @@ -50,7 +54,7 @@ export const ChangeDomainModal = ({
return (
<Modal controller={controller}>
<Form form={form} onSubmit={onSubmit}>
<Heading slot="title">Domain bearbeiten</Heading>
<Heading slot="title">{title}</Heading>
<Content>
<Section>
<Domain
Expand Down