mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-27 21:58:52 +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
|
* Handler for submitting permissions form in chunks
|
||||||
* This call will submit permissions forms in chunks of 5 fieldsets.
|
* This call will submit permissions forms in chunks of 5 fieldsets.
|
||||||
|
|
|
@ -491,7 +491,7 @@ class acp_board
|
||||||
'title' => 'ACP_WEBPUSH_SETTINGS',
|
'title' => 'ACP_WEBPUSH_SETTINGS',
|
||||||
'vars' => [
|
'vars' => [
|
||||||
'legend1' => 'GENERAL_SETTINGS',
|
'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_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],
|
'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
|
// We validate the complete config if wished
|
||||||
validate_config_vars($display_vars['vars'], $cfg_array, $error);
|
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') . '" />
|
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>';
|
<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.',
|
'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' => '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_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' => '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_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',
|
'WEBPUSH_VAPID_PRIVATE' => 'VAPID private key',
|
||||||
|
|
Loading…
Add table
Reference in a new issue