Compare commits
9 Commits
v0.31.0
...
fix-sig-lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b094634799 | ||
|
|
9e597a4390 | ||
|
|
febc3cf48b | ||
|
|
c5abb47403 | ||
|
|
0e3c9bcc10 | ||
|
|
384c3ee88f | ||
|
|
5f7a0537f9 | ||
|
|
5aa5628465 | ||
|
|
0d91bca932 |
1
.github/pull_request_template.md
vendored
1
.github/pull_request_template.md
vendored
@@ -8,6 +8,7 @@ Closes #(issue_number)
|
|||||||
|
|
||||||
- [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
|
- [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
|
||||||
- [ ] I have performed a self-review of my own code
|
- [ ] I have performed a self-review of my own code
|
||||||
|
- [ ] I have attached images of the change if it is UI based
|
||||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||||
- [ ] My changes generate no new warnings
|
- [ ] My changes generate no new warnings
|
||||||
- [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only)
|
- [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only)
|
||||||
|
|||||||
39
README.md
39
README.md
@@ -280,14 +280,44 @@ security:
|
|||||||
useAsUsername: email # Default is 'email'; custom fields can be used as the username
|
useAsUsername: email # Default is 'email'; custom fields can be used as the username
|
||||||
scopes: openid, profile, email # Specify the scopes for which the application will request permissions
|
scopes: openid, profile, email # Specify the scopes for which the application will request permissions
|
||||||
provider: google # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
|
provider: google # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
|
||||||
|
saml2:
|
||||||
|
enabled: false # Currently in alpha, not recommended for use yet, enableAlphaFunctionality must be set to true
|
||||||
|
autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
|
||||||
|
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
|
||||||
|
registrationId: stirling
|
||||||
|
idpMetadataUri: https://dev-XXXXXXXX.okta.com/app/externalKey/sso/saml/metadata
|
||||||
|
idpSingleLogoutUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/slo/saml
|
||||||
|
idpSingleLoginUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/sso/saml
|
||||||
|
idpIssuer: http://www.okta.com/externalKey
|
||||||
|
idpCert: classpath:octa.crt
|
||||||
|
privateKey: classpath:saml-private-key.key
|
||||||
|
spCert: classpath:saml-public-cert.crt
|
||||||
|
|
||||||
|
enterpriseEdition:
|
||||||
|
enabled: false # set to 'true' to enable enterprise edition
|
||||||
|
key: 00000000-0000-0000-0000-000000000000
|
||||||
|
CustomMetadata:
|
||||||
|
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
||||||
|
author: username # Supports text such as 'John Doe' or types such as username to autopopulate with users username
|
||||||
|
creator: Stirling-PDF # Supports text such as 'Company-PDF'
|
||||||
|
producer: Stirling-PDF # Supports text such as 'Company-PDF'
|
||||||
|
|
||||||
|
legal:
|
||||||
|
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms) Empty string to disable or filename to load from local file in static folder
|
||||||
|
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy) Empty string to disable or filename to load from local file in static folder
|
||||||
|
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility) Empty string to disable or filename to load from local file in static folder
|
||||||
|
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie) Empty string to disable or filename to load from local file in static folder
|
||||||
|
impressum: '' # URL to the impressum of your application (e.g. https://example.com/impressum) Empty string to disable or filename to load from local file in static folder
|
||||||
|
|
||||||
system:
|
system:
|
||||||
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
defaultLocale: en-US # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
||||||
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
|
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
|
||||||
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
|
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
|
||||||
showUpdate: true # see when a new update is available
|
showUpdate: false # see when a new update is available
|
||||||
showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
|
showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
|
||||||
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files
|
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files
|
||||||
|
tessdataDir: /usr/share/tessdata # Path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
|
||||||
|
enableAnalytics: undefined # Set to 'true' to enable analytics, set to 'false' to disable analytics, for enterprise users this is set to true
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
appName: '' # Application's visible name
|
appName: '' # Application's visible name
|
||||||
@@ -300,6 +330,11 @@ endpoints:
|
|||||||
|
|
||||||
metrics:
|
metrics:
|
||||||
enabled: true # 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable
|
enabled: true # 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable
|
||||||
|
|
||||||
|
# Automatically Generated Settings (Do Not Edit Directly)
|
||||||
|
AutomaticallyGenerated:
|
||||||
|
key: example
|
||||||
|
UUID: example
|
||||||
```
|
```
|
||||||
|
|
||||||
There is an additional config file ``/configs/custom_settings.yml`` were users familiar with java and spring application.properties can input their own settings on-top of Stirling-PDFs existing ones
|
There is an additional config file ``/configs/custom_settings.yml`` were users familiar with java and spring application.properties can input their own settings on-top of Stirling-PDFs existing ones
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "stirling.software"
|
group = "stirling.software"
|
||||||
version = "0.31.0"
|
version = "0.31.1"
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// 17 is lowest but we support and recommend 21
|
// 17 is lowest but we support and recommend 21
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
appVersion: 0.31.0
|
appVersion: 0.31.1
|
||||||
description: locally hosted web application that allows you to perform various operations
|
description: locally hosted web application that allows you to perform various operations
|
||||||
on PDF files
|
on PDF files
|
||||||
home: https://github.com/Stirling-Tools/Stirling-PDF
|
home: https://github.com/Stirling-Tools/Stirling-PDF
|
||||||
@@ -13,4 +13,4 @@ maintainers:
|
|||||||
name: stirling-pdf-chart
|
name: stirling-pdf-chart
|
||||||
sources:
|
sources:
|
||||||
- https://github.com/Stirling-Tools/Stirling-PDF
|
- https://github.com/Stirling-Tools/Stirling-PDF
|
||||||
version: 1.0.0
|
version: 1.0.1
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@@ -21,6 +22,7 @@ import java.security.cert.X509Certificate;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.pdfbox.examples.signature.CreateSignatureBase;
|
import org.apache.pdfbox.examples.signature.CreateSignatureBase;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
@@ -92,7 +94,7 @@ public class CertSignController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CreateSignature extends CreateSignatureBase {
|
class CreateSignature extends CreateSignatureBase {
|
||||||
File imageFile;
|
File logoFile;
|
||||||
|
|
||||||
public CreateSignature(KeyStore keystore, char[] pin)
|
public CreateSignature(KeyStore keystore, char[] pin)
|
||||||
throws KeyStoreException,
|
throws KeyStoreException,
|
||||||
@@ -102,11 +104,17 @@ public class CertSignController {
|
|||||||
CertificateException {
|
CertificateException {
|
||||||
super(keystore, pin);
|
super(keystore, pin);
|
||||||
ClassPathResource resource = new ClassPathResource("static/images/signature.png");
|
ClassPathResource resource = new ClassPathResource("static/images/signature.png");
|
||||||
imageFile = resource.getFile();
|
try (InputStream is = resource.getInputStream()) {
|
||||||
|
logoFile = Files.createTempFile("signature", ".png").toFile();
|
||||||
|
FileUtils.copyInputStreamToFile(is, logoFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Failed to load image signature file");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream createVisibleSignature(
|
public InputStream createVisibleSignature(
|
||||||
PDDocument srcDoc, PDSignature signature, Integer pageNumber, Boolean showImage)
|
PDDocument srcDoc, PDSignature signature, Integer pageNumber, Boolean showLogo)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// modified from org.apache.pdfbox.examples.signature.CreateVisibleSignature2
|
// modified from org.apache.pdfbox.examples.signature.CreateVisibleSignature2
|
||||||
try (PDDocument doc = new PDDocument()) {
|
try (PDDocument doc = new PDDocument()) {
|
||||||
@@ -145,7 +153,7 @@ public class CertSignController {
|
|||||||
widget.setAppearance(appearance);
|
widget.setAppearance(appearance);
|
||||||
|
|
||||||
try (PDPageContentStream cs = new PDPageContentStream(doc, appearanceStream)) {
|
try (PDPageContentStream cs = new PDPageContentStream(doc, appearanceStream)) {
|
||||||
if (showImage) {
|
if (showLogo) {
|
||||||
cs.saveGraphicsState();
|
cs.saveGraphicsState();
|
||||||
PDExtendedGraphicsState extState = new PDExtendedGraphicsState();
|
PDExtendedGraphicsState extState = new PDExtendedGraphicsState();
|
||||||
extState.setBlendMode(BlendMode.MULTIPLY);
|
extState.setBlendMode(BlendMode.MULTIPLY);
|
||||||
@@ -153,7 +161,7 @@ public class CertSignController {
|
|||||||
cs.setGraphicsStateParameters(extState);
|
cs.setGraphicsStateParameters(extState);
|
||||||
cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
|
cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
|
||||||
PDImageXObject img =
|
PDImageXObject img =
|
||||||
PDImageXObject.createFromFileByExtension(imageFile, doc);
|
PDImageXObject.createFromFileByExtension(logoFile, doc);
|
||||||
cs.drawImage(img, 100, 0);
|
cs.drawImage(img, 100, 0);
|
||||||
cs.restoreGraphicsState();
|
cs.restoreGraphicsState();
|
||||||
}
|
}
|
||||||
@@ -219,6 +227,7 @@ public class CertSignController {
|
|||||||
String location = request.getLocation();
|
String location = request.getLocation();
|
||||||
String name = request.getName();
|
String name = request.getName();
|
||||||
Integer pageNumber = request.getPageNumber() - 1;
|
Integer pageNumber = request.getPageNumber() - 1;
|
||||||
|
Boolean showLogo = request.isShowLogo();
|
||||||
|
|
||||||
if (certType == null) {
|
if (certType == null) {
|
||||||
throw new IllegalArgumentException("Cert type must be provided");
|
throw new IllegalArgumentException("Cert type must be provided");
|
||||||
@@ -258,7 +267,8 @@ public class CertSignController {
|
|||||||
pageNumber,
|
pageNumber,
|
||||||
name,
|
name,
|
||||||
location,
|
location,
|
||||||
reason);
|
reason,
|
||||||
|
showLogo);
|
||||||
return WebResponseUtils.boasToWebResponse(
|
return WebResponseUtils.boasToWebResponse(
|
||||||
baos,
|
baos,
|
||||||
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||||
@@ -274,7 +284,8 @@ public class CertSignController {
|
|||||||
Integer pageNumber,
|
Integer pageNumber,
|
||||||
String name,
|
String name,
|
||||||
String location,
|
String location,
|
||||||
String reason) {
|
String reason,
|
||||||
|
Boolean showLogo) {
|
||||||
try (PDDocument doc = pdfDocumentFactory.load(input)) {
|
try (PDDocument doc = pdfDocumentFactory.load(input)) {
|
||||||
PDSignature signature = new PDSignature();
|
PDSignature signature = new PDSignature();
|
||||||
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
|
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
|
||||||
@@ -287,7 +298,7 @@ public class CertSignController {
|
|||||||
if (showSignature) {
|
if (showSignature) {
|
||||||
SignatureOptions signatureOptions = new SignatureOptions();
|
SignatureOptions signatureOptions = new SignatureOptions();
|
||||||
signatureOptions.setVisualSignature(
|
signatureOptions.setVisualSignature(
|
||||||
instance.createVisibleSignature(doc, signature, pageNumber, true));
|
instance.createVisibleSignature(doc, signature, pageNumber, showLogo));
|
||||||
signatureOptions.setPage(pageNumber);
|
signatureOptions.setPage(pageNumber);
|
||||||
|
|
||||||
doc.addSignature(signature, instance, signatureOptions);
|
doc.addSignature(signature, instance, signatureOptions);
|
||||||
|
|||||||
@@ -50,4 +50,7 @@ public class SignPDFWithCertRequest extends PDFFile {
|
|||||||
description =
|
description =
|
||||||
"The page number where the signature should be visible. This is required if showSignature is set to true")
|
"The page number where the signature should be visible. This is required if showSignature is set to true")
|
||||||
private Integer pageNumber;
|
private Integer pageNumber;
|
||||||
|
|
||||||
|
@Schema(description = "Whether to visually show a signature logo along with the signature")
|
||||||
|
private boolean showLogo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -750,6 +750,7 @@ certSign.showSig=Show Signature
|
|||||||
certSign.reason=Reason
|
certSign.reason=Reason
|
||||||
certSign.location=Location
|
certSign.location=Location
|
||||||
certSign.name=Name
|
certSign.name=Name
|
||||||
|
certSign.showLogo=Show Logo
|
||||||
certSign.submit=Sign PDF
|
certSign.submit=Sign PDF
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -750,6 +750,7 @@ certSign.showSig=Show Signature
|
|||||||
certSign.reason=Reason
|
certSign.reason=Reason
|
||||||
certSign.location=Location
|
certSign.location=Location
|
||||||
certSign.name=Name
|
certSign.name=Name
|
||||||
|
certSign.showLogo=Show Logo
|
||||||
certSign.submit=Sign PDF
|
certSign.submit=Sign PDF
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ info=Info
|
|||||||
pro=Pro
|
pro=Pro
|
||||||
page=Pagina
|
page=Pagina
|
||||||
pages=Pagine
|
pages=Pagine
|
||||||
loading=Loading...
|
loading=Caricamento...
|
||||||
addToDoc=Add to Document
|
addToDoc=Aggiungi al documento
|
||||||
|
|
||||||
legal.privacy=Informativa sulla privacy
|
legal.privacy=Informativa sulla privacy
|
||||||
legal.terms=Termini e Condizioni
|
legal.terms=Termini e Condizioni
|
||||||
@@ -784,9 +784,9 @@ compare.highlightColor.2=Evidenzia colore 2:
|
|||||||
compare.document.1=Documento 1
|
compare.document.1=Documento 1
|
||||||
compare.document.2=Documento 2
|
compare.document.2=Documento 2
|
||||||
compare.submit=Compara
|
compare.submit=Compara
|
||||||
compare.complex.message=One or both of the provided documents are large files, accuracy of comparison may be reduced
|
compare.complex.message=Uno o entrambi i documenti forniti sono file di grandi dimensioni, l'accuratezza del confronto potrebbe risultare ridotta
|
||||||
compare.large.file.message=One or Both of the provided documents are too large to process
|
compare.large.file.message=Uno o entrambi i documenti forniti sono troppo grandi per essere elaborati
|
||||||
compare.no.text.message=One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison.
|
compare.no.text.message=Uno o entrambi i PDF selezionati non hanno contenuto di testo. Si prega di scegliere PDF con testo per il confronto.
|
||||||
|
|
||||||
#BookToPDF
|
#BookToPDF
|
||||||
BookToPDF.title=Libri e fumetti in PDF
|
BookToPDF.title=Libri e fumetti in PDF
|
||||||
@@ -809,11 +809,11 @@ sign.draw=Disegna Firma
|
|||||||
sign.text=Testo
|
sign.text=Testo
|
||||||
sign.clear=Cancella
|
sign.clear=Cancella
|
||||||
sign.add=Aggiungi
|
sign.add=Aggiungi
|
||||||
sign.saved=Saved Signatures
|
sign.saved=Firme salvate
|
||||||
sign.save=Save Signature
|
sign.save=Firma salvata
|
||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Firme personali
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Firme condivise
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=Nessuna firma salvata trovata
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
|
|||||||
@@ -333,6 +333,9 @@ span.icon-text::after {
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
z-index: 1;
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.go-pro-badge {
|
.go-pro-badge {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
<span class="tool-header-text" th:text="#{compress.header}"></span>
|
<span class="tool-header-text" th:text="#{compress.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="#" th:action="@{'/api/v1/misc/compress-pdf'}" method="post" enctype="multipart/form-data">
|
<form action="#" th:action="@{'/api/v1/misc/compress-pdf'}" method="post" enctype="multipart/form-data">
|
||||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
|
|
||||||
<div
|
<div
|
||||||
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}">
|
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -71,7 +71,11 @@
|
|||||||
<label for="name" th:text="#{certSign.name}"></label> <input type="text" class="form-control" id="name" name="name">
|
<label for="name" th:text="#{certSign.name}"></label> <input type="text" class="form-control" id="name" name="name">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="pageNumber" th:text="#{pageNum}"></label> <input type="number" class="form-control" id="pageNumber" name="pageNumber" min="1">
|
<label for="pageNumber" th:text="#{pageNum}"></label> <input type="number" class="form-control" id="pageNumber" name="pageNumber" min="1" value="1">
|
||||||
|
</div>
|
||||||
|
<div class="form-check mb-3">
|
||||||
|
<input type="checkbox" id="showLogo" name="showLogo" checked />
|
||||||
|
<label th:text="#{certSign.showLogo}" for="showLogo"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3 text-left">
|
<div class="mb-3 text-left">
|
||||||
|
|||||||
Reference in New Issue
Block a user