translations

This commit is contained in:
Anthony Stirling 2025-09-04 16:29:05 +01:00
parent ac8ced8a03
commit bf03a6011b
7 changed files with 94 additions and 47 deletions

View File

@ -14,7 +14,13 @@
"Bash(node:*)", "Bash(node:*)",
"Bash(npm run dev:*)", "Bash(npm run dev:*)",
"Bash(sed:*)", "Bash(sed:*)",
"Bash(npm run typecheck:*)" "Bash(npm run typecheck:*)",
"Bash(echo:*)",
"Bash(keys=\"files.placeholder signMode.stepTitle certTypeStep.stepTitle certFiles.stepTitle appearance.stepTitle appearance.title appearance.invisible appearance.visible appearance.options.title sign.submit sign.results choosePrivateKey chooseCertificate chooseP12File choosePfxFile chooseJksFile password passwordOptional serverCertMessage reason location name showLogo pageNumber logoTitle noLogo\")",
"Bash(__NEW_LINE__ echo \"\")",
"Bash(for key in $keys)",
"Bash(do)",
"Bash(done)"
], ],
"deny": [], "deny": [],
"defaultMode": "acceptEdits" "defaultMode": "acceptEdits"

View File

@ -1396,26 +1396,27 @@
"location": "Location", "location": "Location",
"name": "Name", "name": "Name",
"showLogo": "Show Logo", "showLogo": "Show Logo",
"submit": "Sign PDF" "submit": "Sign PDF",
},
"manageSignatures": {
"tags": "sign,certificate,PEM,PKCS12,JKS,server,manual,auto",
"title": "Manage Signatures",
"header": "Sign PDFs with Certificates",
"files": { "files": {
"placeholder": "Select PDF files to sign with certificates" "placeholder": "Select PDF files to sign with certificates"
}, },
"signMode": { "signMode": {
"stepTitle": "Sign Mode" "stepTitle": "Sign Mode"
}, },
"certType": { "certTypeStep": {
"stepTitle": "Certificate Format" "stepTitle": "Certificate Format"
}, },
"certFiles": { "certFiles": {
"stepTitle": "Certificate Files" "stepTitle": "Certificate Files"
}, },
"appearance": { "appearance": {
"stepTitle": "Signature Appearance" "stepTitle": "Signature Appearance",
"title": "Signature Appearance",
"invisible": "Invisible",
"visible": "Visible",
"options": {
"title": "Signature Details"
}
}, },
"sign": { "sign": {
"submit": "Sign PDF", "submit": "Sign PDF",
@ -1423,7 +1424,22 @@
}, },
"error": { "error": {
"failed": "An error occurred whilst signing the PDF." "failed": "An error occurred whilst signing the PDF."
} },
"choosePrivateKey": "Choose Private Key File",
"chooseCertificate": "Choose Certificate File",
"chooseP12File": "Choose PKCS12 File",
"choosePfxFile": "Choose PFX File",
"chooseJksFile": "Choose JKS File",
"passwordOptional": "Leave empty if no password",
"serverCertMessage": "Using server certificate - no files or password required",
"pageNumber": "Page Number",
"logoTitle": "Logo",
"noLogo": "No Logo"
},
"manageSignatures": {
"tags": "sign,certificate,PEM,PKCS12,JKS,server,manual,auto",
"title": "Manage Signatures",
"desc": "Sign PDFs with certificates using manual or server-managed keys"
}, },
"removeCertSign": { "removeCertSign": {
"tags": "authenticate,PEM,P12,official,decrypt", "tags": "authenticate,PEM,P12,official,decrypt",

View File

@ -20,17 +20,17 @@ const CertificateFilesSettings = ({ parameters, onParameterChange, disabled = fa
<FileUploadButton <FileUploadButton
file={parameters.privateKeyFile} file={parameters.privateKeyFile}
onChange={(file) => onParameterChange('privateKeyFile', file || undefined)} onChange={(file) => onParameterChange('privateKeyFile', file || undefined)}
accept=".pem,.der" accept=".pem,.der,.key"
disabled={disabled} disabled={disabled}
placeholder={t('manageSignatures.signing.choosePrivateKey', 'Choose Private Key File')} placeholder={t('certSign.choosePrivateKey', 'Choose Private Key File')}
/> />
{parameters.privateKeyFile && ( {parameters.privateKeyFile && (
<FileUploadButton <FileUploadButton
file={parameters.certFile} file={parameters.certFile}
onChange={(file) => onParameterChange('certFile', file || undefined)} onChange={(file) => onParameterChange('certFile', file || undefined)}
accept=".pem,.der" accept=".pem,.der,.crt,.cer"
disabled={disabled} disabled={disabled}
placeholder={t('manageSignatures.signing.chooseCertificate', 'Choose Certificate File')} placeholder={t('certSign.chooseCertificate', 'Choose Certificate File')}
/> />
)} )}
</Stack> </Stack>
@ -40,9 +40,19 @@ const CertificateFilesSettings = ({ parameters, onParameterChange, disabled = fa
<FileUploadButton <FileUploadButton
file={parameters.p12File} file={parameters.p12File}
onChange={(file) => onParameterChange('p12File', file || undefined)} onChange={(file) => onParameterChange('p12File', file || undefined)}
accept=".p12,.pfx" accept=".p12"
disabled={disabled} disabled={disabled}
placeholder={t('manageSignatures.signing.chooseP12File', 'Choose PKCS12 File')} placeholder={t('certSign.chooseP12File', 'Choose PKCS12 File')}
/>
)}
{parameters.certType === 'PFX' && (
<FileUploadButton
file={parameters.p12File}
onChange={(file) => onParameterChange('p12File', file || undefined)}
accept=".pfx"
disabled={disabled}
placeholder={t('certSign.choosePfxFile', 'Choose PFX File')}
/> />
)} )}
@ -52,13 +62,13 @@ const CertificateFilesSettings = ({ parameters, onParameterChange, disabled = fa
onChange={(file) => onParameterChange('jksFile', file || undefined)} onChange={(file) => onParameterChange('jksFile', file || undefined)}
accept=".jks,.keystore" accept=".jks,.keystore"
disabled={disabled} disabled={disabled}
placeholder={t('manageSignatures.signing.chooseJksFile', 'Choose JKS File')} placeholder={t('certSign.chooseJksFile', 'Choose JKS File')}
/> />
)} )}
{parameters.certType === 'SERVER' && ( {parameters.certType === 'SERVER' && (
<Text c="dimmed" size="sm"> <Text c="dimmed" size="sm">
{t('manageSignatures.signing.serverCertMessage', 'Using server certificate - no files or password required')} {t('certSign.serverCertMessage', 'Using server certificate - no files or password required')}
</Text> </Text>
)} )}
@ -66,11 +76,12 @@ const CertificateFilesSettings = ({ parameters, onParameterChange, disabled = fa
{parameters.certType && ( {parameters.certType && (
(parameters.certType === 'PEM' && parameters.privateKeyFile && parameters.certFile) || (parameters.certType === 'PEM' && parameters.privateKeyFile && parameters.certFile) ||
(parameters.certType === 'PKCS12' && parameters.p12File) || (parameters.certType === 'PKCS12' && parameters.p12File) ||
(parameters.certType === 'PFX' && parameters.p12File) ||
(parameters.certType === 'JKS' && parameters.jksFile) (parameters.certType === 'JKS' && parameters.jksFile)
) && ( ) && (
<TextInput <TextInput
label={t('manageSignatures.signing.password', 'Certificate Password')} label={t('certSign.password', 'Certificate Password')}
placeholder={t('manageSignatures.signing.passwordOptional', 'Leave empty if no password')} placeholder={t('certSign.passwordOptional', 'Leave empty if no password')}
type="password" type="password"
value={parameters.password} value={parameters.password}
onChange={(event) => onParameterChange('password', event.currentTarget.value)} onChange={(event) => onParameterChange('password', event.currentTarget.value)}

View File

@ -14,7 +14,7 @@ const CertificateFormatSettings = ({ parameters, onParameterChange, disabled = f
return ( return (
<Stack gap="md"> <Stack gap="md">
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
{/* First row - PKCS#12 and PEM */} {/* First row - PKCS#12 and PFX */}
<div style={{ display: 'flex', gap: '4px' }}> <div style={{ display: 'flex', gap: '4px' }}>
<Button <Button
variant={parameters.certType === 'PKCS12' ? 'filled' : 'outline'} variant={parameters.certType === 'PKCS12' ? 'filled' : 'outline'}
@ -24,9 +24,23 @@ const CertificateFormatSettings = ({ parameters, onParameterChange, disabled = f
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }} style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
> >
<div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}> <div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}>
PKCS#12<br />(Single file) PKCS#12<br />(.p12 file)
</div> </div>
</Button> </Button>
<Button
variant={parameters.certType === 'PFX' ? 'filled' : 'outline'}
color={parameters.certType === 'PFX' ? 'blue' : 'var(--text-muted)'}
onClick={() => onParameterChange('certType', 'PFX')}
disabled={disabled}
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
>
<div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}>
PFX<br />(.pfx file)
</div>
</Button>
</div>
{/* Second row - PEM and JKS */}
<div style={{ display: 'flex', gap: '4px' }}>
<Button <Button
variant={parameters.certType === 'PEM' ? 'filled' : 'outline'} variant={parameters.certType === 'PEM' ? 'filled' : 'outline'}
color={parameters.certType === 'PEM' ? 'blue' : 'var(--text-muted)'} color={parameters.certType === 'PEM' ? 'blue' : 'var(--text-muted)'}
@ -38,15 +52,12 @@ const CertificateFormatSettings = ({ parameters, onParameterChange, disabled = f
PEM<br />(Key + Cert files) PEM<br />(Key + Cert files)
</div> </div>
</Button> </Button>
</div>
{/* Second row - JKS spanning full width */}
<div style={{ display: 'flex', gap: '4px' }}>
<Button <Button
variant={parameters.certType === 'JKS' ? 'filled' : 'outline'} variant={parameters.certType === 'JKS' ? 'filled' : 'outline'}
color={parameters.certType === 'JKS' ? 'blue' : 'var(--text-muted)'} color={parameters.certType === 'JKS' ? 'blue' : 'var(--text-muted)'}
onClick={() => onParameterChange('certType', 'JKS')} onClick={() => onParameterChange('certType', 'JKS')}
disabled={disabled} disabled={disabled}
style={{ width: '100%', height: 'auto', minHeight: '40px', fontSize: '11px' }} style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
> >
<div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}> <div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}>
JKS<br />(Java KeyStore) JKS<br />(Java KeyStore)
@ -55,8 +66,9 @@ const CertificateFormatSettings = ({ parameters, onParameterChange, disabled = f
</div> </div>
</div> </div>
<Text size="xs" c="dimmed"> <Text size="xs" c="dimmed">
{parameters.certType === 'PKCS12' && "Upload a single .p12/.pfx file containing both certificate and private key"} {parameters.certType === 'PKCS12' && "Upload a single .p12 file containing both certificate and private key"}
{parameters.certType === 'PEM' && "Upload separate certificate (.crt/.pem) and private key (.key/.pem) files"} {parameters.certType === 'PFX' && "Upload a single .pfx file containing both certificate and private key"}
{parameters.certType === 'PEM' && "Upload separate certificate (.pem/.der/.crt/.cer) and private key (.pem/.der/.key) files"}
{parameters.certType === 'JKS' && "Upload a Java KeyStore (.jks) file"} {parameters.certType === 'JKS' && "Upload a Java KeyStore (.jks) file"}
{!parameters.certType && "Choose the format of your certificate files"} {!parameters.certType && "Choose the format of your certificate files"}
</Text> </Text>

View File

@ -16,7 +16,7 @@ const SignatureAppearanceSettings = ({ parameters, onParameterChange, disabled =
{/* Signature Visibility */} {/* Signature Visibility */}
<Stack gap="sm"> <Stack gap="sm">
<Text size="sm" fw={500}> <Text size="sm" fw={500}>
{t('manageSignatures.appearance.title', 'Signature Appearance')} {t('certSign.appearance.title', 'Signature Appearance')}
</Text> </Text>
<div style={{ display: 'flex', gap: '4px' }}> <div style={{ display: 'flex', gap: '4px' }}>
<Button <Button
@ -27,7 +27,7 @@ const SignatureAppearanceSettings = ({ parameters, onParameterChange, disabled =
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }} style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
> >
<div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}> <div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}>
{t('manageSignatures.appearance.invisible', 'Invisible')} {t('certSign.appearance.invisible', 'Invisible')}
</div> </div>
</Button> </Button>
<Button <Button
@ -38,7 +38,7 @@ const SignatureAppearanceSettings = ({ parameters, onParameterChange, disabled =
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }} style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
> >
<div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}> <div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}>
{t('manageSignatures.appearance.visible', 'Visible')} {t('certSign.appearance.visible', 'Visible')}
</div> </div>
</Button> </Button>
</div> </div>
@ -48,28 +48,28 @@ const SignatureAppearanceSettings = ({ parameters, onParameterChange, disabled =
{parameters.showSignature && ( {parameters.showSignature && (
<Stack gap="sm"> <Stack gap="sm">
<Text size="sm" fw={500}> <Text size="sm" fw={500}>
{t('manageSignatures.appearance.options.title', 'Signature Details')} {t('certSign.appearance.options.title', 'Signature Details')}
</Text> </Text>
<TextInput <TextInput
label={t('manageSignatures.signing.reason', 'Reason for Signing')} label={t('certSign.reason', 'Reason')}
value={parameters.reason} value={parameters.reason}
onChange={(event) => onParameterChange('reason', event.currentTarget.value)} onChange={(event) => onParameterChange('reason', event.currentTarget.value)}
disabled={disabled} disabled={disabled}
/> />
<TextInput <TextInput
label={t('manageSignatures.signing.location', 'Location')} label={t('certSign.location', 'Location')}
value={parameters.location} value={parameters.location}
onChange={(event) => onParameterChange('location', event.currentTarget.value)} onChange={(event) => onParameterChange('location', event.currentTarget.value)}
disabled={disabled} disabled={disabled}
/> />
<TextInput <TextInput
label={t('manageSignatures.signing.name', 'Signer Name')} label={t('certSign.name', 'Name')}
value={parameters.name} value={parameters.name}
onChange={(event) => onParameterChange('name', event.currentTarget.value)} onChange={(event) => onParameterChange('name', event.currentTarget.value)}
disabled={disabled} disabled={disabled}
/> />
<NumberInput <NumberInput
label={t('manageSignatures.signing.pageNumber', 'Page Number')} label={t('certSign.pageNumber', 'Page Number')}
value={parameters.pageNumber} value={parameters.pageNumber}
onChange={(value) => onParameterChange('pageNumber', value || 1)} onChange={(value) => onParameterChange('pageNumber', value || 1)}
min={1} min={1}
@ -77,7 +77,7 @@ const SignatureAppearanceSettings = ({ parameters, onParameterChange, disabled =
/> />
<Stack gap="xs"> <Stack gap="xs">
<Text size="sm" fw={500}> <Text size="sm" fw={500}>
{t('manageSignatures.signing.logoTitle', 'Logo')} {t('certSign.logoTitle', 'Logo')}
</Text> </Text>
<div style={{ display: 'flex', gap: '4px' }}> <div style={{ display: 'flex', gap: '4px' }}>
<Button <Button
@ -88,7 +88,7 @@ const SignatureAppearanceSettings = ({ parameters, onParameterChange, disabled =
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }} style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
> >
<div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}> <div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}>
{t('manageSignatures.signing.noLogo', 'No Logo')} {t('certSign.noLogo', 'No Logo')}
</div> </div>
</Button> </Button>
<Button <Button
@ -99,7 +99,7 @@ const SignatureAppearanceSettings = ({ parameters, onParameterChange, disabled =
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }} style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
> >
<div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}> <div style={{ textAlign: 'center', lineHeight: '1.1', fontSize: '11px' }}>
{t('manageSignatures.signing.showLogo', 'Show Logo')} {t('certSign.showLogo', 'Show Logo')}
</div> </div>
</Button> </Button>
</div> </div>

View File

@ -5,7 +5,7 @@ export interface ManageSignaturesParameters extends BaseParameters {
// Sign mode selection // Sign mode selection
signMode: 'MANUAL' | 'AUTO'; signMode: 'MANUAL' | 'AUTO';
// Certificate signing options (only for manual mode) // Certificate signing options (only for manual mode)
certType: '' | 'PEM' | 'PKCS12' | 'JKS'; certType: '' | 'PEM' | 'PKCS12' | 'PFX' | 'JKS';
privateKeyFile?: File; privateKeyFile?: File;
certFile?: File; certFile?: File;
p12File?: File; p12File?: File;
@ -55,6 +55,7 @@ export const useManageSignaturesParameters = (): ManageSignaturesParametersHook
case 'PEM': case 'PEM':
return !!(params.privateKeyFile && params.certFile); return !!(params.privateKeyFile && params.certFile);
case 'PKCS12': case 'PKCS12':
case 'PFX':
return !!params.p12File; return !!params.p12File;
case 'JKS': case 'JKS':
return !!params.jksFile; return !!params.jksFile;

View File

@ -38,6 +38,7 @@ const ManageSignatures = (props: BaseToolProps) => {
case 'PEM': case 'PEM':
return !!(params.privateKeyFile && params.certFile); return !!(params.privateKeyFile && params.certFile);
case 'PKCS12': case 'PKCS12':
case 'PFX':
return !!params.p12File; return !!params.p12File;
case 'JKS': case 'JKS':
return !!params.jksFile; return !!params.jksFile;
@ -51,11 +52,11 @@ const ManageSignatures = (props: BaseToolProps) => {
files: { files: {
selectedFiles: base.selectedFiles, selectedFiles: base.selectedFiles,
isCollapsed: base.hasResults, isCollapsed: base.hasResults,
placeholder: t("manageSignatures.files.placeholder", "Select PDF files to sign with certificates"), placeholder: t("certSign.files.placeholder", "Select PDF files to sign with certificates"),
}, },
steps: [ steps: [
{ {
title: t("manageSignatures.signMode.stepTitle", "Sign Mode"), title: t("certSign.signMode.stepTitle", "Sign Mode"),
isCollapsed: base.settingsCollapsed, isCollapsed: base.settingsCollapsed,
onCollapsedClick: base.settingsCollapsed ? base.handleSettingsReset : undefined, onCollapsedClick: base.settingsCollapsed ? base.handleSettingsReset : undefined,
content: ( content: (
@ -67,7 +68,7 @@ const ManageSignatures = (props: BaseToolProps) => {
), ),
}, },
...(base.params.parameters.signMode === 'MANUAL' ? [{ ...(base.params.parameters.signMode === 'MANUAL' ? [{
title: t("manageSignatures.certType.stepTitle", "Certificate Format"), title: t("certSign.certTypeStep.stepTitle", "Certificate Format"),
isCollapsed: base.settingsCollapsed, isCollapsed: base.settingsCollapsed,
onCollapsedClick: base.settingsCollapsed ? base.handleSettingsReset : undefined, onCollapsedClick: base.settingsCollapsed ? base.handleSettingsReset : undefined,
tooltip: certTypeTips, tooltip: certTypeTips,
@ -80,7 +81,7 @@ const ManageSignatures = (props: BaseToolProps) => {
), ),
}] : []), }] : []),
...(base.params.parameters.signMode === 'MANUAL' ? [{ ...(base.params.parameters.signMode === 'MANUAL' ? [{
title: t("manageSignatures.certFiles.stepTitle", "Certificate Files"), title: t("certSign.certFiles.stepTitle", "Certificate Files"),
isCollapsed: base.settingsCollapsed, isCollapsed: base.settingsCollapsed,
onCollapsedClick: base.settingsCollapsed ? base.handleSettingsReset : undefined, onCollapsedClick: base.settingsCollapsed ? base.handleSettingsReset : undefined,
content: ( content: (
@ -92,7 +93,7 @@ const ManageSignatures = (props: BaseToolProps) => {
), ),
}] : []), }] : []),
{ {
title: t("manageSignatures.appearance.stepTitle", "Signature Appearance"), title: t("certSign.appearance.stepTitle", "Signature Appearance"),
isCollapsed: base.settingsCollapsed || !areCertFilesConfigured(), isCollapsed: base.settingsCollapsed || !areCertFilesConfigured(),
onCollapsedClick: (base.settingsCollapsed || !areCertFilesConfigured()) ? base.handleSettingsReset : undefined, onCollapsedClick: (base.settingsCollapsed || !areCertFilesConfigured()) ? base.handleSettingsReset : undefined,
tooltip: appearanceTips, tooltip: appearanceTips,
@ -106,7 +107,7 @@ const ManageSignatures = (props: BaseToolProps) => {
}, },
], ],
executeButton: { executeButton: {
text: t("manageSignatures.sign.submit", "Sign PDF"), text: t("certSign.sign.submit", "Sign PDF"),
isVisible: !base.hasResults, isVisible: !base.hasResults,
loadingText: t("loading"), loadingText: t("loading"),
onClick: base.handleExecute, onClick: base.handleExecute,
@ -115,7 +116,7 @@ const ManageSignatures = (props: BaseToolProps) => {
review: { review: {
isVisible: base.hasResults, isVisible: base.hasResults,
operation: base.operation, operation: base.operation,
title: t("manageSignatures.sign.results", "Signed PDF"), title: t("certSign.sign.results", "Signed PDF"),
onFileClick: base.handleThumbnailClick, onFileClick: base.handleThumbnailClick,
onUndo: base.handleUndo, onUndo: base.handleUndo,
}, },