test_register_key.html (9629B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 Bug 1247685: Implement `applicationServerKey` for subscription association. 5 6 Any copyright is dedicated to the Public Domain. 7 http://creativecommons.org/licenses/publicdomain/ 8 9 --> 10 <head> 11 <title>Test for Bug 1247685</title> 12 <script src="/tests/SimpleTest/SimpleTest.js"></script> 13 <script type="text/javascript" src="/tests/dom/push/test/test_utils.js"></script> 14 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 15 <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 16 </head> 17 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1247685">Mozilla Bug 1247685</a> 18 <p id="display"></p> 19 <div id="content" style="display: none"> 20 21 </div> 22 <pre id="test"> 23 </pre> 24 25 <script class="testbody" type="text/javascript"> 26 var isTestingMismatchedKey = false; 27 var subscriptions = 0; 28 var testKey; // Generated in `start`. 29 30 function generateKey() { 31 return crypto.subtle.generateKey({ 32 name: "ECDSA", 33 namedCurve: "P-256", 34 }, true, ["sign", "verify"]).then(cryptoKey => 35 crypto.subtle.exportKey("raw", cryptoKey.publicKey) 36 ).then(publicKey => new Uint8Array(publicKey)); 37 } 38 39 var registration; 40 add_task(async function start() { 41 await setupPrefsAndReplaceService({ 42 register(pageRecord) { 43 ok(pageRecord.appServerKey.length, 44 "App server key should not be empty"); 45 if (pageRecord.appServerKey.length != 65) { 46 // eslint-disable-next-line no-throw-literal 47 throw { result: 48 SpecialPowers.Cr.NS_ERROR_DOM_PUSH_INVALID_KEY_ERR }; 49 } 50 if (isTestingMismatchedKey) { 51 // eslint-disable-next-line no-throw-literal 52 throw { result: 53 SpecialPowers.Cr.NS_ERROR_DOM_PUSH_MISMATCHED_KEY_ERR }; 54 } 55 return { 56 endpoint: "https://example.com/push/" + (++subscriptions), 57 appServerKey: pageRecord.appServerKey, 58 }; 59 }, 60 61 registration() { 62 return { 63 endpoint: "https://example.com/push/subWithKey", 64 appServerKey: testKey, 65 }; 66 }, 67 }); 68 await setPushPermission(true); 69 testKey = await generateKey(); 70 71 var url = "worker.js?caller=test_register_key.html"; 72 registration = await navigator.serviceWorker.register(url, {scope: "."}); 73 await waitForActive(registration); 74 }); 75 76 var controlledFrame; 77 add_task(async function createControlledIFrame() { 78 controlledFrame = await injectControlledFrame(); 79 }); 80 81 add_task(async function validKey() { 82 var pushSubscription = await registration.pushManager.subscribe({ 83 applicationServerKey: await generateKey(), 84 }); 85 is(pushSubscription.endpoint, "https://example.com/push/1", 86 "Wrong endpoint for subscription with key"); 87 is(pushSubscription.options.applicationServerKey, 88 pushSubscription.options.applicationServerKey, 89 "App server key getter should return the same object"); 90 }); 91 92 add_task(async function retrieveKey() { 93 var pushSubscription = await registration.pushManager.getSubscription(); 94 is(pushSubscription.endpoint, "https://example.com/push/subWithKey", 95 "Got wrong endpoint for subscription with key"); 96 isDeeply( 97 new Uint8Array(pushSubscription.options.applicationServerKey), 98 testKey, 99 "Got wrong app server key" 100 ); 101 }); 102 103 add_task(async function mismatchedKey() { 104 isTestingMismatchedKey = true; 105 try { 106 await registration.pushManager.subscribe({ 107 applicationServerKey: await generateKey(), 108 }); 109 ok(false, "Should reject for mismatched app server keys"); 110 } catch (error) { 111 ok(error instanceof DOMException, 112 "Wrong exception type for mismatched key"); 113 is(error.name, "InvalidStateError", 114 "Wrong exception name for mismatched key"); 115 } finally { 116 isTestingMismatchedKey = false; 117 } 118 }); 119 120 add_task(async function emptyKeyInWorker() { 121 var errorInfo = await sendRequestToWorker({ 122 type: "subscribeWithKey", 123 key: new ArrayBuffer(0), 124 }); 125 ok(errorInfo.isDOMException, 126 "Wrong exception type in worker for empty key"); 127 is(errorInfo.name, "InvalidAccessError", 128 "Wrong exception name in worker for empty key"); 129 }); 130 131 add_task(async function invalidKeyInWorker() { 132 var errorInfo = await sendRequestToWorker({ 133 type: "subscribeWithKey", 134 key: new Uint8Array([1]), 135 }); 136 ok(errorInfo.isDOMException, 137 "Wrong exception type in worker for invalid key"); 138 is(errorInfo.name, "InvalidAccessError", 139 "Wrong exception name in worker for invalid key"); 140 }); 141 142 add_task(async function validKeyInWorker() { 143 var key = await generateKey(); 144 var data = await sendRequestToWorker({ 145 type: "subscribeWithKey", 146 key, 147 }); 148 is(data.endpoint, "https://example.com/push/2", 149 "Wrong endpoint for subscription with key created in worker"); 150 isDeeply(new Uint8Array(data.key), key, 151 "Wrong app server key for subscription created in worker"); 152 }); 153 154 add_task(async function mismatchedKeyInWorker() { 155 isTestingMismatchedKey = true; 156 try { 157 var errorInfo = await sendRequestToWorker({ 158 type: "subscribeWithKey", 159 key: await generateKey(), 160 }); 161 ok(errorInfo.isDOMException, 162 "Wrong exception type in worker for mismatched key"); 163 is(errorInfo.name, "InvalidStateError", 164 "Wrong exception name in worker for mismatched key"); 165 } finally { 166 isTestingMismatchedKey = false; 167 } 168 }); 169 170 add_task(async function validKeyBuffer() { 171 var key = await generateKey(); 172 var pushSubscription = await registration.pushManager.subscribe({ 173 applicationServerKey: key.buffer, 174 }); 175 is(pushSubscription.endpoint, "https://example.com/push/3", 176 "Wrong endpoint for subscription created with key buffer"); 177 var subscriptionKey = pushSubscription.options.applicationServerKey; 178 isDeeply(new Uint8Array(subscriptionKey), key, 179 "App server key getter should match given key"); 180 }); 181 182 add_task(async function validKeyBufferInWorker() { 183 var key = await generateKey(); 184 var data = await sendRequestToWorker({ 185 type: "subscribeWithKey", 186 key: key.buffer, 187 }); 188 is(data.endpoint, "https://example.com/push/4", 189 "Wrong endpoint for subscription with key buffer created in worker"); 190 isDeeply(new Uint8Array(data.key), key, 191 "App server key getter should match given key for subscription created in worker"); 192 }); 193 194 add_task(async function validKeyString() { 195 var base64Key = "BOp8kf30nj6mKFFSPw_w3JAMS99Bac8zneMJ6B6lmKixUO5XTf4AtdPgYUgWke-XE25JHdcooyLgJML1R57jhKY"; 196 var key = base64UrlDecode(base64Key); 197 var pushSubscription = await registration.pushManager.subscribe({ 198 applicationServerKey: base64Key, 199 }); 200 is(pushSubscription.endpoint, "https://example.com/push/5", 201 "Wrong endpoint for subscription created with Base64-encoded key"); 202 isDeeply(new Uint8Array(pushSubscription.options.applicationServerKey), key, 203 "App server key getter should match Base64-decoded key"); 204 }); 205 206 add_task(async function validKeyStringInWorker() { 207 var base64Key = "BOp8kf30nj6mKFFSPw_w3JAMS99Bac8zneMJ6B6lmKixUO5XTf4AtdPgYUgWke-XE25JHdcooyLgJML1R57jhKY"; 208 var key = base64UrlDecode(base64Key); 209 var data = await sendRequestToWorker({ 210 type: "subscribeWithKey", 211 key: base64Key, 212 }); 213 is(data.endpoint, "https://example.com/push/6", 214 "Wrong endpoint for subscription created with Base64-encoded key in worker"); 215 isDeeply(new Uint8Array(data.key), key, 216 "App server key getter should match decoded key for subscription created in worker"); 217 }); 218 219 add_task(async function invalidKeyString() { 220 try { 221 await registration.pushManager.subscribe({ 222 applicationServerKey: "!@#$^&*", 223 }); 224 ok(false, "Should reject for invalid Base64-encoded keys"); 225 } catch (error) { 226 ok(error instanceof DOMException, 227 "Wrong exception type for invalid Base64-encoded key"); 228 is(error.name, "InvalidCharacterError", 229 "Wrong exception name for invalid Base64-encoded key"); 230 } 231 }); 232 233 add_task(async function invalidKeyStringInWorker() { 234 var errorInfo = await sendRequestToWorker({ 235 type: "subscribeWithKey", 236 key: "!@#$^&*", 237 }); 238 ok(errorInfo.isDOMException, 239 "Wrong exception type in worker for invalid Base64-encoded key"); 240 is(errorInfo.name, "InvalidCharacterError", 241 "Wrong exception name in worker for invalid Base64-encoded key"); 242 }); 243 244 add_task(async function emptyKeyString() { 245 try { 246 await registration.pushManager.subscribe({ 247 applicationServerKey: "", 248 }); 249 ok(false, "Should reject for empty key strings"); 250 } catch (error) { 251 ok(error instanceof DOMException, 252 "Wrong exception type for empty key string"); 253 is(error.name, "InvalidAccessError", 254 "Wrong exception name for empty key string"); 255 } 256 }); 257 258 add_task(async function emptyKeyStringInWorker() { 259 var errorInfo = await sendRequestToWorker({ 260 type: "subscribeWithKey", 261 key: "", 262 }); 263 ok(errorInfo.isDOMException, 264 "Wrong exception type in worker for empty key string"); 265 is(errorInfo.name, "InvalidAccessError", 266 "Wrong exception name in worker for empty key string"); 267 }); 268 269 add_task(async function unsubscribe() { 270 is(subscriptions, 6, "Wrong subscription count"); 271 controlledFrame.remove(); 272 }); 273 274 add_task(async function unregister() { 275 await registration.unregister(); 276 }); 277 278 </script> 279 </body> 280 </html>