|
@@ -1,100 +1,94 @@
|
|
|
-import {RouteComponentProps} from 'react-router';
|
|
|
-
|
|
|
import ExternalLink from 'sentry/components/links/externalLink';
|
|
|
+import LoadingError from 'sentry/components/loadingError';
|
|
|
+import LoadingIndicator from 'sentry/components/loadingIndicator';
|
|
|
import Panel from 'sentry/components/panels/panel';
|
|
|
import PanelBody from 'sentry/components/panels/panelBody';
|
|
|
import PanelHeader from 'sentry/components/panels/panelHeader';
|
|
|
import PreviewFeature from 'sentry/components/previewFeature';
|
|
|
+import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
|
|
|
import {t, tct} from 'sentry/locale';
|
|
|
-import {Organization, ProjectKey} from 'sentry/types';
|
|
|
+import {ProjectKey} from 'sentry/types';
|
|
|
+import {useApiQuery} from 'sentry/utils/queryClient';
|
|
|
import routeTitleGen from 'sentry/utils/routeTitle';
|
|
|
-import withOrganization from 'sentry/utils/withOrganization';
|
|
|
-import DeprecatedAsyncView from 'sentry/views/deprecatedAsyncView';
|
|
|
+import useOrganization from 'sentry/utils/useOrganization';
|
|
|
+import {useParams} from 'sentry/utils/useParams';
|
|
|
import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
|
|
|
import ReportUri, {
|
|
|
getSecurityDsn,
|
|
|
} from 'sentry/views/settings/projectSecurityHeaders/reportUri';
|
|
|
|
|
|
-type Props = RouteComponentProps<{projectId: string}, {}> & {
|
|
|
- organization: Organization;
|
|
|
-};
|
|
|
+function getInstructions(keyList: ProjectKey[]) {
|
|
|
+ return `Expect-CT: report-uri="${getSecurityDsn(keyList)}"`;
|
|
|
+}
|
|
|
|
|
|
-type State = {
|
|
|
- keyList: null | ProjectKey[];
|
|
|
-} & DeprecatedAsyncView['state'];
|
|
|
+function ProjectExpectCtReports() {
|
|
|
+ const organization = useOrganization();
|
|
|
+ const {projectId} = useParams();
|
|
|
|
|
|
-class ProjectExpectCtReports extends DeprecatedAsyncView<Props, State> {
|
|
|
- getEndpoints(): ReturnType<DeprecatedAsyncView['getEndpoints']> {
|
|
|
- const {organization} = this.props;
|
|
|
- const {projectId} = this.props.params;
|
|
|
- return [['keyList', `/projects/${organization.slug}/${projectId}/keys/`]];
|
|
|
- }
|
|
|
+ const {
|
|
|
+ data: keyList,
|
|
|
+ isLoading,
|
|
|
+ isError,
|
|
|
+ refetch,
|
|
|
+ } = useApiQuery<ProjectKey[]>([`/projects/${organization.slug}/${projectId}/keys/`], {
|
|
|
+ staleTime: 0,
|
|
|
+ });
|
|
|
|
|
|
- getTitle() {
|
|
|
- const {projectId} = this.props.params;
|
|
|
- return routeTitleGen(t('Certificate Transparency (Expect-CT)'), projectId, false);
|
|
|
+ if (isLoading) {
|
|
|
+ return <LoadingIndicator />;
|
|
|
}
|
|
|
|
|
|
- getInstructions(keyList: ProjectKey[]) {
|
|
|
- return `Expect-CT: report-uri="${getSecurityDsn(keyList)}"`;
|
|
|
+ if (isError) {
|
|
|
+ return <LoadingError onRetry={refetch} />;
|
|
|
}
|
|
|
|
|
|
- renderBody() {
|
|
|
- const {organization, params} = this.props;
|
|
|
- const {keyList} = this.state;
|
|
|
- if (!keyList) {
|
|
|
- return null;
|
|
|
- }
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <SentryDocumentTitle
|
|
|
+ title={routeTitleGen(t('Certificate Transparency (Expect-CT)'), projectId, false)}
|
|
|
+ />
|
|
|
+ <SettingsPageHeader title={t('Certificate Transparency')} />
|
|
|
|
|
|
- return (
|
|
|
- <div>
|
|
|
- <SettingsPageHeader title={t('Certificate Transparency')} />
|
|
|
+ <PreviewFeature />
|
|
|
|
|
|
- <PreviewFeature />
|
|
|
+ <ReportUri keyList={keyList} orgId={organization.slug} projectId={projectId} />
|
|
|
|
|
|
- <ReportUri
|
|
|
- keyList={keyList}
|
|
|
- orgId={organization.slug}
|
|
|
- projectId={params.projectId}
|
|
|
- />
|
|
|
-
|
|
|
- <Panel>
|
|
|
- <PanelHeader>{t('About')}</PanelHeader>
|
|
|
- <PanelBody withPadding>
|
|
|
- <p>
|
|
|
- {tct(
|
|
|
- `[link:Certificate Transparency]
|
|
|
+ <Panel>
|
|
|
+ <PanelHeader>{t('About')}</PanelHeader>
|
|
|
+ <PanelBody withPadding>
|
|
|
+ <p>
|
|
|
+ {tct(
|
|
|
+ `[link:Certificate Transparency]
|
|
|
(CT) is a security standard which helps track and identify valid certificates, allowing identification of maliciously issued certificates`,
|
|
|
- {
|
|
|
- link: (
|
|
|
- <ExternalLink href="https://en.wikipedia.org/wiki/Certificate_Transparency" />
|
|
|
- ),
|
|
|
- }
|
|
|
- )}
|
|
|
- </p>
|
|
|
- <p>
|
|
|
- {tct(
|
|
|
- "To configure reports in Sentry, you'll need to configure the [header] a header from your server:",
|
|
|
- {
|
|
|
- header: <code>Expect-CT</code>,
|
|
|
- }
|
|
|
- )}
|
|
|
- </p>
|
|
|
-
|
|
|
- <pre>{this.getInstructions(keyList)}</pre>
|
|
|
-
|
|
|
- <p>
|
|
|
- {tct('For more information, see [link:the article on MDN].', {
|
|
|
+ {
|
|
|
link: (
|
|
|
- <ExternalLink href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT" />
|
|
|
+ <ExternalLink href="https://en.wikipedia.org/wiki/Certificate_Transparency" />
|
|
|
),
|
|
|
- })}
|
|
|
- </p>
|
|
|
- </PanelBody>
|
|
|
- </Panel>
|
|
|
- </div>
|
|
|
- );
|
|
|
- }
|
|
|
+ }
|
|
|
+ )}
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ {tct(
|
|
|
+ "To configure reports in Sentry, you'll need to configure the [header] a header from your server:",
|
|
|
+ {
|
|
|
+ header: <code>Expect-CT</code>,
|
|
|
+ }
|
|
|
+ )}
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <pre>{getInstructions(keyList)}</pre>
|
|
|
+
|
|
|
+ <p>
|
|
|
+ {tct('For more information, see [link:the article on MDN].', {
|
|
|
+ link: (
|
|
|
+ <ExternalLink href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT" />
|
|
|
+ ),
|
|
|
+ })}
|
|
|
+ </p>
|
|
|
+ </PanelBody>
|
|
|
+ </Panel>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
-export default withOrganization(ProjectExpectCtReports);
|
|
|
+export default ProjectExpectCtReports;
|