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';
8 import { hasValidAnonymousSignature } from './hasValidAnonymousSignature';
12 signatureIssues: SignatureIssues | undefined;
13 signatureNetworkError?: boolean;
14 signatureAddress: string | undefined;
17 corruptedLink?: boolean;
21 export default function SignatureAlert({
25 signatureNetworkError,
32 <Alert type="info" className={className}>
33 <TextLoader className="m-0">{c('Info').t`Checking signatures`}</TextLoader>
40 <Alert type="warning" className={className}>
42 .t`Unfortunately, it appears that the file or some of its data cannot be decrypted.`}</span>
47 if (signatureNetworkError) {
49 <Alert type="warning" className={className}>
50 <span>{c('Info').t`Signature cannot be validated due to network error, please try again later.`}</span>
55 const validAnonymousSignature =
56 !!signatureIssues && !signatureAddress && hasValidAnonymousSignature(signatureIssues);
59 <Alert type={signatureIssues && !validAnonymousSignature ? 'error' : 'success'} className={className}>
61 signatureIssues={signatureIssues}
62 signatureAddress={signatureAddress}
63 validAnonymousSignature={validAnonymousSignature}
71 signatureIssues: SignatureIssues | undefined;
72 signatureAddress: string | undefined;
75 validAnonymousSignature?: boolean;
78 export function SignatureAlertBody({
81 validAnonymousSignature,
86 <strong className="text-break" key="fileName">
91 const emailAddress = (
92 <strong className="text-break" key="signatureAddress" data-testid="signature-address">
93 {signatureAddress || c('Info').t`an anonymous user`}
97 if (!signatureIssues) {
101 ? c('Info').jt`Digital signature verified. This file was securely uploaded by ${emailAddress}.`
102 : c('Info').jt`Digital signature verified. This folder was securely uploaded by ${emailAddress}.`}
109 (validAnonymousSignature === undefined ? hasValidAnonymousSignature(signatureIssues) : validAnonymousSignature)
115 .jt`The digital signature has been partially verified. The file was uploaded from a public page that does not specify a specific user origin.`
117 .jt`The digital signature has been partially verified. The folder was uploaded from a public page that does not specify a specific user origin.`}
122 const locationTranslations: { [key in SignatureIssueLocation]: string } = {
123 passphrase: c('Item').t`keys`,
124 hash: c('Item').t`hash key`,
125 name: c('Item').t`name`,
126 xattrs: c('Item').t`file attributes`,
127 contentKeyPacket: c('Item').t`file data key`,
128 blocks: c('Item').t`file data`,
129 thumbnail: c('Item').t`thumbnail`,
130 manifest: c('Item').t`file data order`,
132 const items = Object.keys(signatureIssues)
133 .map((location) => locationTranslations[location as SignatureIssueLocation])
136 const statuses = Object.values(signatureIssues);
137 const hasNoSignatureIssue = statuses.some((status) => status === VERIFICATION_STATUS.NOT_SIGNED);
138 const hasBadSignatureIssue = statuses.some((status) => status === VERIFICATION_STATUS.SIGNED_AND_INVALID);
142 if (hasNoSignatureIssue && !hasBadSignatureIssue) {
143 if (signatureAddress) {
145 ? c('Info').jt`File is missing signature. We couldn’t verify that ${emailAddress} uploaded ${fileName}.`
147 .jt`Folder is missing signature. We couldn’t verify that ${emailAddress} uploaded ${fileName}.`;
150 ? c('Info').jt`File is missing signature. We couldn’t verify who uploaded ${fileName}.`
151 : c('Info').jt`Folder is missing signature. We couldn’t verify who uploaded ${fileName}.`;
153 textWarning = c('Info').jt`The following may have been tampered with: ${items}. Only open if you trust it.`;
155 if (signatureAddress) {
156 textReason = c('Info').jt`We couldn’t verify that ${emailAddress} uploaded ${fileName}.`;
157 textWarning = c('Info')
158 .jt`The account may have a new key, or the following may have been tampered with: ${items}. Only open if you trust it.`;
160 textReason = c('Info').jt`We couldn’t verify who uploaded ${fileName}.`;
161 textWarning = c('Info').jt`The following may have been tampered with: ${items}. Only open if you trust it.`;
171 <a href={getKnowledgeBaseUrl('/drive-signature-management')} target="_blank">
172 {c('Action').t`Learn more`}