You've already forked wc-licensed-product
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fc2fe70576 | |||
| f5a1e55710 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.2.1] - 2026-01-22
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- SHA256 hash input changed from text field to file upload field
|
||||||
|
- Checksum files (.sha256 or .txt) can now be uploaded directly
|
||||||
|
- Improved user experience for version integrity verification
|
||||||
|
|
||||||
|
### Technical Details
|
||||||
|
|
||||||
|
- Added `readChecksumFile()` JavaScript function using FileReader API with Promise support
|
||||||
|
- Checksum file format supports both "hash filename" and plain "hash" formats
|
||||||
|
- Added localized error messages for checksum file validation
|
||||||
|
|
||||||
## [0.2.0] - 2026-01-22
|
## [0.2.0] - 2026-01-22
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -101,9 +101,38 @@
|
|||||||
$('#selected_file_name').text('');
|
$('#selected_file_name').text('');
|
||||||
$('#remove-version-file-btn').hide();
|
$('#remove-version-file-btn').hide();
|
||||||
|
|
||||||
// Hide and clear SHA256 hash field
|
// Hide and clear checksum file field
|
||||||
$('#sha256-hash-row').hide();
|
$('#sha256-hash-row').hide();
|
||||||
$('#new_file_hash').val('');
|
$('#new_checksum_file').val('');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read checksum from uploaded file
|
||||||
|
* Supports formats: "hash filename" or just "hash"
|
||||||
|
*/
|
||||||
|
readChecksumFile: function(file) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
if (!file) {
|
||||||
|
resolve('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(e) {
|
||||||
|
var content = e.target.result.trim();
|
||||||
|
// Extract hash from content (format: "hash filename" or just "hash")
|
||||||
|
var match = content.match(/^([a-fA-F0-9]{64})/);
|
||||||
|
if (match) {
|
||||||
|
resolve(match[1].toLowerCase());
|
||||||
|
} else {
|
||||||
|
reject(new Error(wcLicensedProductVersions.strings.invalidChecksumFile || 'Invalid checksum file format'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.onerror = function() {
|
||||||
|
reject(new Error(wcLicensedProductVersions.strings.checksumReadError || 'Failed to read checksum file'));
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,13 +163,14 @@
|
|||||||
addVersion: function(e) {
|
addVersion: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
var self = WCLicensedProductVersions;
|
||||||
var $btn = $(this);
|
var $btn = $(this);
|
||||||
var $spinner = $btn.siblings('.spinner');
|
var $spinner = $btn.siblings('.spinner');
|
||||||
var productId = $btn.data('product-id');
|
var productId = $btn.data('product-id');
|
||||||
var version = $('#new_version').val().trim();
|
var version = $('#new_version').val().trim();
|
||||||
var releaseNotes = $('#new_release_notes').val().trim();
|
var releaseNotes = $('#new_release_notes').val().trim();
|
||||||
var attachmentId = $('#new_attachment_id').val();
|
var attachmentId = $('#new_attachment_id').val();
|
||||||
var fileHash = $('#new_file_hash').val().trim();
|
var checksumFile = $('#new_checksum_file')[0].files[0];
|
||||||
|
|
||||||
// Validate version
|
// Validate version
|
||||||
if (!version) {
|
if (!version) {
|
||||||
@@ -156,6 +186,8 @@
|
|||||||
$btn.prop('disabled', true);
|
$btn.prop('disabled', true);
|
||||||
$spinner.addClass('is-active');
|
$spinner.addClass('is-active');
|
||||||
|
|
||||||
|
// Read checksum file if provided, then submit
|
||||||
|
self.readChecksumFile(checksumFile).then(function(fileHash) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: wcLicensedProductVersions.ajaxUrl,
|
url: wcLicensedProductVersions.ajaxUrl,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
@@ -183,7 +215,7 @@
|
|||||||
$('#selected_file_name').text('');
|
$('#selected_file_name').text('');
|
||||||
$('#remove-version-file-btn').hide();
|
$('#remove-version-file-btn').hide();
|
||||||
$('#sha256-hash-row').hide();
|
$('#sha256-hash-row').hide();
|
||||||
$('#new_file_hash').val('');
|
$('#new_checksum_file').val('');
|
||||||
} else {
|
} else {
|
||||||
alert(response.data.message || wcLicensedProductVersions.strings.error);
|
alert(response.data.message || wcLicensedProductVersions.strings.error);
|
||||||
}
|
}
|
||||||
@@ -196,6 +228,11 @@
|
|||||||
$spinner.removeClass('is-active');
|
$spinner.removeClass('is-active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}).catch(function(error) {
|
||||||
|
alert(error.message);
|
||||||
|
$btn.prop('disabled', false);
|
||||||
|
$spinner.removeClass('is-active');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteVersion: function(e) {
|
deleteVersion: function(e) {
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1
releases/wc-licensed-product-0.2.0.sha256
Normal file
1
releases/wc-licensed-product-0.2.0.sha256
Normal file
@@ -0,0 +1 @@
|
|||||||
|
20d90f61721b4579cb979cd19b0262f3286c3510dcb0345fe5e8da2703e3836f wc-licensed-product-0.2.0.zip
|
||||||
BIN
releases/wc-licensed-product-0.2.0.zip
Normal file
BIN
releases/wc-licensed-product-0.2.0.zip
Normal file
Binary file not shown.
@@ -99,10 +99,10 @@ final class VersionAdminController
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr id="sha256-hash-row" style="display: none;">
|
<tr id="sha256-hash-row" style="display: none;">
|
||||||
<th><label for="new_file_hash"><?php esc_html_e('SHA256 Hash', 'wc-licensed-product'); ?></label></th>
|
<th><label for="new_checksum_file"><?php esc_html_e('Checksum File', 'wc-licensed-product'); ?></label></th>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" id="new_file_hash" name="new_file_hash" class="large-text" placeholder="<?php esc_attr_e('Enter SHA256 checksum...', 'wc-licensed-product'); ?>" pattern="[a-fA-F0-9]{64}" />
|
<input type="file" id="new_checksum_file" name="new_checksum_file" accept=".sha256,.txt" />
|
||||||
<p class="description"><?php esc_html_e('SHA256 checksum of the uploaded file (optional but recommended for integrity verification).', 'wc-licensed-product'); ?></p>
|
<p class="description"><?php esc_html_e('Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity.', 'wc-licensed-product'); ?></p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -218,6 +218,8 @@ final class VersionAdminController
|
|||||||
'error' => __('An error occurred. Please try again.', 'wc-licensed-product'),
|
'error' => __('An error occurred. Please try again.', 'wc-licensed-product'),
|
||||||
'selectFile' => __('Select Download File', 'wc-licensed-product'),
|
'selectFile' => __('Select Download File', 'wc-licensed-product'),
|
||||||
'useThisFile' => __('Use this file', 'wc-licensed-product'),
|
'useThisFile' => __('Use this file', 'wc-licensed-product'),
|
||||||
|
'invalidChecksumFile' => __('Invalid checksum file format. File must contain a 64-character SHA256 hash.', 'wc-licensed-product'),
|
||||||
|
'checksumReadError' => __('Failed to read checksum file.', 'wc-licensed-product'),
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Plugin Name: WooCommerce Licensed Product
|
* Plugin Name: WooCommerce Licensed Product
|
||||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
||||||
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
||||||
* Version: 0.2.0
|
* Version: 0.2.1
|
||||||
* Author: Marco Graetsch
|
* Author: Marco Graetsch
|
||||||
* Author URI: https://src.bundespruefstelle.ch/magdev
|
* Author URI: https://src.bundespruefstelle.ch/magdev
|
||||||
* License: GPL-2.0-or-later
|
* License: GPL-2.0-or-later
|
||||||
@@ -28,7 +28,7 @@ if (!defined('ABSPATH')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Plugin constants
|
// Plugin constants
|
||||||
define('WC_LICENSED_PRODUCT_VERSION', '0.2.0');
|
define('WC_LICENSED_PRODUCT_VERSION', '0.2.1');
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||||
|
|||||||
Reference in New Issue
Block a user