mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-07 20:08:53 +00:00
[ticket/17010] Generate VAPID keys with javascript in ACP
PHPBB3-17010
This commit is contained in:
parent
3513c85ee6
commit
7410c3be6f
3 changed files with 109 additions and 22 deletions
|
@ -157,6 +157,68 @@ phpbb.addAjaxCallback('row_delete', function(res) {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* This callback generates the VAPID keys for the web push notification service.
|
||||
*/
|
||||
phpbb.addAjaxCallback('generate_vapid_keys', (res) => {
|
||||
function rawKeyToBase64(rawKey) {
|
||||
const keyBuffer = new Uint8Array(rawKey);
|
||||
let keyText = '';
|
||||
const keyLength = keyBuffer.byteLength;
|
||||
for (let i = 0; i < keyLength; i++) {
|
||||
keyText += String.fromCharCode(keyBuffer[i]);
|
||||
}
|
||||
|
||||
keyText = window.btoa(keyText);
|
||||
return keyText;
|
||||
}
|
||||
|
||||
function base64SafeEncode(base64String) {
|
||||
const base64URL = base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
||||
return base64URL;
|
||||
}
|
||||
|
||||
async function generateVAPIDKeys() {
|
||||
try {
|
||||
// Generate a new key pair using the Subtle Crypto API
|
||||
const keyPair = await crypto.subtle.generateKey(
|
||||
{
|
||||
name: 'ECDH',
|
||||
namedCurve: 'P-256',
|
||||
},
|
||||
true,
|
||||
['deriveKey', 'deriveBits']
|
||||
);
|
||||
|
||||
// Export the private key as a JWK (JSON Web Key) object
|
||||
const privateKeyJwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey);
|
||||
console.log(privateKeyJwk.d);
|
||||
|
||||
const privateKeyString = privateKeyJwk.d;
|
||||
|
||||
// Export the public key as a JWK object
|
||||
const publicKeyBuffer = await crypto.subtle.exportKey('raw', keyPair.publicKey);
|
||||
const publicKeyString = base64SafeEncode(rawKeyToBase64(publicKeyBuffer));
|
||||
console.log(publicKeyString);
|
||||
|
||||
return {
|
||||
privateKey: privateKeyString,
|
||||
publicKey: publicKeyString
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error generating private key:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
generateVAPIDKeys().then(keyPair => {
|
||||
const publicKeyInput = document.querySelector('#webpush_vapid_public');
|
||||
const privateKeyInput = document.querySelector('#webpush_vapid_private');
|
||||
publicKeyInput.value = keyPair.publicKey;
|
||||
privateKeyInput.value = keyPair.privateKey;
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Handler for submitting permissions form in chunks
|
||||
* This call will submit permissions forms in chunks of 5 fieldsets.
|
||||
|
|
|
@ -491,7 +491,7 @@ class acp_board
|
|||
'title' => 'ACP_WEBPUSH_SETTINGS',
|
||||
'vars' => [
|
||||
'legend1' => 'GENERAL_SETTINGS',
|
||||
'webpush_enable' => ['lang' => 'WEBPUSH_ENABLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true],
|
||||
'webpush_enable' => ['lang' => 'WEBPUSH_ENABLE', 'validate' => 'bool', 'type' => 'custom', 'method' => 'webpush_enable', 'explain' => true],
|
||||
'webpush_vapid_public' => ['lang' => 'WEBPUSH_VAPID_PUBLIC', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true],
|
||||
'webpush_vapid_private' => ['lang' => 'WEBPUSH_VAPID_PRIVATE', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true],
|
||||
|
||||
|
@ -539,27 +539,6 @@ class acp_board
|
|||
}
|
||||
}
|
||||
|
||||
if ($mode == 'webpush')
|
||||
{
|
||||
// Create VAPID keys if keys are empty and web push is enabled
|
||||
if ($submit && $cfg_array['webpush_enable'] && $cfg_array['webpush_enable'] != $config['webpush_enable']
|
||||
&& empty($cfg_array['webpush_vapid_public']) && empty($cfg_array['webpush_vapid_private'])
|
||||
&& empty($config['webpush_vapid_public']) && empty($config['webpush_vapid_private']))
|
||||
{
|
||||
try
|
||||
{
|
||||
$vapid_keys = VAPID::createVapidKeys();
|
||||
$cfg_array['webpush_vapid_public'] = $vapid_keys['publicKey'];
|
||||
$cfg_array['webpush_vapid_private'] = $vapid_keys['privateKey'];
|
||||
}
|
||||
catch (\ErrorException $exception)
|
||||
{
|
||||
// Nothing we can do about this, user will have to follow the
|
||||
// documentation and manually create these.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We validate the complete config if wished
|
||||
validate_config_vars($display_vars['vars'], $cfg_array, $error);
|
||||
|
||||
|
@ -1383,4 +1362,49 @@ class acp_board
|
|||
return '<input class="button2" type="submit" id="' . $key . '" name="' . $key . '" value="' . $user->lang('SEND_TEST_EMAIL') . '" />
|
||||
<textarea id="' . $key . '_text" name="' . $key . '_text" placeholder="' . $user->lang('MESSAGE') . '"></textarea>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate form data for web push enable
|
||||
*
|
||||
* @param string $value Webpush enable value
|
||||
* @param string $key Webpush enable config key
|
||||
*
|
||||
* @return array[] Form data
|
||||
*/
|
||||
public function webpush_enable($value, $key): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'tag' => 'radio',
|
||||
'buttons' => [
|
||||
[
|
||||
'name' => "config[$key]",
|
||||
'label' => $this->language->lang('YES'),
|
||||
'type' => 'radio',
|
||||
'class' => 'radio',
|
||||
'value' => 1,
|
||||
'checked' => $value,
|
||||
],
|
||||
[
|
||||
'name' => "config[$key]",
|
||||
'label' => $this->language->lang('NO'),
|
||||
'type' => 'radio',
|
||||
'class' => 'radio',
|
||||
'value' => 0,
|
||||
'checked' => !$value,
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'tag' => 'input',
|
||||
'class' => 'button2',
|
||||
'name' => "config[$key]",
|
||||
'type' => 'button',
|
||||
'value' => $this->language->lang('WEBPUSH_GENERATE_VAPID_KEYS'),
|
||||
'data' => [
|
||||
'ajax' => 'generate_vapid_keys',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -603,6 +603,7 @@ $lang = array_merge($lang, [
|
|||
'ACP_WEBPUSH_SETTINGS_EXPLAIN' => 'Here you can enable and control the use of Webpush for board notifications. Webpush is a simple protocol for the delivery of real-time events to user agents, more commonly known as push messages. It is supported by most modern browsers on desktop and mobile devices.',
|
||||
'WEBPUSH_ENABLE' => 'Enable Webpush',
|
||||
'WEBPUSH_ENABLE_EXPLAIN' => 'Allow receiving notifications via Webpush.<br><em><strong>Note:</strong></em> If VAPID keys have not been set, phpBB will try to automatically create them when enabling Webpush.',
|
||||
'WEBPUSH_GENERATE_VAPID_KEYS' => 'Generate VAPID keys',
|
||||
'WEBPUSH_VAPID_PUBLIC' => 'VAPID public key',
|
||||
'WEBPUSH_VAPID_PUBLIC_EXPLAIN' => 'The VAPID public key will be shared to authenticate push messages sent by your site.<br><em><strong>Warning:</strong> Changing the VAPID public key will automatically invalidate all webpush subscriptions.</em>',
|
||||
'WEBPUSH_VAPID_PRIVATE' => 'VAPID private key',
|
||||
|
|
Loading…
Add table
Reference in a new issue