1 import { c } from 'ttag';
3 import { Alert, TextLoader } from '@proton/components';
4 import { VERIFICATION_STATUS } from '@proton/crypto';
5 import { getKnowledgeBaseUrl } from '@proton/shared/lib/helpers/url';
7 import type { SignatureIssueLocation, SignatureIssues } from '../store';
11 signatureIssues: SignatureIssues | undefined;
12 signatureNetworkError?: boolean;
13 signatureAddress: string | undefined;
16 corruptedLink?: boolean;
20 export default function SignatureAlert({
23 signatureNetworkError,
30 <Alert type="info" className={className}>
31 <TextLoader className="m-0">{c('Info').t`Checking signatures`}</TextLoader>
38 <Alert type="warning" className={className}>
40 .t`Unfortunately, it appears that the file or some of its data cannot be decrypted.`}</span>
45 if (signatureNetworkError) {
47 <Alert type="warning" className={className}>
48 <span>{c('Info').t`Signature cannot be validated due to network error, please try again later.`}</span>
54 <Alert type={signatureIssues ? 'error' : 'success'} className={className}>
55 <SignatureAlertBody signatureIssues={signatureIssues} {...props} />
61 signatureIssues: SignatureIssues | undefined;
62 signatureAddress: string | undefined;
67 export function SignatureAlertBody({ signatureIssues, signatureAddress, isFile, name }: PropsBody) {
69 <strong className="text-break" key="fileName">
74 const emailAddress = (
75 <strong className="text-break" key="signatureAddress" data-testid="signature-address">
80 if (!signatureIssues) {
84 ? c('Info').jt`Digital signature verified. This file was securely uploaded by ${emailAddress}.`
85 : c('Info').jt`Digital signature verified. This folder was securely uploaded by ${emailAddress}.`}
90 const locationTranslations: { [key in SignatureIssueLocation]: string } = {
91 passphrase: c('Item').t`keys`,
92 hash: c('Item').t`hash key`,
93 name: c('Item').t`name`,
94 xattrs: c('Item').t`file attributes`,
95 contentKeyPacket: c('Item').t`file data key`,
96 blocks: c('Item').t`file data`,
97 thumbnail: c('Item').t`thumbnail`,
98 manifest: c('Item').t`file data order`,
100 const items = Object.keys(signatureIssues)
101 .map((location) => locationTranslations[location as SignatureIssueLocation])
104 const statuses = Object.values(signatureIssues);
105 const hasNoSignatureIssue = statuses.some((status) => status === VERIFICATION_STATUS.NOT_SIGNED);
106 const hasBadSignatureIssue = statuses.some((status) => status === VERIFICATION_STATUS.SIGNED_AND_INVALID);
110 if (hasNoSignatureIssue && !hasBadSignatureIssue) {
111 if (signatureAddress) {
113 ? c('Info').jt`File is missing signature. We couldn’t verify that ${emailAddress} uploaded ${fileName}.`
115 .jt`Folder is missing signature. We couldn’t verify that ${emailAddress} uploaded ${fileName}.`;
118 ? c('Info').jt`File is missing signature. We couldn’t verify who uploaded ${fileName}.`
119 : c('Info').jt`Folder is missing signature. We couldn’t verify who uploaded ${fileName}.`;
121 textWarning = c('Info').jt`The following may have been tampered with: ${items}. Only open if you trust it.`;
123 if (signatureAddress) {
124 textReason = c('Info').jt`We couldn’t verify that ${emailAddress} uploaded ${fileName}.`;
125 textWarning = c('Info')
126 .jt`The account may have a new key, or the following may have been tampered with: ${items}. Only open if you trust it.`;
128 textReason = c('Info').jt`We couldn’t verify who uploaded ${fileName}.`;
129 textWarning = c('Info').jt`The following may have been tampered with: ${items}. Only open if you trust it.`;
139 <a href={getKnowledgeBaseUrl('/drive-signature-management')} target="_blank">
140 {c('Action').t`Learn more`}