mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-11-01 01:21:18 +01:00 
			
		
		
		
	# Description of Changes Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] 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) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. Co-authored-by: a <a>
This commit is contained in:
		
							parent
							
								
									9cc4f14465
								
							
						
					
					
						commit
						28a259ec95
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -13,6 +13,7 @@ local.properties
 | 
			
		||||
.recommenders
 | 
			
		||||
.classpath
 | 
			
		||||
.project
 | 
			
		||||
*.local.json
 | 
			
		||||
version.properties
 | 
			
		||||
 | 
			
		||||
#### Stirling-PDF Files ###
 | 
			
		||||
 | 
			
		||||
@ -91,6 +91,59 @@ public class GetInfoOnPDF {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates structured summary data about the PDF highlighting its unique characteristics such
 | 
			
		||||
     * as encryption status, permission restrictions, and standards compliance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param document The PDF document to analyze
 | 
			
		||||
     * @return An ObjectNode containing structured summary data
 | 
			
		||||
     */
 | 
			
		||||
    private ObjectNode generatePDFSummaryData(PDDocument document) {
 | 
			
		||||
        ObjectNode summaryData = objectMapper.createObjectNode();
 | 
			
		||||
 | 
			
		||||
        // Check if encrypted
 | 
			
		||||
        if (document.isEncrypted()) {
 | 
			
		||||
            summaryData.put("encrypted", true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check permissions
 | 
			
		||||
        AccessPermission ap = document.getCurrentAccessPermission();
 | 
			
		||||
        ArrayNode restrictedPermissions = objectMapper.createArrayNode();
 | 
			
		||||
 | 
			
		||||
        if (!ap.canAssembleDocument()) restrictedPermissions.add("document assembly");
 | 
			
		||||
        if (!ap.canExtractContent()) restrictedPermissions.add("content extraction");
 | 
			
		||||
        if (!ap.canExtractForAccessibility()) restrictedPermissions.add("accessibility extraction");
 | 
			
		||||
        if (!ap.canFillInForm()) restrictedPermissions.add("form filling");
 | 
			
		||||
        if (!ap.canModify()) restrictedPermissions.add("modification");
 | 
			
		||||
        if (!ap.canModifyAnnotations()) restrictedPermissions.add("annotation modification");
 | 
			
		||||
        if (!ap.canPrint()) restrictedPermissions.add("printing");
 | 
			
		||||
 | 
			
		||||
        if (restrictedPermissions.size() > 0) {
 | 
			
		||||
            summaryData.set("restrictedPermissions", restrictedPermissions);
 | 
			
		||||
            summaryData.put("restrictedPermissionsCount", restrictedPermissions.size());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check standard compliance
 | 
			
		||||
        if (checkForStandard(document, "PDF/A")) {
 | 
			
		||||
            summaryData.put("standardCompliance", "PDF/A");
 | 
			
		||||
            summaryData.put("standardPurpose", "long-term archiving");
 | 
			
		||||
        } else if (checkForStandard(document, "PDF/X")) {
 | 
			
		||||
            summaryData.put("standardCompliance", "PDF/X");
 | 
			
		||||
            summaryData.put("standardPurpose", "graphic exchange");
 | 
			
		||||
        } else if (checkForStandard(document, "PDF/UA")) {
 | 
			
		||||
            summaryData.put("standardCompliance", "PDF/UA");
 | 
			
		||||
            summaryData.put("standardPurpose", "universal accessibility");
 | 
			
		||||
        } else if (checkForStandard(document, "PDF/E")) {
 | 
			
		||||
            summaryData.put("standardCompliance", "PDF/E");
 | 
			
		||||
            summaryData.put("standardPurpose", "engineering workflows");
 | 
			
		||||
        } else if (checkForStandard(document, "PDF/VT")) {
 | 
			
		||||
            summaryData.put("standardCompliance", "PDF/VT");
 | 
			
		||||
            summaryData.put("standardPurpose", "variable and transactional printing");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return summaryData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean checkForStandard(PDDocument document, String standardKeyword) {
 | 
			
		||||
        // Check XMP Metadata
 | 
			
		||||
        try {
 | 
			
		||||
@ -191,6 +244,12 @@ public class GetInfoOnPDF {
 | 
			
		||||
            }
 | 
			
		||||
            jsonOutput.set("FormFields", formFieldsNode);
 | 
			
		||||
 | 
			
		||||
            // Generate structured summary data about PDF characteristics
 | 
			
		||||
            ObjectNode summaryData = generatePDFSummaryData(pdfBoxDoc);
 | 
			
		||||
            if (summaryData != null && summaryData.size() > 0) {
 | 
			
		||||
                jsonOutput.set("SummaryData", summaryData);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // embeed files TODO size
 | 
			
		||||
            if (catalog.getNames() != null) {
 | 
			
		||||
                PDEmbeddedFilesNameTreeNode efTree = catalog.getNames().getEmbeddedFiles();
 | 
			
		||||
 | 
			
		||||
@ -807,6 +807,28 @@ getPdfInfo.title=Get Info on PDF
 | 
			
		||||
getPdfInfo.header=Get Info on PDF
 | 
			
		||||
getPdfInfo.submit=Get Info
 | 
			
		||||
getPdfInfo.downloadJson=Download JSON
 | 
			
		||||
getPdfInfo.summary=PDF Summary
 | 
			
		||||
getPdfInfo.summary.encrypted=This PDF is encrypted so may face issues with some applications
 | 
			
		||||
getPdfInfo.summary.permissions=This PDF has {0} restricted permissions which may limit what you can do with it
 | 
			
		||||
getPdfInfo.summary.compliance=This PDF complies with the {0} standard
 | 
			
		||||
getPdfInfo.summary.basicInfo=Basic Information
 | 
			
		||||
getPdfInfo.summary.docInfo=Document Information
 | 
			
		||||
getPdfInfo.summary.encrypted.alert=Encrypted PDF - This document is password protected
 | 
			
		||||
getPdfInfo.summary.not.encrypted.alert=Unencrypted PDF - No password protection
 | 
			
		||||
getPdfInfo.summary.permissions.alert=Restricted Permissions - {0} actions are not allowed
 | 
			
		||||
getPdfInfo.summary.all.permissions.alert=All Permissions Allowed
 | 
			
		||||
getPdfInfo.summary.compliance.alert={0} Compliant
 | 
			
		||||
getPdfInfo.summary.no.compliance.alert=No Compliance Standards
 | 
			
		||||
getPdfInfo.summary.security.section=Security Status
 | 
			
		||||
getPdfInfo.section.BasicInfo=Basic Information about the PDF document including file size, page count, and language
 | 
			
		||||
getPdfInfo.section.Metadata=Document metadata including title, author, creation date and other document properties
 | 
			
		||||
getPdfInfo.section.DocumentInfo=Technical details about the PDF document structure and version
 | 
			
		||||
getPdfInfo.section.Compliancy=PDF standards compliance information (PDF/A, PDF/X, etc.)
 | 
			
		||||
getPdfInfo.section.Encryption=Security and encryption details of the document
 | 
			
		||||
getPdfInfo.section.Permissions=Document permission settings that control what actions can be performed
 | 
			
		||||
getPdfInfo.section.Other=Additional document components like bookmarks, layers, and embedded files
 | 
			
		||||
getPdfInfo.section.FormFields=Interactive form fields present in the document
 | 
			
		||||
getPdfInfo.section.PerPageInfo=Detailed information about each page in the document
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#markdown-to-pdf
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@
 | 
			
		||||
        <br><br>
 | 
			
		||||
        <div class="container">
 | 
			
		||||
          <div class="row justify-content-center">
 | 
			
		||||
            <div class="col-md-6 bg-card">
 | 
			
		||||
            <div class="col-md-7 bg-card">
 | 
			
		||||
              <div class="tool-header">
 | 
			
		||||
                <span class="material-symbols-rounded tool-header-icon other">info</span>
 | 
			
		||||
                <span class="tool-header-text" th:text="#{getPdfInfo.header}"></span>
 | 
			
		||||
@ -22,6 +22,82 @@
 | 
			
		||||
                <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{getPdfInfo.submit}"></button>
 | 
			
		||||
              </form>
 | 
			
		||||
              <div class="container mt-0">
 | 
			
		||||
                <!-- PDF Summary section -->
 | 
			
		||||
                <div id="pdf-summary" class="card mt-3 mb-3" style="display: none;">
 | 
			
		||||
                  <div class="card-header">
 | 
			
		||||
                    <h5 class="mb-0" id="summary-heading">PDF Summary</h5>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="card-body">
 | 
			
		||||
                    <!-- Quick overview of key details -->
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                      <div class="col-md-6">
 | 
			
		||||
                        <h6 id="summary-basic-info-heading">Basic Information</h6>
 | 
			
		||||
                        <ul class="list-unstyled">
 | 
			
		||||
                          <li><strong>Pages:</strong> <span id="summary-pages">-</span></li>
 | 
			
		||||
                          <li><strong>File Size:</strong> <span id="summary-size">-</span></li>
 | 
			
		||||
                          <li><strong>PDF Version:</strong> <span id="summary-version">-</span></li>
 | 
			
		||||
                          <li><strong>Language:</strong> <span id="summary-language">-</span></li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="col-md-6">
 | 
			
		||||
                        <h6 id="summary-doc-info-heading">Document Information</h6>
 | 
			
		||||
                        <ul class="list-unstyled">
 | 
			
		||||
                          <li><strong>Title:</strong> <span id="summary-title">-</span></li>
 | 
			
		||||
                          <li><strong>Author:</strong> <span id="summary-author">-</span></li>
 | 
			
		||||
                          <li><strong>Created:</strong> <span id="summary-created">-</span></li>
 | 
			
		||||
                          <li><strong>Modified:</strong> <span id="summary-modified">-</span></li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    
 | 
			
		||||
                    <!-- Security section -->
 | 
			
		||||
                    <div class="mt-4 mb-3">
 | 
			
		||||
                      <h6 id="summary-security-heading">Security Status</h6>
 | 
			
		||||
                      <div class="row">
 | 
			
		||||
                        <div class="col-md-4">
 | 
			
		||||
                          <div id="encryption-status" class="card mb-2 h-100">
 | 
			
		||||
                            <div class="card-body p-2 d-flex align-items-center">
 | 
			
		||||
                              <span id="encryption-icon" class="me-2"><i class="bi bi-lock"></i></span>
 | 
			
		||||
                              <span id="encryption-text" class="small">Encryption: Unknown</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-md-4">
 | 
			
		||||
                          <div id="permissions-status" class="card mb-2 h-100">
 | 
			
		||||
                            <div class="card-body p-2 d-flex align-items-center">
 | 
			
		||||
                              <span id="permissions-icon" class="me-2"><i class="bi bi-shield"></i></span>
 | 
			
		||||
                              <span id="permissions-text" class="small">Permissions: Unknown</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-md-4">
 | 
			
		||||
                          <div id="compliance-status" class="card mb-2 h-100">
 | 
			
		||||
                            <div class="card-body p-2 d-flex align-items-center">
 | 
			
		||||
                              <span id="compliance-icon" class="me-2"><i class="bi bi-check-circle"></i></span>
 | 
			
		||||
                              <span id="compliance-text" class="small">Compliance: Unknown</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    
 | 
			
		||||
                    <!-- Detailed alerts -->
 | 
			
		||||
                    <div id="summary-alerts" class="mt-3">
 | 
			
		||||
                      <!-- Will be populated with detailed alerts for encryption, permissions, etc. -->
 | 
			
		||||
                    </div>
 | 
			
		||||
                    
 | 
			
		||||
                    <!-- Descriptive note about PDF characteristics -->
 | 
			
		||||
                    <div class="card mt-3">
 | 
			
		||||
                      <div class="card-header">
 | 
			
		||||
                        <h6 class="mb-0">PDF Overview</h6>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="card-body">
 | 
			
		||||
                        <p id="summary-text" class="mb-0"></p>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                
 | 
			
		||||
                <!-- Iterate over each main section in the JSON -->
 | 
			
		||||
                <div id="json-content">
 | 
			
		||||
                  <!-- JavaScript will populate this section -->
 | 
			
		||||
@ -31,21 +107,379 @@
 | 
			
		||||
                <a href="#" id="downloadJson" class="btn btn-primary mt-3" style="display: none;" th:text="#{getPdfInfo.downloadJson}">Download JSON</a>
 | 
			
		||||
              </div>
 | 
			
		||||
              <script th:src="@{'/js/fetch-utils.js'}"></script>
 | 
			
		||||
              <script>
 | 
			
		||||
              <script th:inline="javascript">
 | 
			
		||||
                // Pre-load message translations
 | 
			
		||||
                const getPdfInfoSummary = /*[[#{getPdfInfo.summary}]]*/ "PDF Summary";
 | 
			
		||||
                const getPdfInfoSummaryEncrypted = /*[[#{getPdfInfo.summary.encrypted}]]*/ "This PDF is encrypted so may face issues with some applications";
 | 
			
		||||
                const getPdfInfoSummaryPermissions = /*[[#{getPdfInfo.summary.permissions}]]*/ "This PDF has {0} restricted permissions which may limit what you can do with it";
 | 
			
		||||
                const getPdfInfoSummaryCompliance = /*[[#{getPdfInfo.summary.compliance}]]*/ "This PDF complies with the {0} standard, meaning it is suitable for {1}";
 | 
			
		||||
                const getPdfInfoSummaryBasicInfo = /*[[#{getPdfInfo.summary.basicInfo}]]*/ "Basic Information";
 | 
			
		||||
                const getPdfInfoSummaryDocInfo = /*[[#{getPdfInfo.summary.docInfo}]]*/ "Document Information";
 | 
			
		||||
                const getPdfInfoSummarySecuritySection = /*[[#{getPdfInfo.summary.security.section}]]*/ "Security Status";
 | 
			
		||||
                const getPdfInfoSummaryEncryptedAlert = /*[[#{getPdfInfo.summary.encrypted.alert}]]*/ "Encrypted PDF - This document is password protected";
 | 
			
		||||
                const getPdfInfoSummaryNotEncryptedAlert = /*[[#{getPdfInfo.summary.not.encrypted.alert}]]*/ "Unencrypted PDF - No password protection";
 | 
			
		||||
                const getPdfInfoSummaryPermissionsAlert = /*[[#{getPdfInfo.summary.permissions.alert}]]*/ "Restricted Permissions - {0} actions are not allowed";
 | 
			
		||||
                const getPdfInfoSummaryAllPermissionsAlert = /*[[#{getPdfInfo.summary.all.permissions.alert}]]*/ "All Permissions Allowed";
 | 
			
		||||
                const getPdfInfoSummaryComplianceAlert = /*[[#{getPdfInfo.summary.compliance.alert}]]*/ "{0} Compliant";
 | 
			
		||||
                const getPdfInfoSummaryNoComplianceAlert = /*[[#{getPdfInfo.summary.no.compliance.alert}]]*/ "No Compliance Standards";
 | 
			
		||||
                
 | 
			
		||||
                // Update the summary headings
 | 
			
		||||
                document.addEventListener('DOMContentLoaded', function() {
 | 
			
		||||
                  document.getElementById('summary-heading').textContent = getPdfInfoSummary;
 | 
			
		||||
                  document.getElementById('summary-basic-info-heading').textContent = getPdfInfoSummaryBasicInfo;
 | 
			
		||||
                  document.getElementById('summary-doc-info-heading').textContent = getPdfInfoSummaryDocInfo;
 | 
			
		||||
                  document.getElementById('summary-security-heading').textContent = getPdfInfoSummarySecuritySection;
 | 
			
		||||
                });
 | 
			
		||||
                
 | 
			
		||||
                // Pre-load section descriptions
 | 
			
		||||
                const getPdfInfoSectionBasicInfo = /*[[#{getPdfInfo.section.BasicInfo}]]*/ "Basic Information about the PDF document including file size, page count, and language";
 | 
			
		||||
                const getPdfInfoSectionMetadata = /*[[#{getPdfInfo.section.Metadata}]]*/ "Document metadata including title, author, creation date and other document properties";
 | 
			
		||||
                const getPdfInfoSectionDocumentInfo = /*[[#{getPdfInfo.section.DocumentInfo}]]*/ "Technical details about the PDF document structure and version";
 | 
			
		||||
                const getPdfInfoSectionCompliancy = /*[[#{getPdfInfo.section.Compliancy}]]*/ "PDF standards compliance information (PDF/A, PDF/X, etc.)";
 | 
			
		||||
                const getPdfInfoSectionEncryption = /*[[#{getPdfInfo.section.Encryption}]]*/ "Security and encryption details of the document";
 | 
			
		||||
                const getPdfInfoSectionPermissions = /*[[#{getPdfInfo.section.Permissions}]]*/ "Document permission settings that control what actions can be performed";
 | 
			
		||||
                const getPdfInfoSectionOther = /*[[#{getPdfInfo.section.Other}]]*/ "Additional document components like bookmarks, layers, and embedded files";
 | 
			
		||||
                const getPdfInfoSectionFormFields = /*[[#{getPdfInfo.section.FormFields}]]*/ "Interactive form fields present in the document";
 | 
			
		||||
                const getPdfInfoSectionPerPageInfo = /*[[#{getPdfInfo.section.PerPageInfo}]]*/ "Detailed information about each page in the document";
 | 
			
		||||
 | 
			
		||||
                document.getElementById("pdfInfoForm").addEventListener("submit", function(event) {
 | 
			
		||||
                  event.preventDefault();
 | 
			
		||||
                  
 | 
			
		||||
                  // Clear previous results when submitting a new form
 | 
			
		||||
                  document.getElementById('json-content').innerHTML = '';
 | 
			
		||||
                  document.getElementById('pdf-summary').style.display = 'none';
 | 
			
		||||
                  document.getElementById('downloadJson').style.display = 'none';
 | 
			
		||||
 | 
			
		||||
                  const formData = new FormData(event.target);
 | 
			
		||||
 | 
			
		||||
                  fetchWithCsrf('api/v1/security/get-info-on-pdf', {
 | 
			
		||||
                    method: 'POST',
 | 
			
		||||
                    body: formData
 | 
			
		||||
                  }).then(response => response.json()).then(data => {
 | 
			
		||||
                    // Populate and display the enhanced PDF summary
 | 
			
		||||
                    populateSummarySection(data);
 | 
			
		||||
                    
 | 
			
		||||
                    displayJsonData(data);
 | 
			
		||||
                    setDownloadLink(data);
 | 
			
		||||
                    document.getElementById("downloadJson").style.display = "block";
 | 
			
		||||
                  }).catch(error => console.error('Error:', error));
 | 
			
		||||
                  
 | 
			
		||||
                // Function to reset all summary elements to default state
 | 
			
		||||
                function resetSummaryElements() {
 | 
			
		||||
                  // Reset basic information fields
 | 
			
		||||
                  document.getElementById('summary-pages').textContent = '-';
 | 
			
		||||
                  document.getElementById('summary-size').textContent = '-';
 | 
			
		||||
                  document.getElementById('summary-version').textContent = '-';
 | 
			
		||||
                  document.getElementById('summary-language').textContent = '-';
 | 
			
		||||
                  
 | 
			
		||||
                  // Reset document information fields
 | 
			
		||||
                  document.getElementById('summary-title').textContent = '-';
 | 
			
		||||
                  document.getElementById('summary-author').textContent = '-';
 | 
			
		||||
                  document.getElementById('summary-created').textContent = '-';
 | 
			
		||||
                  document.getElementById('summary-modified').textContent = '-';
 | 
			
		||||
                  
 | 
			
		||||
                  // Reset security status cards
 | 
			
		||||
                  const cards = ['encryption-status', 'permissions-status', 'compliance-status'];
 | 
			
		||||
                  cards.forEach(id => {
 | 
			
		||||
                    const card = document.getElementById(id);
 | 
			
		||||
                    // Remove all classes except the base ones
 | 
			
		||||
                    card.className = 'card mb-2 h-100';
 | 
			
		||||
                  });
 | 
			
		||||
                  
 | 
			
		||||
                  // Reset status text and icons
 | 
			
		||||
                  document.getElementById('encryption-icon').innerHTML = '<i class="bi bi-lock"></i>';
 | 
			
		||||
                  document.getElementById('encryption-text').textContent = 'Encryption: Unknown';
 | 
			
		||||
                  
 | 
			
		||||
                  document.getElementById('permissions-icon').innerHTML = '<i class="bi bi-shield"></i>';
 | 
			
		||||
                  document.getElementById('permissions-text').textContent = 'Permissions: Unknown';
 | 
			
		||||
                  
 | 
			
		||||
                  document.getElementById('compliance-icon').innerHTML = '<i class="bi bi-check-circle"></i>';
 | 
			
		||||
                  document.getElementById('compliance-text').textContent = 'Compliance: Unknown';
 | 
			
		||||
                  
 | 
			
		||||
                  // Clear alerts container
 | 
			
		||||
                  document.getElementById('summary-alerts').innerHTML = '';
 | 
			
		||||
                  
 | 
			
		||||
                  // Reset summary text
 | 
			
		||||
                  document.getElementById('summary-text').innerHTML = '';
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                // Function to populate the enhanced summary section
 | 
			
		||||
                function populateSummarySection(data) {
 | 
			
		||||
                  // Reset all elements first
 | 
			
		||||
                  resetSummaryElements();
 | 
			
		||||
                  
 | 
			
		||||
                  // Get basic information
 | 
			
		||||
                  if (data.BasicInfo) {
 | 
			
		||||
                    document.getElementById('summary-pages').textContent = data.BasicInfo["Number of pages"] || "-";
 | 
			
		||||
                    
 | 
			
		||||
                    // Format file size nicely
 | 
			
		||||
                    let fileSize = data.BasicInfo["FileSizeInBytes"];
 | 
			
		||||
                    if (fileSize) {
 | 
			
		||||
                      const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
 | 
			
		||||
                      const i = Math.floor(Math.log(fileSize) / Math.log(1024));
 | 
			
		||||
                      fileSize = (fileSize / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
 | 
			
		||||
                      document.getElementById('summary-size').textContent = fileSize;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    document.getElementById('summary-language').textContent = data.BasicInfo["Language"] || "-";
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Get document information
 | 
			
		||||
                  if (data.DocumentInfo) {
 | 
			
		||||
                    document.getElementById('summary-version').textContent = data.DocumentInfo["PDF version"] || "-";
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Get metadata
 | 
			
		||||
                  if (data.Metadata) {
 | 
			
		||||
                    document.getElementById('summary-title').textContent = data.Metadata["Title"] || "-";
 | 
			
		||||
                    document.getElementById('summary-author').textContent = data.Metadata["Author"] || "-";
 | 
			
		||||
                    document.getElementById('summary-created').textContent = data.Metadata["CreationDate"] || "-";
 | 
			
		||||
                    document.getElementById('summary-modified').textContent = data.Metadata["ModificationDate"] || "-";
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Update security status cards
 | 
			
		||||
                  
 | 
			
		||||
                  // Encryption status
 | 
			
		||||
                  const encryptionStatusCard = document.getElementById('encryption-status');
 | 
			
		||||
                  const encryptionIcon = document.getElementById('encryption-icon');
 | 
			
		||||
                  const encryptionText = document.getElementById('encryption-text');
 | 
			
		||||
                  
 | 
			
		||||
                  if (data.Encryption && data.Encryption.IsEncrypted) {
 | 
			
		||||
                    encryptionIcon.innerHTML = '<i class="bi bi-lock-fill"></i>';
 | 
			
		||||
                    encryptionText.textContent = getPdfInfoSummaryEncryptedAlert;
 | 
			
		||||
                  } else {
 | 
			
		||||
                    encryptionIcon.innerHTML = '<i class="bi bi-unlock-fill"></i>';
 | 
			
		||||
                    encryptionText.textContent = getPdfInfoSummaryNotEncryptedAlert;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Permissions status
 | 
			
		||||
                  const permissionsStatusCard = document.getElementById('permissions-status');
 | 
			
		||||
                  const permissionsIcon = document.getElementById('permissions-icon');
 | 
			
		||||
                  const permissionsText = document.getElementById('permissions-text');
 | 
			
		||||
                  
 | 
			
		||||
                  let restrictedPermissions = [];
 | 
			
		||||
                  if (data.Permissions) {
 | 
			
		||||
                    for (const [permission, state] of Object.entries(data.Permissions)) {
 | 
			
		||||
                      if (state === "Not Allowed") {
 | 
			
		||||
                        restrictedPermissions.push(permission);
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  if (restrictedPermissions.length > 0) {
 | 
			
		||||
                    permissionsIcon.innerHTML = '<i class="bi bi-shield-lock-fill"></i>';
 | 
			
		||||
                    const formattedAlert = getPdfInfoSummaryPermissionsAlert.replace('{0}', restrictedPermissions.length);
 | 
			
		||||
                    permissionsText.textContent = formattedAlert;
 | 
			
		||||
                  } else {
 | 
			
		||||
                    permissionsIcon.innerHTML = '<i class="bi bi-shield-check"></i>';
 | 
			
		||||
                    permissionsText.textContent = getPdfInfoSummaryAllPermissionsAlert;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Compliance status
 | 
			
		||||
                  const complianceStatusCard = document.getElementById('compliance-status');
 | 
			
		||||
                  const complianceIcon = document.getElementById('compliance-icon');
 | 
			
		||||
                  const complianceText = document.getElementById('compliance-text');
 | 
			
		||||
                  
 | 
			
		||||
                  let hasCompliance = false;
 | 
			
		||||
                  let compliantStandards = [];
 | 
			
		||||
                  
 | 
			
		||||
                  if (data.Compliancy) {
 | 
			
		||||
                    for (const [standard, compliant] of Object.entries(data.Compliancy)) {
 | 
			
		||||
                      if (compliant === true) {
 | 
			
		||||
                        hasCompliance = true;
 | 
			
		||||
                        const standardName = standard.replace("Is", "").replace("Compliant", "");
 | 
			
		||||
                        compliantStandards.push(standardName);
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  if (hasCompliance) {
 | 
			
		||||
                    complianceIcon.innerHTML = '<i class="bi bi-check-circle-fill"></i>';
 | 
			
		||||
                    const formattedAlert = getPdfInfoSummaryComplianceAlert.replace('{0}', compliantStandards.join(', '));
 | 
			
		||||
                    complianceText.textContent = formattedAlert;
 | 
			
		||||
                  } else {
 | 
			
		||||
                    complianceIcon.innerHTML = '<i class="bi bi-dash-circle"></i>';
 | 
			
		||||
                    complianceText.textContent = getPdfInfoSummaryNoComplianceAlert;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Create detailed characteristic alerts
 | 
			
		||||
                  const alertsContainer = document.getElementById('summary-alerts');
 | 
			
		||||
                  
 | 
			
		||||
                  // Clear previous alerts
 | 
			
		||||
                  alertsContainer.innerHTML = '';
 | 
			
		||||
                  
 | 
			
		||||
                  // Create a single comprehensive security details section
 | 
			
		||||
                  let hasSummaryInfo = false;
 | 
			
		||||
                  
 | 
			
		||||
                  // Create a consolidated security details card if there are security details worth highlighting
 | 
			
		||||
                  if ((data.Encryption && data.Encryption.IsEncrypted) || 
 | 
			
		||||
                      restrictedPermissions.length > 0 || 
 | 
			
		||||
                      hasCompliance) {
 | 
			
		||||
                    
 | 
			
		||||
                    const securityDetailsCard = document.createElement('div');
 | 
			
		||||
                    securityDetailsCard.className = 'card mt-3 mb-3';
 | 
			
		||||
                    
 | 
			
		||||
                    const cardHeader = document.createElement('div');
 | 
			
		||||
                    cardHeader.className = 'card-header';
 | 
			
		||||
                    cardHeader.innerHTML = '<h6 class="mb-0">Detailed Security Information</h6>';
 | 
			
		||||
                    securityDetailsCard.appendChild(cardHeader);
 | 
			
		||||
                    
 | 
			
		||||
                    const cardBody = document.createElement('div');
 | 
			
		||||
                    cardBody.className = 'card-body';
 | 
			
		||||
                    
 | 
			
		||||
                    // Add detailed encryption info
 | 
			
		||||
                    if (data.Encryption && data.Encryption.IsEncrypted) {
 | 
			
		||||
                      const encryptionDiv = document.createElement('div');
 | 
			
		||||
                      encryptionDiv.className = 'mb-3';
 | 
			
		||||
                      encryptionDiv.innerHTML = '<h6>Encryption Details:</h6>';
 | 
			
		||||
                      
 | 
			
		||||
                      const encryptionList = document.createElement('ul');
 | 
			
		||||
                      encryptionList.className = 'list-unstyled';
 | 
			
		||||
                      
 | 
			
		||||
                      if (data.Encryption.EncryptionAlgorithm) {
 | 
			
		||||
                        encryptionList.innerHTML += `<li><strong>Algorithm:</strong> ${data.Encryption.EncryptionAlgorithm}</li>`;
 | 
			
		||||
                      }
 | 
			
		||||
                      if (data.Encryption.KeyLength) {
 | 
			
		||||
                        encryptionList.innerHTML += `<li><strong>Key Length:</strong> ${data.Encryption.KeyLength} bits</li>`;
 | 
			
		||||
                      }
 | 
			
		||||
                      
 | 
			
		||||
                      encryptionDiv.appendChild(encryptionList);
 | 
			
		||||
                      cardBody.appendChild(encryptionDiv);
 | 
			
		||||
                      hasSummaryInfo = true;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    // Add detailed permissions info
 | 
			
		||||
                    if (restrictedPermissions.length > 0) {
 | 
			
		||||
                      const permissionsDiv = document.createElement('div');
 | 
			
		||||
                      permissionsDiv.className = 'mb-3';
 | 
			
		||||
                      permissionsDiv.innerHTML = '<h6>Restricted Permissions:</h6>';
 | 
			
		||||
                      
 | 
			
		||||
                      const permissionsList = document.createElement('ul');
 | 
			
		||||
                      restrictedPermissions.forEach(perm => {
 | 
			
		||||
                        permissionsList.innerHTML += `<li>${perm}</li>`;
 | 
			
		||||
                      });
 | 
			
		||||
                      
 | 
			
		||||
                      permissionsDiv.appendChild(permissionsList);
 | 
			
		||||
                      cardBody.appendChild(permissionsDiv);
 | 
			
		||||
                      hasSummaryInfo = true;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    // Add detailed compliance info
 | 
			
		||||
                    if (hasCompliance) {
 | 
			
		||||
                      const complianceDiv = document.createElement('div');
 | 
			
		||||
                      complianceDiv.className = 'mb-3';
 | 
			
		||||
                      complianceDiv.innerHTML = '<h6>Standards Compliance:</h6>';
 | 
			
		||||
                      
 | 
			
		||||
                      const complianceList = document.createElement('ul');
 | 
			
		||||
                      complianceList.className = 'list-unstyled';
 | 
			
		||||
                      
 | 
			
		||||
                      compliantStandards.forEach(standard => {
 | 
			
		||||
                        let standardDescription = '';
 | 
			
		||||
                        
 | 
			
		||||
                        // Add brief descriptions for standards
 | 
			
		||||
                        if (standard === "PDF/A") {
 | 
			
		||||
                          standardDescription = 'ISO standard for long-term document archiving';
 | 
			
		||||
                        } else if (standard === "PDF/X") {
 | 
			
		||||
                          standardDescription = 'ISO standard for printing and graphic arts exchange';
 | 
			
		||||
                        } else if (standard === "PDF/UA") {
 | 
			
		||||
                          standardDescription = 'ISO standard for universal accessibility';
 | 
			
		||||
                        } else if (standard === "PDF/E") {
 | 
			
		||||
                          standardDescription = 'ISO standard for engineering documents';
 | 
			
		||||
                        } else if (standard === "PDF/VT") {
 | 
			
		||||
                          standardDescription = 'ISO standard for variable and transactional printing';
 | 
			
		||||
                        }
 | 
			
		||||
                        
 | 
			
		||||
                        complianceList.innerHTML += `<li><strong>${standard}:</strong> ${standardDescription}</li>`;
 | 
			
		||||
                      });
 | 
			
		||||
                      
 | 
			
		||||
                      complianceDiv.appendChild(complianceList);
 | 
			
		||||
                      cardBody.appendChild(complianceDiv);
 | 
			
		||||
                      hasSummaryInfo = true;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    securityDetailsCard.appendChild(cardBody);
 | 
			
		||||
                    
 | 
			
		||||
                    if (hasSummaryInfo) {
 | 
			
		||||
                      alertsContainer.appendChild(securityDetailsCard);
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Generate a general document summary
 | 
			
		||||
                  const summaryTextElement = document.getElementById('summary-text');
 | 
			
		||||
                  
 | 
			
		||||
                  // Create a general summary for the document
 | 
			
		||||
                  let generalSummary = `This is a ${data.BasicInfo["Number of pages"] || "multi"}-page PDF`;
 | 
			
		||||
                  
 | 
			
		||||
                  if (data.Metadata && data.Metadata["Title"]) {
 | 
			
		||||
                    generalSummary += ` titled "${data.Metadata["Title"]}"`;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  if (data.Metadata && data.Metadata["Author"]) {
 | 
			
		||||
                    generalSummary += ` created by ${data.Metadata["Author"]}`;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  if (data.DocumentInfo && data.DocumentInfo["PDF version"]) {
 | 
			
		||||
                    generalSummary += ` (PDF version ${data.DocumentInfo["PDF version"]})`;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Add security information to the general summary if relevant
 | 
			
		||||
                  if (data.Encryption && data.Encryption.IsEncrypted) {
 | 
			
		||||
                    generalSummary += '. The document is password protected';
 | 
			
		||||
                    
 | 
			
		||||
                    if (data.Encryption.EncryptionAlgorithm) {
 | 
			
		||||
                      generalSummary += ` using ${data.Encryption.EncryptionAlgorithm}`;
 | 
			
		||||
                      
 | 
			
		||||
                      if (data.Encryption.KeyLength) {
 | 
			
		||||
                        generalSummary += ` (${data.Encryption.KeyLength} bit)`;
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  if (restrictedPermissions.length > 0) {
 | 
			
		||||
                    generalSummary += `. It has ${restrictedPermissions.length} restricted permissions`;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Add compliance standards if available
 | 
			
		||||
                  if (hasCompliance && compliantStandards.length > 0) {
 | 
			
		||||
                    generalSummary += `. This document complies with the ${compliantStandards.join(', ')} PDF standard${compliantStandards.length > 1 ? 's' : ''}`;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  generalSummary += '.';
 | 
			
		||||
                  
 | 
			
		||||
                  // Remove SummaryData from JSON to avoid duplication
 | 
			
		||||
                  if (data.SummaryData) {
 | 
			
		||||
                    delete data.SummaryData;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  summaryTextElement.innerHTML = generalSummary;
 | 
			
		||||
                  
 | 
			
		||||
                  // Display the summary section
 | 
			
		||||
                  document.getElementById('pdf-summary').style.display = 'block';
 | 
			
		||||
                }
 | 
			
		||||
                  
 | 
			
		||||
                function generateSummaryFromData(summaryData) {
 | 
			
		||||
                  let summary = [];
 | 
			
		||||
                  
 | 
			
		||||
                  // Handle encryption information
 | 
			
		||||
                  if (summaryData.encrypted) {
 | 
			
		||||
                    summary.push(getPdfInfoSummaryEncrypted);
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Handle permissions information
 | 
			
		||||
                  if (summaryData.restrictedPermissions && summaryData.restrictedPermissions.length > 0) {
 | 
			
		||||
                    const formattedPermissionsText = getPdfInfoSummaryPermissions.replace('{0}', summaryData.restrictedPermissionsCount);
 | 
			
		||||
                    summary.push(formattedPermissionsText);
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Handle standard compliance information
 | 
			
		||||
                  if (summaryData.standardCompliance) {
 | 
			
		||||
                    const formattedComplianceText = getPdfInfoSummaryCompliance
 | 
			
		||||
                      .replace('{0}', summaryData.standardCompliance);
 | 
			
		||||
                    summary.push(formattedComplianceText);
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  return summary.join(' ');
 | 
			
		||||
                }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                function displayJsonData(jsonData) {
 | 
			
		||||
@ -77,8 +511,9 @@
 | 
			
		||||
                  header.className = 'card-header';
 | 
			
		||||
                  header.id = `${safeKey}-heading-${depth}`;
 | 
			
		||||
                  const h5Elem = document.createElement('h5');
 | 
			
		||||
                  h5Elem.className = 'mb-0';
 | 
			
		||||
                  h5Elem.className = 'mb-0 d-flex align-items-center';
 | 
			
		||||
 | 
			
		||||
                  // Create the main content (button or text)
 | 
			
		||||
                  if (key === 'XMPMetadata' && typeof value === "string") {
 | 
			
		||||
                    const buttonElem = createButtonElement(key, safeKey, depth);
 | 
			
		||||
                    h5Elem.appendChild(buttonElem);
 | 
			
		||||
@ -95,6 +530,8 @@
 | 
			
		||||
                    h5Elem.textContent = `${key}: ${String(value)}`;
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  // Info buttons removed as requested
 | 
			
		||||
 | 
			
		||||
                  header.appendChild(h5Elem);
 | 
			
		||||
                  card.appendChild(header);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user