Compare commits
9 Commits
master
...
unsubscrib
Author | SHA1 | Date |
---|---|---|
Matthew Raymer | 608b826d4e | 1 year ago |
Matthew Raymer | 2125a0c32b | 1 year ago |
Matthew Raymer | 5570c0e3dd | 1 year ago |
Matthew Raymer | d3dd048efd | 1 year ago |
Matthew Raymer | 9075ea8c91 | 1 year ago |
Matthew Raymer | 4a12fc92b5 | 1 year ago |
Matthew Raymer | fdbf0e3b9c | 1 year ago |
Matthew Raymer | bcb636c150 | 1 year ago |
Matthew Raymer | 160c0ceff7 | 1 year ago |
18 changed files with 9909 additions and 9722 deletions
@ -1,3 +1,5 @@ |
|||
*~ |
|||
node_modules |
|||
build |
|||
web_push |
|||
data |
@ -0,0 +1,3 @@ |
|||
#!/bin/bash |
|||
|
|||
docker build . -t endorser-push-server:1.0 --no-cache |
Binary file not shown.
@ -0,0 +1 @@ |
|||
hello! |
@ -0,0 +1,5 @@ |
|||
-----BEGIN EC PRIVATE KEY----- |
|||
MHcCAQEEIOjRzTX6T5FkhmOscZZdGp1b1PuOgk2p/YoJ7abFaJPPoAoGCCqGSM49 |
|||
AwEHoUQDQgAEQazvs+7/4y9drkN8RZCB3ZCFVhMZQLtcJmgeY5x9+RXqYE18VHJs |
|||
qagywecu9JLckZFFcraOX2hsifyEPQgCYw== |
|||
-----END EC PRIVATE KEY----- |
@ -0,0 +1 @@ |
|||
A¬ï³îÿã/]®C|E��Ý�…V@»\&hcœ}ùê`M|Trl©¨2Áç.ô’Ü‘‘Er¶Ž_hl‰ü„=c |
Binary file not shown.
@ -0,0 +1,4 @@ |
|||
-----BEGIN PUBLIC KEY----- |
|||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQazvs+7/4y9drkN8RZCB3ZCFVhMZ |
|||
QLtcJmgeY5x9+RXqYE18VHJsqagywecu9JLckZFFcraOX2hsifyEPQgCYw== |
|||
-----END PUBLIC KEY----- |
Binary file not shown.
@ -0,0 +1,74 @@ |
|||
|
|||
# NOTES on working with Cryptographic Keys |
|||
|
|||
Since the VAPID key pair was created using cyprto.createECDH we could reconstitute our public key |
|||
using only the private key: |
|||
``` |
|||
const curveName = 'prime256v1'; |
|||
const ecdh = crypto.createECDH(curveName); |
|||
const privateKeyBuffer = Buffer.from(privateKey, 'base64'); |
|||
ecdh.setPrivateKey(privateKeyBuffer); |
|||
const rawPublicKeyBuffer = ecdh.getPublicKey(); |
|||
|
|||
``` |
|||
|
|||
Unfortunately, crypto module creates only "raw" keys. And when working with jsonwebtoken.sign method |
|||
we must have a PEM or something with ASN metadata. So, we create PEMs using eckeys-util module: |
|||
|
|||
``` |
|||
const pems = ecKeyUtils.generatePem({curveName, privateKey: ecdh.getPrivateKey(), publicKey: rawPublicKeyBuffer }); |
|||
|
|||
console.log("privateKey: ", pems.privateKey); |
|||
console.log(); |
|||
console.log("publicKey: ", pems.publicKey); |
|||
|
|||
const jwtToken = jwt.sign(jwtInfo, pems.privateKey, { algorithm: 'ES256' }); |
|||
``` |
|||
|
|||
|
|||
I trie here to create my own ASN1 metadata but this seems doomed due to ignorance of what were the required |
|||
components: |
|||
``` |
|||
const asn1Header = Buffer.from('3059301306072a8648ce3d020106082a8648ce3d030107034200', 'hex'); |
|||
const derPublicKeyBuffer = Buffer.concat([asn1Header, rawPublicKeyBuffer]); |
|||
const base64DerPublicKey = derPublicKeyBuffer.toString('base64'); |
|||
console.log("base64DerPublicKey: ", base64DerPublicKey) |
|||
``` |
|||
Such an approach creates a DER key pair. An alternative to that method is: |
|||
``` |
|||
const ders = ecKeyUtils.generateDer({curveName, privateKey: ecdh.getPrivateKey(), publicKey: rawPublicKeyBuffer }); |
|||
console.log("privateKey: ", ders.privateKey); |
|||
console.log("publicKey: ", ders.publicKey); |
|||
``` |
|||
|
|||
... using eckeys-util again ... but I'm not 100% sure if these have all the necessary ASN1 metadata AND |
|||
the DER key will produce this error ... |
|||
|
|||
``` |
|||
Error: secretOrPrivateKey must be an asymmetric key when using ES256 |
|||
at module.exports [as sign] (/usr/src/app/node_modules/jsonwebtoken/sign.js:124:22) |
|||
|
|||
``` |
|||
... when used in the sign method. So, apparently, sign does not like the DER binary format but it is |
|||
fine with PEM. |
|||
|
|||
## When sending a notification request to the Mozilla endpoint it does not like the Crypto-Key header: |
|||
|
|||
``` |
|||
{ |
|||
"code":400, |
|||
"errno":110, |
|||
"error":"Bad Request", |
|||
"message":"Invalid aes128gcm Crypto-Key header", |
|||
"more_info":"http://autopush.readthedocs.io/en/latest/http.html#error-codes" |
|||
} |
|||
|
|||
``` |
|||
|
|||
fcm.google.com push server: |
|||
|
|||
``` |
|||
authorization header had invalid format. authorization header should have the following format: t=jwtToken; k=base64(publicApplicationServerKey) |
|||
|
|||
403 |
|||
``` |
File diff suppressed because it is too large
@ -1,58 +1,59 @@ |
|||
{ |
|||
"name": "node-typescript-boilerplate", |
|||
"version": "0.0.0", |
|||
"description": "Minimalistic boilerplate to quick-start Node.js development in TypeScript.", |
|||
"type": "module", |
|||
"engines": { |
|||
"node": ">= 18.12 <19" |
|||
}, |
|||
"devDependencies": { |
|||
"@types/body-parser": "^1.19.2", |
|||
"@types/express": "^4.17.17", |
|||
"@types/jest": "~29.5", |
|||
"@types/jsonwebtoken": "^9.0.2", |
|||
"@types/node": "~20", |
|||
"@types/sqlite3": "^3.1.8", |
|||
"@typescript-eslint/eslint-plugin": "^6.4.0", |
|||
"@typescript-eslint/parser": "^6.4.0", |
|||
"eslint": "~8.47", |
|||
"eslint-config-prettier": "~9.0", |
|||
"eslint-plugin-jest": "~27.2", |
|||
"jest": "~29.6", |
|||
"prettier": "~3.0", |
|||
"rimraf": "~5.0", |
|||
"ts-api-utils": "~1.0", |
|||
"ts-jest": "~29.1", |
|||
"typescript": "~5.1" |
|||
}, |
|||
"scripts": { |
|||
"start": "node build/src/main.js", |
|||
"clean": "rimraf coverage build tmp", |
|||
"prebuild": "npm run lint", |
|||
"build": "tsc -p tsconfig.json", |
|||
"build:watch": "tsc -w -p tsconfig.json", |
|||
"build:release": "npm run clean && tsc -p tsconfig.release.json", |
|||
"lint": "eslint . --ext .ts --ext .mts", |
|||
"test": "jest --coverage", |
|||
"prettier": "prettier --config .prettierrc --write .", |
|||
"test:watch": "jest --watch" |
|||
}, |
|||
"author": "Jakub Synowiec <jsynowiec@users.noreply.github.com>", |
|||
"license": "Apache-2.0", |
|||
"dependencies": { |
|||
"body-parser": "^1.20.2", |
|||
"elliptic": "^6.5.4", |
|||
"express": "^4.18.2", |
|||
"http_ece": "^1.1.0", |
|||
"jsonwebtoken": "^9.0.1", |
|||
"node-fetch": "^3.3.2", |
|||
"npm-check-updates": "16.11.1", |
|||
"reflect-metadata": "^0.1.13", |
|||
"sqlite3": "^5.1.6", |
|||
"tslib": "~2.6", |
|||
"typeorm": "^0.3.17" |
|||
}, |
|||
"volta": { |
|||
"node": "18.12.1" |
|||
} |
|||
"name": "node-typescript-boilerplate", |
|||
"version": "0.0.0", |
|||
"description": "Minimalistic boilerplate to quick-start Node.js development in TypeScript.", |
|||
"type": "module", |
|||
"engines": { |
|||
"node": ">= 18.12 <19" |
|||
}, |
|||
"devDependencies": { |
|||
"@types/body-parser": "^1.19.2", |
|||
"@types/express": "^4.17.17", |
|||
"@types/jest": "~29.5", |
|||
"@types/jsonwebtoken": "^9.0.2", |
|||
"@types/node": "~20", |
|||
"@types/sqlite3": "^3.1.8", |
|||
"@typescript-eslint/eslint-plugin": "^6.4.0", |
|||
"@typescript-eslint/parser": "^6.4.0", |
|||
"eslint": "~8.47", |
|||
"eslint-config-prettier": "~9.0", |
|||
"eslint-plugin-jest": "~27.2", |
|||
"jest": "~29.6", |
|||
"prettier": "~3.0", |
|||
"rimraf": "~5.0", |
|||
"ts-api-utils": "~1.0", |
|||
"ts-jest": "~29.1", |
|||
"typescript": "~5.1" |
|||
}, |
|||
"scripts": { |
|||
"start": "node build/src/main.js", |
|||
"clean": "rimraf coverage build tmp", |
|||
"prebuild": "npm run lint", |
|||
"build": "tsc -p tsconfig.json", |
|||
"build:watch": "tsc -w -p tsconfig.json", |
|||
"build:release": "npm run clean && tsc -p tsconfig.release.json", |
|||
"lint": "eslint . --ext .ts --ext .mts", |
|||
"test": "jest --coverage", |
|||
"prettier": "prettier --config .prettierrc --write .", |
|||
"test:watch": "jest --watch" |
|||
}, |
|||
"author": "Jakub Synowiec <jsynowiec@users.noreply.github.com>", |
|||
"license": "Apache-2.0", |
|||
"dependencies": { |
|||
"body-parser": "^1.20.2", |
|||
"eckey-utils": "^0.7.13", |
|||
"elliptic": "^6.5.4", |
|||
"express": "^4.18.2", |
|||
"http_ece": "^1.1.0", |
|||
"jsonwebtoken": "^9.0.1", |
|||
"node-fetch": "^3.3.2", |
|||
"npm-check-updates": "16.11.1", |
|||
"reflect-metadata": "^0.1.13", |
|||
"sqlite3": "^5.1.6", |
|||
"tslib": "~2.6", |
|||
"typeorm": "^0.3.17" |
|||
}, |
|||
"volta": { |
|||
"node": "18.12.1" |
|||
} |
|||
} |
|||
|
Binary file not shown.
Loading…
Reference in new issue