diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index 25a6527481..67956e946a 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -160,24 +160,13 @@ 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; - } +phpbb.addAjaxCallback('generate_vapid_keys', () => { + /** + * Generate VAPID keypair with public and private key string + * + * @returns {Promise<{privateKey: string, publicKey: string}|null>} + */ async function generateVAPIDKeys() { try { // Generate a new key pair using the Subtle Crypto API @@ -190,28 +179,26 @@ phpbb.addAjaxCallback('generate_vapid_keys', (res) => { ['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); + const publicKeyString = phpbb.base64UrlEncode(phpbb.rawKeyToBase64(publicKeyBuffer)); return { privateKey: privateKeyString, publicKey: publicKeyString }; } catch (error) { - console.error('Error generating private key:', error); + console.error('Error generating keys with SubtleCrypto:', error); return null; } } generateVAPIDKeys().then(keyPair => { + if (!keyPair) { + return; + } const publicKeyInput = document.querySelector('#webpush_vapid_public'); const privateKeyInput = document.querySelector('#webpush_vapid_private'); publicKeyInput.value = keyPair.publicKey; diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index d301cc8da8..c0b225214d 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -1677,6 +1677,33 @@ phpbb.getFunctionByName = function (functionName) { return context[func]; }; +/** + * Convert raw key ArrayBuffer to base64 string. + * + * @param {ArrayBuffer} rawKey Raw key array buffer as exported by SubtleCrypto exportKey() + * @returns {string} Base64 encoded raw key string + */ +phpbb.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]); + } + + return window.btoa(keyText); +}; + +/** + * Base64URL encode base64 encoded string + * + * @param {string} base64String Base64 encoded string + * @returns {string} Base64URL encoded string + */ +phpbb.base64UrlEncode = (base64String) => { + return base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); +}; + /** * Register page dropdowns. */