-
Notifications
You must be signed in to change notification settings - Fork 1
Secure “Content Unlocking” Flow (Server-Verified Login Tokens) #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Secure “Content Unlocking” Flow (Server-Verified Login Tokens) #92
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a secure content unlocking flow that validates payment transactions on the server before granting access to paywalled content. The key security improvement is the introduction of server-verified unlock tokens that prevent unauthorized content access.
Key Changes:
- Introduced a two-step validation process: first validating the unlock transaction, then marking payment as successful using a server-issued token
- Added
unlock_tokenandusedfields to the database schema to track transaction validation state - Refactored the JavaScript payment flow to use
onCloseinstead ofonSuccessfor better reliability
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| includes/class-paybutton-ajax.php | Added ajax_validate_unlock_tx() endpoint and refactored mark_payment_successful() to verify unlock tokens before granting access |
| includes/class-paybutton-activator.php | Updated database schema to include unlock_token, used flag, and additional indexes for improved query performance |
| assets/js/paywalled-content.js | Restructured payment flow to validate transactions and retrieve unlock tokens before marking payment successful |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $table_name = $wpdb->prefix . 'paybutton_paywall_unlocked'; | ||
|
|
||
| $sql = "CREATE TABLE IF NOT EXISTS $table_name ( | ||
| $sql = "CREATE TABLE $table_name ( |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing from CREATE TABLE IF NOT EXISTS to CREATE TABLE will cause the activation to fail if the table already exists. This breaks plugin reactivation and updates. Restore the IF NOT EXISTS clause.
|
|
||
| $sql_login = "CREATE TABLE IF NOT EXISTS $login_table ( | ||
| id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, | ||
| $sql_login = "CREATE TABLE $login_table ( |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing from CREATE TABLE IF NOT EXISTS to CREATE TABLE will cause the activation to fail if the table already exists. This breaks plugin reactivation and updates. Restore the IF NOT EXISTS clause.
| $sql_login = "CREATE TABLE $login_table ( | |
| $sql_login = "CREATE TABLE IF NOT EXISTS $login_table ( |
assets/js/paywalled-content.js
Outdated
| configData.onSuccess = function(tx) { | ||
| $.ajax({ | ||
|
|
||
| // Shared state: user wallet add + unlock tx captured in onSuccess, consumed in onClose. |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'add' to 'address'.
| // Shared state: user wallet add + unlock tx captured in onSuccess, consumed in onClose. | |
| // Shared state: user wallet address + unlock tx captured in onSuccess, consumed in onClose. |
| } | ||
|
|
||
| /** | ||
| * AJAX endpoint to validate a content–unlock transaction. |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace en-dash (–) with standard hyphen (-) for consistency with standard naming conventions.
| * AJAX endpoint to validate a content–unlock transaction. | |
| * AJAX endpoint to validate a content-unlock transaction. |
| } | ||
|
|
||
| // Generate a random, unguessable token | ||
| $raw = random_bytes(18); // ~24 chars base64url |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states '~24 chars base64url' but the calculation is imprecise. 18 bytes encodes to exactly 24 base64 characters. Consider updating the comment to '24 chars base64url' for accuracy.
| $raw = random_bytes(18); // ~24 chars base64url | |
| $raw = random_bytes(18); // 24 chars base64url |
Klakurka
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably good to merge but we can remove some of this commented out logging.
| // if ($wpdb->last_error) { | ||
| // error_log('[paybutton] insert error: ' . $wpdb->last_error); | ||
| // } else { | ||
| // error_log('[paybutton] insert ok id=' . $wpdb->insert_id); | ||
| // } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I will keep it for future reference
No description provided.