FIX: FCM pushes fixed due to deprecation of legacy api (#292)
* FIX: FCM pushes fixed due to deprecation of legacy api
This commit is contained in:
parent
b28dd3eb2e
commit
5d3f630a01
@ -87,18 +87,22 @@ Works well on Heroku (you'll need `JawsDB Maria` addon)
|
||||
Set them as env variables or put them into `.env` file in project root dir.
|
||||
|
||||
- `JAWSDB_MARIA_URL` for example `mysql://username:password@host:port/database`
|
||||
- `FCM_SERVER_KEY` hex encoded
|
||||
- ~~`FCM_SERVER_KEY` hex encoded~~ deprecated (in favor of json key file) after FCM XMPP and HTTP legacy APIs was deprecated; the new one is HTTP v1 API; theres also a new uri to post payload
|
||||
- `APNS_P8` hex encoded
|
||||
- `APNS_P8_KID` issuer key which is "key ID" of your p8 file
|
||||
- `APPLE_TEAM_ID` "team ID" of your developer account
|
||||
- `BITCOIN_RPC` for example `http://username:password@host:8332`
|
||||
- `APNS_TOPIC` for example `io.bluewallet.bluewallet`
|
||||
- `GOOGLE_KEY_FILE` - json file with Google key for FCM, in hex
|
||||
- `GOOGLE_PROJECT_ID` - acquired with the key file
|
||||
|
||||
|
||||
### Getting certificates
|
||||
|
||||
- outdated https://dev.to/jakubkoci/react-native-push-notifications-313i
|
||||
- https://stackoverflow.com/questions/44631803/ios-swift-how-to-create-p8-file/67533665#67533665
|
||||
- get P8 hex `xxd -p file.p8 | tr -d '\n'`
|
||||
- get P8 hex `xxd -p file.p8 | tr -d '\n'` (google key file as well)
|
||||
- https://firebase.google.com/docs/cloud-messaging/migrate-v1
|
||||
|
||||
### License
|
||||
|
||||
|
||||
411
package-lock.json
generated
411
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "groundcontrol",
|
||||
"version": "2.3.4",
|
||||
"version": "3.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
@ -13,6 +13,7 @@
|
||||
"dotenv": "^16.0.2",
|
||||
"express": "^4.21.1",
|
||||
"express-rate-limit": "^6.6.0",
|
||||
"google-auth-library": "^9.15.0",
|
||||
"helmet": "^5.1.0",
|
||||
"jayson": "^3.6.6",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
@ -173,6 +174,15 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
|
||||
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
@ -234,6 +244,15 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/bignumber.js": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
|
||||
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
@ -720,6 +739,12 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/eyes": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
|
||||
@ -807,6 +832,68 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gaxios": {
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
|
||||
"integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"is-stream": "^2.0.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gaxios/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/gaxios/node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/gcp-metadata": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
|
||||
"integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"gaxios": "^6.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/generate-function": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
|
||||
@ -871,6 +958,44 @@
|
||||
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/google-auth-library": {
|
||||
"version": "9.15.0",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz",
|
||||
"integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"gaxios": "^6.1.1",
|
||||
"gcp-metadata": "^6.1.0",
|
||||
"gtoken": "^7.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/google-auth-library/node_modules/jwa": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/google-auth-library/node_modules/jws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
@ -882,6 +1007,40 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gtoken": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
|
||||
"integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"gaxios": "^6.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gtoken/node_modules/jwa": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/gtoken/node_modules/jws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
@ -957,6 +1116,42 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.2",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent/node_modules/debug": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
@ -1022,6 +1217,18 @@
|
||||
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isomorphic-ws": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
|
||||
@ -1075,6 +1282,15 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/json-bigint": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bignumber.js": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
@ -1770,6 +1986,12 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
@ -2133,6 +2355,22 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
@ -2375,6 +2613,11 @@
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA=="
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
|
||||
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
@ -2416,6 +2659,11 @@
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
|
||||
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
@ -2759,6 +3007,11 @@
|
||||
"integrity": "sha512-HFN2+4ZGdkQOS8Qli4z6knmJFnw6lZed67o6b7RGplWeb1Z0s8VXaj3dUgPIdm9hrhZXTRpCTHXA0/2Eqex0vA==",
|
||||
"requires": {}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"eyes": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
|
||||
@ -2815,6 +3068,42 @@
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"gaxios": {
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
|
||||
"integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
|
||||
"requires": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"is-stream": "^2.0.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"gcp-metadata": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
|
||||
"integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
|
||||
"requires": {
|
||||
"gaxios": "^6.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"generate-function": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
|
||||
@ -2864,6 +3153,40 @@
|
||||
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
|
||||
"dev": true
|
||||
},
|
||||
"google-auth-library": {
|
||||
"version": "9.15.0",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz",
|
||||
"integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"gaxios": "^6.1.1",
|
||||
"gcp-metadata": "^6.1.0",
|
||||
"gtoken": "^7.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"jwa": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||
"requires": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"jws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||
"requires": {
|
||||
"jwa": "^2.0.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
@ -2872,6 +3195,36 @@
|
||||
"get-intrinsic": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"gtoken": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
|
||||
"integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
|
||||
"requires": {
|
||||
"gaxios": "^6.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"jwa": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||
"requires": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"jws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||
"requires": {
|
||||
"jwa": "^2.0.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
@ -2920,6 +3273,30 @@
|
||||
"toidentifier": "1.0.1"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||
"requires": {
|
||||
"agent-base": "^7.1.2",
|
||||
"debug": "4"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||
"requires": {
|
||||
"ms": "^2.1.3"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
@ -2962,6 +3339,11 @@
|
||||
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
|
||||
},
|
||||
"isomorphic-ws": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
|
||||
@ -3006,6 +3388,14 @@
|
||||
"argparse": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"json-bigint": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||
"requires": {
|
||||
"bignumber.js": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
@ -3518,6 +3908,11 @@
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
@ -3709,6 +4104,20 @@
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
||||
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "groundcontrol",
|
||||
"version": "2.3.4",
|
||||
"version": "3.0.0",
|
||||
"description": "GroundControl push server API",
|
||||
"devDependencies": {
|
||||
"@types/node": "18.7.16",
|
||||
@ -13,6 +13,7 @@
|
||||
"dotenv": "^16.0.2",
|
||||
"express": "^4.21.1",
|
||||
"express-rate-limit": "^6.6.0",
|
||||
"google-auth-library": "^9.15.0",
|
||||
"helmet": "^5.1.0",
|
||||
"jayson": "^3.6.6",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { GoogleAuth } from "google-auth-library";
|
||||
import { DataSource } from "typeorm";
|
||||
import { PushLog } from "../entity/PushLog";
|
||||
import { TokenToAddress } from "../entity/TokenToAddress";
|
||||
@ -8,11 +9,18 @@ const jwt = require("jsonwebtoken");
|
||||
const http2 = require("http2");
|
||||
require("dotenv").config();
|
||||
|
||||
if (!process.env.APNS_P8 || !process.env.APPLE_TEAM_ID || !process.env.APNS_P8_KID || !process.env.FCM_SERVER_KEY) {
|
||||
if (!process.env.APNS_P8 || !process.env.APPLE_TEAM_ID || !process.env.APNS_P8_KID || !process.env.GOOGLE_KEY_FILE || !process.env.GOOGLE_PROJECT_ID) {
|
||||
console.error("not all env variables set");
|
||||
process.exit();
|
||||
}
|
||||
|
||||
const keyFileStr = Buffer.from(process.env.GOOGLE_KEY_FILE, "hex").toString("ascii");
|
||||
require('fs').writeFileSync('/tmp/google_key_file.json', keyFileStr, {encoding: "ascii"});
|
||||
const auth = new GoogleAuth({
|
||||
keyFile: '/tmp/google_key_file.json',
|
||||
scopes: 'https://www.googleapis.com/auth/cloud-platform',
|
||||
});
|
||||
|
||||
/**
|
||||
* Since we cant attach any code to openapi schema definition, this is a repository of transforming pushnotification object
|
||||
* (thats created from apenapi schema) to actual payload thats gona be pushed to fcm/apns. In most basic case we would
|
||||
@ -29,8 +37,10 @@ export class GroundControlToMajorTom {
|
||||
protected static _jwtToken: string = "";
|
||||
protected static _jwtTokenMicroTimestamp: number = 0;
|
||||
|
||||
static getGoogleServerKey() {
|
||||
return process.env.FCM_SERVER_KEY;
|
||||
static async getGoogleCredentials() {
|
||||
const client = await auth.getClient();
|
||||
const accessTokenResponse = await client.getAccessToken();
|
||||
return accessTokenResponse.token; // `accessTokenResponse.token` contains the short-lived access token
|
||||
}
|
||||
|
||||
static getApnsJwtToken(): string {
|
||||
@ -64,15 +74,19 @@ export class GroundControlToMajorTom {
|
||||
serverKey: string,
|
||||
apnsP8: string,
|
||||
pushNotification: components["schemas"]["PushNotificationOnchainAddressGotUnconfirmedTransaction"]
|
||||
): Promise<[object, object]> {
|
||||
): Promise<void> {
|
||||
const fcmPayload = {
|
||||
data: {},
|
||||
notification: {
|
||||
title: "New unconfirmed transaction",
|
||||
body: "You received new transfer on " + GroundControlToMajorTom.shortenAddress(pushNotification.address),
|
||||
badge: pushNotification.badge,
|
||||
tag: pushNotification.txid,
|
||||
},
|
||||
message: {
|
||||
token: '',
|
||||
data: {
|
||||
badge: String(pushNotification.badge),
|
||||
tag: pushNotification.txid,
|
||||
},
|
||||
notification: {
|
||||
title: "New unconfirmed transaction",
|
||||
body: "You received new transfer on " + GroundControlToMajorTom.shortenAddress(pushNotification.address),
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const apnsPayload = {
|
||||
@ -91,14 +105,17 @@ export class GroundControlToMajorTom {
|
||||
if (pushNotification.os === "ios") return GroundControlToMajorTom._pushToApns(dataSource, apnsP8, pushNotification.token, apnsPayload, pushNotification, pushNotification.txid);
|
||||
}
|
||||
|
||||
static async pushOnchainTxidGotConfirmed(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationTxidGotConfirmed"]): Promise<[object, object]> {
|
||||
static async pushOnchainTxidGotConfirmed(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationTxidGotConfirmed"]): Promise<void> {
|
||||
const fcmPayload = {
|
||||
data: {},
|
||||
notification: {
|
||||
title: "Transaction - Confirmed",
|
||||
body: "Your transaction " + GroundControlToMajorTom.shortenTxid(pushNotification.txid) + " has been confirmed",
|
||||
badge: pushNotification.badge,
|
||||
tag: pushNotification.txid,
|
||||
message: {
|
||||
data: {
|
||||
badge: String(pushNotification.badge),
|
||||
tag: pushNotification.txid,
|
||||
},
|
||||
notification: {
|
||||
title: "Transaction - Confirmed",
|
||||
body: "Your transaction " + GroundControlToMajorTom.shortenTxid(pushNotification.txid) + " has been confirmed",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -118,12 +135,14 @@ export class GroundControlToMajorTom {
|
||||
if (pushNotification.os === "ios") return GroundControlToMajorTom._pushToApns(dataSource, apnsP8, pushNotification.token, apnsPayload, pushNotification, pushNotification.txid);
|
||||
}
|
||||
|
||||
static async pushMessage(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationMessage"]): Promise<[object, object]> {
|
||||
static async pushMessage(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationMessage"]): Promise<void> {
|
||||
const fcmPayload = {
|
||||
data: {},
|
||||
notification: {
|
||||
title: "Message",
|
||||
body: pushNotification.text,
|
||||
message: {
|
||||
data: {},
|
||||
notification: {
|
||||
title: "Message",
|
||||
body: pushNotification.text,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -143,15 +162,19 @@ export class GroundControlToMajorTom {
|
||||
if (pushNotification.os === "ios") return GroundControlToMajorTom._pushToApns(dataSource, apnsP8, pushNotification.token, apnsPayload, pushNotification, pushNotification.txid);
|
||||
}
|
||||
|
||||
static async pushOnchainAddressWasPaid(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationOnchainAddressGotPaid"]): Promise<[object, object]> {
|
||||
static async pushOnchainAddressWasPaid(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationOnchainAddressGotPaid"]): Promise<void> {
|
||||
const fcmPayload = {
|
||||
data: {},
|
||||
notification: {
|
||||
title: "+" + pushNotification.sat + " sats",
|
||||
body: "Received on " + GroundControlToMajorTom.shortenAddress(pushNotification.address),
|
||||
badge: pushNotification.badge,
|
||||
tag: pushNotification.txid,
|
||||
},
|
||||
message: {
|
||||
token: '',
|
||||
data: {
|
||||
badge: String(pushNotification.badge),
|
||||
tag: pushNotification.txid,
|
||||
},
|
||||
notification: {
|
||||
title: "+" + pushNotification.sat + " sats",
|
||||
body: "Received on " + GroundControlToMajorTom.shortenAddress(pushNotification.address),
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const apnsPayload = {
|
||||
@ -170,14 +193,17 @@ export class GroundControlToMajorTom {
|
||||
if (pushNotification.os === "ios") return GroundControlToMajorTom._pushToApns(dataSource, apnsP8, pushNotification.token, apnsPayload, pushNotification, pushNotification.txid);
|
||||
}
|
||||
|
||||
static async pushLightningInvoicePaid(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationLightningInvoicePaid"]): Promise<[object, object]> {
|
||||
static async pushLightningInvoicePaid(dataSource: DataSource, serverKey: string, apnsP8: string, pushNotification: components["schemas"]["PushNotificationLightningInvoicePaid"]): Promise<void> {
|
||||
const fcmPayload = {
|
||||
data: {},
|
||||
notification: {
|
||||
body: "Paid: " + (pushNotification.memo || "your invoice"),
|
||||
title: "+" + pushNotification.sat + " sats",
|
||||
badge: pushNotification.badge,
|
||||
tag: pushNotification.hash,
|
||||
message: {
|
||||
data: {
|
||||
badge: String(pushNotification.badge),
|
||||
tag: pushNotification.hash,
|
||||
},
|
||||
notification: {
|
||||
body: "Paid: " + (pushNotification.memo || "your invoice"),
|
||||
title: "+" + pushNotification.sat + " sats",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -197,7 +223,7 @@ export class GroundControlToMajorTom {
|
||||
if (pushNotification.os === "ios") return GroundControlToMajorTom._pushToApns(dataSource, apnsP8, pushNotification.token, apnsPayload, pushNotification, pushNotification.hash);
|
||||
}
|
||||
|
||||
protected static async _pushToApns(dataSource: DataSource, apnsP8: string, token: string, apnsPayload: object, pushNotification: components["schemas"]["PushNotificationBase"], collapseId): Promise<[object, object]> {
|
||||
protected static async _pushToApns(dataSource: DataSource, apnsP8: string, token: string, apnsPayload: object, pushNotification: components["schemas"]["PushNotificationBase"], collapseId): Promise<void> {
|
||||
return new Promise(function (resolve) {
|
||||
// we pass some of the notification properties as data properties to FCM payload:
|
||||
for (let dataKey of Object.keys(pushNotification)) {
|
||||
@ -239,7 +265,7 @@ export class GroundControlToMajorTom {
|
||||
success: responseJson[":status"] === 200,
|
||||
});
|
||||
|
||||
resolve([apnsPayload, responseJson]);
|
||||
resolve();
|
||||
});
|
||||
|
||||
request.setEncoding("utf8");
|
||||
@ -267,48 +293,50 @@ export class GroundControlToMajorTom {
|
||||
success: responseJson[":status"] === 200,
|
||||
});
|
||||
|
||||
resolve([apnsPayload, responseJson]);
|
||||
resolve();
|
||||
});
|
||||
request.end();
|
||||
});
|
||||
}
|
||||
|
||||
protected static async _pushToFcm(dataSource: DataSource, serverKey: string, token: string, fcmPayload: object, pushNotification: components["schemas"]["PushNotificationBase"]): Promise<[object, object]> {
|
||||
fcmPayload["to"] = token;
|
||||
fcmPayload["priority"] = "high";
|
||||
protected static async _pushToFcm(dataSource: DataSource, bearer: string, token: string, fcmPayload: object, pushNotification: components["schemas"]["PushNotificationBase"]): Promise<void> {
|
||||
fcmPayload["message"]["token"] = token;
|
||||
|
||||
// now, we pass some of the notification properties as data properties to FCM payload:
|
||||
for (let dataKey of Object.keys(pushNotification)) {
|
||||
if (["token", "os", "badge"].includes(dataKey)) continue;
|
||||
fcmPayload["data"][dataKey] = pushNotification[dataKey];
|
||||
fcmPayload["message"]["data"][dataKey] = String(pushNotification[dataKey]);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const rawResponse = await fetch("https://fcm.googleapis.com/fcm/send", {
|
||||
const rawResponse = await fetch(`https://fcm.googleapis.com/v1/projects/${process.env.GOOGLE_PROJECT_ID}/messages:send`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: "key=" + serverKey,
|
||||
Authorization: `Bearer ${bearer}`,
|
||||
"Content-Type": "application/json",
|
||||
Host: "fcm.googleapis.com",
|
||||
},
|
||||
body: JSON.stringify(Object.assign({}, fcmPayload)),
|
||||
});
|
||||
const responseJson = await rawResponse.json();
|
||||
|
||||
delete fcmPayload["to"]; // compacting a bit, we dont need token in payload as well
|
||||
let responseText: string;
|
||||
try {
|
||||
responseText = await rawResponse.text();
|
||||
} catch (error) {
|
||||
console.error("error getting response from FCM", error);
|
||||
}
|
||||
|
||||
GroundControlToMajorTom.processFcmResponse(dataSource, responseJson, token);
|
||||
delete fcmPayload["message"]["token"]; // compacting a bit, we dont need token in payload as well
|
||||
|
||||
const success = GroundControlToMajorTom.processFcmResponse(dataSource, responseText, token);
|
||||
|
||||
const PushLogRepository = dataSource.getRepository(PushLog);
|
||||
await PushLogRepository.save({
|
||||
token: token,
|
||||
os: "android",
|
||||
payload: JSON.stringify(fcmPayload),
|
||||
response: JSON.stringify(responseJson),
|
||||
success: !!responseJson["success"],
|
||||
response: responseText,
|
||||
success,
|
||||
});
|
||||
|
||||
return [fcmPayload, responseJson];
|
||||
}
|
||||
|
||||
static async killDeadToken(dataSource: DataSource, token: string) {
|
||||
@ -318,21 +346,45 @@ export class GroundControlToMajorTom {
|
||||
await dataSource.getRepository(TokenToHash).createQueryBuilder().delete().where("token = :token", { token }).execute();
|
||||
}
|
||||
|
||||
static processFcmResponse(dataSource: DataSource, response, token: string) {
|
||||
if (response && response.results && Array.isArray(response.results) && response.results.length === 1) {
|
||||
if (response.results[0] && response.results[0].error && ["NotRegistered"].includes(response.results[0].error)) {
|
||||
return GroundControlToMajorTom.killDeadToken(dataSource, token);
|
||||
static processFcmResponse(dataSource: DataSource, responseText: string, token: string): boolean {
|
||||
try {
|
||||
const response = JSON.parse(responseText);
|
||||
|
||||
if (response?.error) {
|
||||
if (response.error.code === 404) {
|
||||
GroundControlToMajorTom.killDeadToken(dataSource, token);
|
||||
return false;
|
||||
}
|
||||
|
||||
// additonal check for the same thing, just for any case
|
||||
if (Array.isArray(response?.error?.details)) {
|
||||
for (const detail of response.error.details) {
|
||||
if (detail.errorCode === "UNREGISTERED") {
|
||||
GroundControlToMajorTom.killDeadToken(dataSource, token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (response && response.results && Array.isArray(response.results) && response.results.length !== 1) {
|
||||
console.error("Expected only single result in FCM response, cant handle batch responses yet (zero response also means smth is wrong):", response);
|
||||
|
||||
if (response?.name) {
|
||||
// thats a sign that payload is accepted and might be delivered
|
||||
return true;
|
||||
}
|
||||
} catch (_) {
|
||||
console.error("error parsing FCM response", responseText);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static processApnsResponse(dataSource: DataSource, response, token: string) {
|
||||
if (response && response.data) {
|
||||
try {
|
||||
console.log('parsing', response.data);
|
||||
const data = JSON.parse(response.data);
|
||||
if (data && data.reason && ["Unregistered", "BadDeviceToken"].includes(data.reason)) return GroundControlToMajorTom.killDeadToken(dataSource, token);
|
||||
if (data && data.reason && ["Unregistered", "BadDeviceToken", "DeviceTokenNotForTopic"].includes(data.reason)) return GroundControlToMajorTom.killDeadToken(dataSource, token);
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import dataSource from "../data-source";
|
||||
import { paths, components } from "../openapi/api";
|
||||
require("dotenv").config();
|
||||
const pck = require("../../package.json");
|
||||
if (!process.env.JAWSDB_MARIA_URL || !process.env.FCM_SERVER_KEY || !process.env.APNS_P8 || !process.env.APNS_TOPIC || !process.env.APPLE_TEAM_ID || !process.env.APNS_P8_KID) {
|
||||
if (!process.env.JAWSDB_MARIA_URL || !process.env.GOOGLE_KEY_FILE || !process.env.APNS_P8 || !process.env.APNS_TOPIC || !process.env.APPLE_TEAM_ID || !process.env.APNS_P8_KID || !process.env.GOOGLE_PROJECT_ID) {
|
||||
console.error("not all env variables set");
|
||||
process.exit();
|
||||
}
|
||||
@ -19,6 +19,9 @@ if (!process.env.JAWSDB_MARIA_URL || !process.env.FCM_SERVER_KEY || !process.env
|
||||
const LAST_PROCESSED_BLOCK = "LAST_PROCESSED_BLOCK";
|
||||
|
||||
const ADDRESS_IGNORE_LIST = [
|
||||
"1NXNHZr6Pbzi3VStcgaxwEhspTWNXQ3Q4G",
|
||||
"bc1qee7hk4a3k3km7j8hwclm0pkl76dhhgxay5nevu",
|
||||
"bc1qclyfsxuu8vcwq38yygs5zrskwacq8sjlyvk9mx",
|
||||
"bc1qltxjty7xfrnkzlrhmxpcekknr3uncne8sht7rn",
|
||||
"bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
|
||||
"bc1qw8wrek2m7nlqldll66ajnwr9mh64syvkt67zlu",
|
||||
|
||||
@ -7,7 +7,7 @@ import dataSource from "./data-source";
|
||||
require("dotenv").config();
|
||||
const helmet = require("helmet");
|
||||
const cors = require("cors");
|
||||
if (!process.env.JAWSDB_MARIA_URL || !process.env.FCM_SERVER_KEY || !process.env.APNS_P8 || !process.env.APNS_TOPIC) {
|
||||
if (!process.env.JAWSDB_MARIA_URL || !process.env.GOOGLE_KEY_FILE || !process.env.APNS_P8 || !process.env.APNS_TOPIC || !process.env.GOOGLE_PROJECT_ID) {
|
||||
console.error("not all env variables set");
|
||||
process.exit();
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { NOTIFICATION_LEVEL_NEWS, NOTIFICATION_LEVEL_PRICE, NOTIFICATION_LEVEL_T
|
||||
import dataSource from "./data-source";
|
||||
import { components } from "./openapi/api";
|
||||
require("dotenv").config();
|
||||
if (!process.env.FCM_SERVER_KEY || !process.env.APNS_P8 || !process.env.APNS_TOPIC || !process.env.APPLE_TEAM_ID || !process.env.APNS_P8_KID) {
|
||||
if (!process.env.GOOGLE_KEY_FILE || !process.env.APNS_P8 || !process.env.APNS_TOPIC || !process.env.APPLE_TEAM_ID || !process.env.APNS_P8_KID || !process.env.GOOGLE_PROJECT_ID) {
|
||||
console.error("not all env variables set");
|
||||
process.exit();
|
||||
}
|
||||
@ -107,31 +107,31 @@ dataSource
|
||||
case 2:
|
||||
payload = <components["schemas"]["PushNotificationOnchainAddressGotPaid"]>payload;
|
||||
process.env.VERBOSE && console.log("pushing to token", payload.token, payload.os);
|
||||
await GroundControlToMajorTom.pushOnchainAddressWasPaid(connection, GroundControlToMajorTom.getGoogleServerKey(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await GroundControlToMajorTom.pushOnchainAddressWasPaid(connection, await GroundControlToMajorTom.getGoogleCredentials(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await sendQueueRepository.remove(record);
|
||||
break;
|
||||
case 3:
|
||||
payload = <components["schemas"]["PushNotificationOnchainAddressGotUnconfirmedTransaction"]>payload;
|
||||
process.env.VERBOSE && console.log("pushing to token", payload.token, payload.os);
|
||||
await GroundControlToMajorTom.pushOnchainAddressGotUnconfirmedTransaction(connection, GroundControlToMajorTom.getGoogleServerKey(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await GroundControlToMajorTom.pushOnchainAddressGotUnconfirmedTransaction(connection, await GroundControlToMajorTom.getGoogleCredentials(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await sendQueueRepository.remove(record);
|
||||
break;
|
||||
case 1:
|
||||
payload = <components["schemas"]["PushNotificationLightningInvoicePaid"]>payload;
|
||||
process.env.VERBOSE && console.log("pushing to token", payload.token, payload.os);
|
||||
await GroundControlToMajorTom.pushLightningInvoicePaid(connection, GroundControlToMajorTom.getGoogleServerKey(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await GroundControlToMajorTom.pushLightningInvoicePaid(connection, await GroundControlToMajorTom.getGoogleCredentials(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await sendQueueRepository.remove(record);
|
||||
break;
|
||||
case 4:
|
||||
payload = <components["schemas"]["PushNotificationTxidGotConfirmed"]>payload;
|
||||
process.env.VERBOSE && console.log("pushing to token", payload.token, payload.os);
|
||||
await GroundControlToMajorTom.pushOnchainTxidGotConfirmed(connection, GroundControlToMajorTom.getGoogleServerKey(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await GroundControlToMajorTom.pushOnchainTxidGotConfirmed(connection, await GroundControlToMajorTom.getGoogleCredentials(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await sendQueueRepository.remove(record);
|
||||
break;
|
||||
case 5:
|
||||
payload = <components["schemas"]["PushNotificationMessage"]>payload;
|
||||
process.env.VERBOSE && console.log("pushing to token", payload.token, payload.os);
|
||||
await GroundControlToMajorTom.pushMessage(connection, GroundControlToMajorTom.getGoogleServerKey(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await GroundControlToMajorTom.pushMessage(connection, await GroundControlToMajorTom.getGoogleCredentials(), GroundControlToMajorTom.getApnsJwtToken(), payload);
|
||||
await sendQueueRepository.remove(record);
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"skipLibCheck": true,
|
||||
"lib": ["es5", "es6"],
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user