mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 01:39:24 +02:00
Refactor YPTWallet configuration: remove unused checks and add donation notification URL handling
https://github.com/WWBN/AVideo/issues/10138
This commit is contained in:
parent
bc240901ed
commit
c147b57f41
4 changed files with 548 additions and 83 deletions
|
@ -75,9 +75,6 @@ class YPTSocket extends PluginAbstract
|
|||
'debugAllUsersSocket',
|
||||
'allow_self_signed',
|
||||
'forceNonSecure',
|
||||
'showTotalOnlineUsersPerVideo',
|
||||
'showTotalOnlineUsersPerLive',
|
||||
'showTotalOnlineUsersPerLiveLink',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -919,17 +919,6 @@ class YPTWallet extends PluginAbstract
|
|||
public function getWalletConfigurationHTML($users_id, $wallet, $walletDataObject)
|
||||
{
|
||||
global $global;
|
||||
if (empty($walletDataObject->CryptoWalletEnabled)) {
|
||||
if (User::isAdmin()) {
|
||||
YPTWallet::showAdminMessage();
|
||||
echo '<div class="alert alert-warning" role="alert">
|
||||
<i class="fa fa-exclamation-triangle"></i>
|
||||
YPTWallet configuration will only appear if <strong>CryptoWalletEnabled</strong> is enabled in the plugin parameters.
|
||||
<br>If you have an empty configuration menu, please hide this button by checking the <strong>hideConfiguration</strong> option in the YPTWallet parameters.
|
||||
</div>';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
include_once $global['systemRootPath'] . 'plugin/YPTWallet/getWalletConfigurationHTML.php';
|
||||
}
|
||||
|
||||
|
@ -985,4 +974,149 @@ class YPTWallet extends PluginAbstract
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function setDonationNotificationURL($users_id, $url)
|
||||
{
|
||||
// Sanitize the URL string for safe database storage
|
||||
$url = trim($url);
|
||||
|
||||
// Remove any null bytes and control characters that could cause issues
|
||||
$url = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $url);
|
||||
|
||||
// HTML encode any special characters to prevent XSS when displayed
|
||||
$url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
// Limit length to prevent database issues
|
||||
if (strlen($url) > 2048) {
|
||||
_error_log("URL too long. Maximum 2048 characters allowed");
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = new User($users_id);
|
||||
return $user->addExternalOptions('donation_notification_url', $url);
|
||||
}
|
||||
|
||||
static function getDonationNotificationURL($users_id)
|
||||
{
|
||||
$user = new User($users_id);
|
||||
return $user->getExternalOptions('donation_notification_url');
|
||||
}
|
||||
|
||||
|
||||
public function afterDonation($from_users_id, $how_much, $videos_id, $users_id, $extraParameters)
|
||||
{
|
||||
$donation_notification_url = self::getDonationNotificationURL($users_id);
|
||||
$webhookSecret = self::getDonationNotificationSecret($users_id); // Get user's secret
|
||||
|
||||
$obj = AVideoPlugin::getObjectData('YPTWallet');
|
||||
|
||||
$data = array(
|
||||
'from_users_id' => $from_users_id,
|
||||
'from_users_name' => User::getNameIdentificationById($from_users_id),
|
||||
'currency' => $obj->currency,
|
||||
'how_much_human' => YPTWallet::formatCurrency($how_much),
|
||||
'how_much' => $how_much,
|
||||
'message' => $extraParameters['message'] ?? '',
|
||||
'videos_id' => $videos_id,
|
||||
'users_id' => $users_id,
|
||||
'time' => time(),
|
||||
'extraParameters' => $extraParameters
|
||||
);
|
||||
|
||||
if (!empty($donation_notification_url) && isValidURL($donation_notification_url)) {
|
||||
_error_log("Sending donation notification via POST to URL: {$donation_notification_url} for user ID: {$users_id}");
|
||||
|
||||
// Create POST data string
|
||||
$postData = http_build_query($data);
|
||||
|
||||
// Generate signature using user's webhook secret
|
||||
$signature = hash_hmac('sha256', $postData, $webhookSecret);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $donation_notification_url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
|
||||
curl_setopt($ch, CURLOPT_NOSIGNAL, true);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, getSelfUserAgent());
|
||||
|
||||
// Add signature to headers
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
'X-Webhook-Signature: sha256=' . $signature,
|
||||
'X-Webhook-Timestamp: ' . $data['time']
|
||||
));
|
||||
|
||||
// Silent execution
|
||||
ob_start();
|
||||
curl_exec($ch);
|
||||
ob_end_clean();
|
||||
curl_close($ch);
|
||||
} else {
|
||||
_error_log("Donation notification URL is not set or invalid for user ID: {$users_id} " . json_encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a cryptographically secure random string.
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
private static function generateRandomString($length = 32)
|
||||
{
|
||||
if (function_exists('random_bytes')) {
|
||||
return bin2hex(random_bytes($length / 2));
|
||||
} elseif (function_exists('openssl_random_pseudo_bytes')) {
|
||||
return bin2hex(openssl_random_pseudo_bytes($length / 2));
|
||||
} else {
|
||||
// fallback (not cryptographically secure)
|
||||
return substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $length)), 0, $length);
|
||||
}
|
||||
}
|
||||
|
||||
static function setDonationNotificationSecret($users_id, $secret = null)
|
||||
{
|
||||
// If no secret provided, generate a new one
|
||||
if (empty($secret)) {
|
||||
$secret = self::generateRandomString(32);
|
||||
}
|
||||
|
||||
// Sanitize the secret
|
||||
$secret = trim($secret);
|
||||
|
||||
// Limit length for database safety
|
||||
if (strlen($secret) > 255) {
|
||||
_error_log("Webhook secret too long. Maximum 255 characters allowed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove any dangerous characters
|
||||
$secret = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $secret);
|
||||
|
||||
$user = new User($users_id);
|
||||
return $user->addExternalOptions('donation_notification_secret', $secret);
|
||||
}
|
||||
|
||||
static function getDonationNotificationSecret($users_id)
|
||||
{
|
||||
$user = new User($users_id);
|
||||
$secret = $user->getExternalOptions('donation_notification_secret');
|
||||
|
||||
// If no secret exists, generate one
|
||||
if (empty($secret)) {
|
||||
$secret = self::generateRandomString(32);
|
||||
self::setDonationNotificationSecret($users_id, $secret);
|
||||
}
|
||||
|
||||
return $secret;
|
||||
}
|
||||
|
||||
static function regenerateDonationNotificationSecret($users_id)
|
||||
{
|
||||
$newSecret = self::generateRandomString(32);
|
||||
return self::setDonationNotificationSecret($users_id, $newSecret);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,15 +5,333 @@ $myWallet = YPTWallet::getWallet(User::getId());
|
|||
<div class="panel-heading"><?php echo __("Configurations"); ?></div>
|
||||
<div class="panel-body">
|
||||
<form id="form">
|
||||
<div class="form-group">
|
||||
<div class="form-group" style="<?php echo $walletDataObject->CryptoWalletEnabled ? '' : 'display:none;' ?>">
|
||||
<label for="CryptoWallet"><?php echo $walletDataObject->CryptoWalletName; ?>:</label>
|
||||
<input type="text" class="form-control" name="CryptoWallet" value="<?php echo $myWallet->getCrypto_wallet_address(); ?>">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success"><i class="fas fa-save"></i> <?php echo __("Save"); ?></button>
|
||||
<div class="form-group">
|
||||
<label for="donation_notification_url">
|
||||
<?php echo __('Donation Notification URL'); ?> (Webhook):
|
||||
<button type="button" class="btn btn-xs btn-info" data-toggle="collapse" data-target="#webhookDocs" style="margin-left: 5px;">
|
||||
<i class="fa fa-question-circle"></i> <?php echo __('Help'); ?>
|
||||
</button>
|
||||
</label>
|
||||
<input type="url" class="form-control" name="donation_notification_url" value="<?php echo YPTWallet::getDonationNotificationUrl(User::getId()); ?>" placeholder="<?php echo __('Donation Notification URL'); ?>"
|
||||
title="<?php echo __('This URL will be called when a donation is made.'); ?>">
|
||||
|
||||
<div class="well well-sm" style="margin-top: 10px;">
|
||||
<h5><i class="fa fa-key"></i> <?php echo __('Your Webhook Secret Key:'); ?></h5>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="webhookSecret" value="<?php echo YPTWallet::getDonationNotificationSecret(User::getId()); ?>" readonly>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" onclick="copyToClipboard(document.getElementById('webhookSecret'))">
|
||||
<i class="fa fa-copy"></i> <?php echo __('Copy'); ?>
|
||||
</button>
|
||||
<button class="btn btn-warning" type="button" onclick="regenerateSecret()" title="<?php echo __('Generate new secret key'); ?>">
|
||||
<i class="fa fa-refresh"></i> <?php echo __('Regenerate'); ?>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<small class="text-muted"><?php echo __('Use this secret to verify webhook signatures. Keep it safe and private!'); ?></small>
|
||||
</div>
|
||||
|
||||
<!-- Webhook Documentation -->
|
||||
<div class="collapse" id="webhookDocs" style="margin-top: 10px;">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<i class="fa fa-info-circle"></i> <?php echo __('Webhook Documentation'); ?>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p><i class="fa fa-globe"></i> <strong><?php echo __('How it works:'); ?></strong></p>
|
||||
<p><?php echo __('When someone makes a donation, AVideo will automatically send a POST request to your URL with the following parameters and security headers:'); ?></p>
|
||||
|
||||
<div class="well well-sm">
|
||||
<h5><i class="fa fa-shield"></i> <?php echo __('Security Headers:'); ?></h5>
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><i class="fa fa-tag"></i> <?php echo __('Header'); ?></th>
|
||||
<th><i class="fa fa-info"></i> <?php echo __('Description'); ?></th>
|
||||
<th><i class="fa fa-eye"></i> <?php echo __('Example'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>X-Webhook-Signature</code></td>
|
||||
<td><?php echo __('HMAC SHA256 signature of the POST data for verification'); ?></td>
|
||||
<td><code>sha256=abc123...</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>X-Webhook-Timestamp</code></td>
|
||||
<td><?php echo __('Unix timestamp when the request was sent'); ?></td>
|
||||
<td><code><?php echo time(); ?></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Content-Type</code></td>
|
||||
<td><?php echo __('Request content type'); ?></td>
|
||||
<td><code>application/x-www-form-urlencoded</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>User-Agent</code></td>
|
||||
<td><?php echo __('Identifies the request as coming from AVideo'); ?></td>
|
||||
<td><code>AVideoStreamer_*</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h5><i class="fa fa-list"></i> <?php echo __('Parameters explained:'); ?></h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><i class="fa fa-tag"></i> <?php echo __('Parameter'); ?></th>
|
||||
<th><i class="fa fa-info"></i> <?php echo __('Description'); ?></th>
|
||||
<th><i class="fa fa-eye"></i> <?php echo __('Example'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>from_users_id</code></td>
|
||||
<td><?php echo __('ID of the user who made the donation'); ?></td>
|
||||
<td><span class="label label-info">1</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>from_users_name</code></td>
|
||||
<td><?php echo __('Name of the user who made the donation'); ?></td>
|
||||
<td><span class="label label-info">John Doe</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>currency</code></td>
|
||||
<td><?php echo __('Currency code configured in wallet'); ?></td>
|
||||
<td><span class="label label-warning">USD</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>how_much</code></td>
|
||||
<td><?php echo __('Raw amount donated (numeric value)'); ?></td>
|
||||
<td><span class="label label-success">21</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>how_much_human</code></td>
|
||||
<td><?php echo __('Formatted amount with currency symbol'); ?></td>
|
||||
<td><span class="label label-success">$21.00</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>message</code></td>
|
||||
<td><?php echo __('Message sent with the donation'); ?></td>
|
||||
<td><span class="label label-default">Great content</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>videos_id</code></td>
|
||||
<td><?php echo __('ID of the video (0 for live chat)'); ?></td>
|
||||
<td><span class="label label-primary">0</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>users_id</code></td>
|
||||
<td><?php echo __('ID of the user receiving the donation (You)'); ?></td>
|
||||
<td><span class="label label-info">1</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>time</code></td>
|
||||
<td><?php echo __('Unix timestamp when the donation was made'); ?></td>
|
||||
<td><span class="label label-default"><?php echo time(); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>extraParameters[superChat]</code></td>
|
||||
<td><?php echo __('Super chat flag (1 if super chat)'); ?></td>
|
||||
<td><span class="label label-warning">1</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>extraParameters[message]</code></td>
|
||||
<td><?php echo __('Duplicate of message parameter for compatibility'); ?></td>
|
||||
<td><span class="label label-default">Great content</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>extraParameters[live_transmitions_history_id]</code></td>
|
||||
<td><?php echo __('Live transmission ID (if donation during live stream)'); ?></td>
|
||||
<td><span class="label label-danger">32</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger">
|
||||
<i class="fa fa-shield"></i>
|
||||
<strong><?php echo __('Security Warning:'); ?></strong>
|
||||
<?php echo __('ALWAYS verify the webhook signature before processing any data. Never trust webhook data without proper signature verification!'); ?>
|
||||
</div>
|
||||
|
||||
<div class="well well-sm">
|
||||
<h5><i class="fa fa-code"></i> <?php echo __('PHP Verification Example:'); ?></h5>
|
||||
<pre><code><?php echo htmlspecialchars('<?php
|
||||
// Step 1: Get headers and raw POST data
|
||||
$signature = $_SERVER[\'HTTP_X_WEBHOOK_SIGNATURE\'] ?? \'\';
|
||||
$timestamp = $_SERVER[\'HTTP_X_WEBHOOK_TIMESTAMP\'] ?? \'\';
|
||||
$rawPostData = file_get_contents(\'php://input\');
|
||||
|
||||
// Step 2: Your webhook secret (copy from above)
|
||||
$webhookSecret = \'YOUR_WEBHOOK_SECRET_FROM_ABOVE\';
|
||||
|
||||
// Step 3: Verify timestamp (optional but recommended)
|
||||
$currentTime = time();
|
||||
$timeDifference = $currentTime - intval($timestamp);
|
||||
if ($timeDifference > 300) { // 5 minutes tolerance
|
||||
http_response_code(400);
|
||||
exit(\'Request expired\');
|
||||
}
|
||||
|
||||
// Step 4: Calculate expected signature
|
||||
$expectedSignature = \'sha256=\' . hash_hmac(\'sha256\', $rawPostData, $webhookSecret);
|
||||
|
||||
// Step 5: Verify signature using timing-safe comparison
|
||||
if (!hash_equals($signature, $expectedSignature)) {
|
||||
http_response_code(401);
|
||||
exit(\'Invalid signature\');
|
||||
}
|
||||
|
||||
// Step 6: Signature is valid, process the webhook data
|
||||
parse_str($rawPostData, $donationData);
|
||||
|
||||
// Now you can safely use the donation data
|
||||
$donorId = $donationData[\'from_users_id\'];
|
||||
$donorName = $donationData[\'from_users_name\'];
|
||||
$amount = $donationData[\'how_much\'];
|
||||
$formattedAmount = $donationData[\'how_much_human\'];
|
||||
$message = $donationData[\'message\'];
|
||||
$videoId = $donationData[\'videos_id\'];
|
||||
$receiverId = $donationData[\'users_id\'];
|
||||
|
||||
// Your processing logic here...
|
||||
// Example: Save to database, send notifications, etc.
|
||||
|
||||
// Always respond with 200 OK
|
||||
http_response_code(200);
|
||||
echo \'Webhook processed successfully\';
|
||||
?>'); ?></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="well well-sm">
|
||||
<h5><i class="fa fa-code"></i> <?php echo __('Node.js/JavaScript Example:'); ?></h5>
|
||||
<pre><code><?php echo htmlspecialchars('const crypto = require(\'crypto\');
|
||||
const express = require(\'express\');
|
||||
const app = express();
|
||||
|
||||
// Middleware to get raw body
|
||||
app.use(\'/webhook\', express.raw({type: \'application/x-www-form-urlencoded\'}));
|
||||
|
||||
app.post(\'/webhook\', (req, res) => {
|
||||
const signature = req.headers[\'x-webhook-signature\'];
|
||||
const timestamp = req.headers[\'x-webhook-timestamp\'];
|
||||
const rawBody = req.body;
|
||||
|
||||
// Your webhook secret
|
||||
const webhookSecret = \'YOUR_WEBHOOK_SECRET_FROM_ABOVE\';
|
||||
|
||||
// Verify timestamp
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
const timeDifference = currentTime - parseInt(timestamp);
|
||||
if (timeDifference > 300) {
|
||||
return res.status(400).send(\'Request expired\');
|
||||
}
|
||||
|
||||
// Calculate expected signature
|
||||
const expectedSignature = \'sha256=\' + crypto
|
||||
.createHmac(\'sha256\', webhookSecret)
|
||||
.update(rawBody)
|
||||
.digest(\'hex\');
|
||||
|
||||
// Verify signature
|
||||
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
|
||||
return res.status(401).send(\'Invalid signature\');
|
||||
}
|
||||
|
||||
// Parse form data
|
||||
const params = new URLSearchParams(rawBody.toString());
|
||||
const donationData = Object.fromEntries(params);
|
||||
|
||||
// Process webhook data
|
||||
console.log(\'Donation received:\', donationData);
|
||||
|
||||
res.status(200).send(\'OK\');
|
||||
});'); ?></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<i class="fa fa-key"></i>
|
||||
<strong><?php echo __('Security Best Practices:'); ?></strong>
|
||||
<ul class="list-unstyled" style="margin-top: 10px;">
|
||||
<li><i class="fa fa-check text-success"></i> <?php echo __('Always use hash_equals() or crypto.timingSafeEqual() for signature comparison'); ?></li>
|
||||
<li><i class="fa fa-check text-success"></i> <?php echo __('Verify timestamp to prevent replay attacks'); ?></li>
|
||||
<li><i class="fa fa-check text-success"></i> <?php echo __('Use the raw POST body for signature calculation, not parsed data'); ?></li>
|
||||
<li><i class="fa fa-check text-success"></i> <?php echo __('Keep your webhook secret private and secure'); ?></li>
|
||||
<li><i class="fa fa-check text-success"></i> <?php echo __('Regenerate your webhook secret if compromised'); ?></li>
|
||||
<li><i class="fa fa-check text-success"></i> <?php echo __('Always respond with HTTP 200 for valid requests'); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<i class="fa fa-exclamation-triangle"></i>
|
||||
<strong><?php echo __('Important:'); ?></strong>
|
||||
<?php echo __('Your webhook endpoint should respond with HTTP 200 status code for successful processing. The request timeout is 1 second, so ensure your endpoint responds quickly.'); ?>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<i class="fa fa-lightbulb-o"></i>
|
||||
<strong><?php echo __('Use Cases:'); ?></strong>
|
||||
<?php echo __('You can use this webhook to integrate with external systems, trigger notifications, update databases, send emails, integrate with Discord/Slack, or create custom donation alerts when donations are received.'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success btn-block"><i class="fas fa-save"></i> <?php echo __("Save"); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function copyToClipboard(element) {
|
||||
element.select();
|
||||
element.setSelectionRange(0, 99999);
|
||||
document.execCommand("copy");
|
||||
avideoToast("<?php echo __('Copied to clipboard!'); ?>");
|
||||
}
|
||||
|
||||
function regenerateSecret() {
|
||||
avideoConfirmCallBack(
|
||||
__('Are you sure you want to generate a new webhook secret? This will invalidate the current one and any existing integrations will need to be updated with the new secret.'),
|
||||
function() {
|
||||
// Confirm callback - user clicked confirm
|
||||
modal.showPleaseWait();
|
||||
$.ajax({
|
||||
url: webSiteRootURL + 'plugin/YPTWallet/view/saveConfiguration.php',
|
||||
data: {
|
||||
regenerate_webhook_secret: 1
|
||||
},
|
||||
type: 'post',
|
||||
success: function(response) {
|
||||
if (!response.error && response.new_webhook_secret) {
|
||||
$('#webhookSecret').val(response.webhook_secret);
|
||||
avideoToastSuccess(__('New webhook secret generated successfully!'));
|
||||
} else {
|
||||
avideoAlertError(__('Error generating new secret'));
|
||||
}
|
||||
modal.hidePleaseWait();
|
||||
},
|
||||
error: function() {
|
||||
avideoAlertError(__('Failed to regenerate webhook secret'));
|
||||
modal.hidePleaseWait();
|
||||
}
|
||||
});
|
||||
},
|
||||
function() {
|
||||
// Cancel callback - user clicked cancel
|
||||
console.log("User cancelled webhook secret regeneration");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$("#form").submit(function(event) {
|
||||
event.preventDefault();
|
||||
|
@ -24,12 +342,15 @@ $myWallet = YPTWallet::getWallet(User::getId());
|
|||
type: 'post',
|
||||
success: function(response) {
|
||||
if (!response.error) {
|
||||
avideoAlert("<?php echo __("Congratulations!"); ?>", "<?php echo __("Configuration Saved"); ?>", "success");
|
||||
avideoAlertSuccess(__("Configuration Saved"));
|
||||
// Update webhook secret display if returned
|
||||
if (response.webhook_secret) {
|
||||
document.getElementById('webhookSecret').value = response.webhook_secret;
|
||||
}
|
||||
} else {
|
||||
avideoAlert("<?php echo __("Sorry!"); ?>", response.msg, "error");
|
||||
avideoAlertError(response.msg);
|
||||
}
|
||||
modal.hidePleaseWait();
|
||||
console.log(response);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -27,6 +27,19 @@ $wallet->setCrypto_wallet_address($_POST['CryptoWallet']);
|
|||
if($wallet->save()){
|
||||
$obj->error = false;
|
||||
}
|
||||
|
||||
if(isset($_REQUEST['donation_notification_url'])){
|
||||
$obj->donation_notification_url = YPTWallet::setDonationNotificationURL(User::getId(), $_REQUEST['donation_notification_url']);
|
||||
}
|
||||
|
||||
// Handle webhook secret regeneration
|
||||
if(isset($_REQUEST['regenerate_webhook_secret']) && $_REQUEST['regenerate_webhook_secret'] == '1'){
|
||||
$obj->new_webhook_secret = YPTWallet::regenerateDonationNotificationSecret(User::getId());
|
||||
}
|
||||
|
||||
// Always return current webhook secret
|
||||
$obj->webhook_secret = YPTWallet::getDonationNotificationSecret(User::getId());
|
||||
|
||||
$obj->walletBalance = $plugin->getBalanceFormated(User::getId());
|
||||
|
||||
echo json_encode($obj);
|
Loading…
Add table
Add a link
Reference in a new issue