From 977d28353c44cc8e2e15e390da99ea38b94827fa Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 15 Aug 2021 20:52:46 +0000 Subject: [PATCH] Transmit push subscriptions --- composer.json | 5 +- composer.lock | 703 +++++++++++++++++++++++++++++++- src/Model/Subscription.php | 2 + src/Worker/PushSubscription.php | 59 +++ 4 files changed, 765 insertions(+), 4 deletions(-) create mode 100644 src/Worker/PushSubscription.php diff --git a/composer.json b/composer.json index 4e485e4e99..1e3fcfcffe 100644 --- a/composer.json +++ b/composer.json @@ -67,7 +67,8 @@ "npm-asset/moment": "^2.24", "npm-asset/perfect-scrollbar": "0.6.16", "npm-asset/textcomplete": "^0.18.2", - "npm-asset/typeahead.js": "^0.11.1" + "npm-asset/typeahead.js": "^0.11.1", + "minishlink/web-push": "^6.0" }, "repositories": [ { @@ -94,7 +95,7 @@ }, "config": { "platform": { - "php": "7.0" + "php": "7.2" }, "autoloader-suffix": "Friendica", "optimize-autoloader": true, diff --git a/composer.lock b/composer.lock index bf85afb791..fdfe37bbbf 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5cf680863afa011d3c2c9f4e0b817690", + "content-hash": "9560ab7f3a3b33c673672c11813ae52e", "packages": [ { "name": "asika/simple-console", @@ -253,6 +253,58 @@ }, "type": "bower-asset-library" }, + { + "name": "brick/math", + "version": "0.9.2", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.3.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" + } + ], + "time": "2021-01-20T22:51:39+00:00" + }, { "name": "composer/ca-bundle", "version": "1.2.9", @@ -513,6 +565,77 @@ ], "time": "2020-06-29T00:56:53+00:00" }, + { + "name": "fgrosse/phpasn1", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/fgrosse/PHPASN1.git", + "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/20299033c35f4300eb656e7e8e88cf52d1d6694e", + "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.3", + "satooshi/php-coveralls": "~2.0" + }, + "suggest": { + "ext-bcmath": "BCmath is the fallback extension for big integer calculations", + "ext-curl": "For loading OID information from the web if they have not bee defined statically", + "ext-gmp": "GMP is the preferred extension for big integer calculations", + "phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "FG\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Friedrich Große", + "email": "friedrich.grosse@gmail.com", + "homepage": "https://github.com/FGrosse", + "role": "Author" + }, + { + "name": "All contributors", + "homepage": "https://github.com/FGrosse/PHPASN1/contributors" + } + ], + "description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.", + "homepage": "https://github.com/FGrosse/PHPASN1", + "keywords": [ + "DER", + "asn.1", + "asn1", + "ber", + "binary", + "decoding", + "encoding", + "x.509", + "x.690", + "x509", + "x690" + ], + "time": "2021-04-24T19:01:55+00:00" + }, { "name": "friendica/json-ld", "version": "1.1.1", @@ -1059,6 +1182,65 @@ ], "time": "2019-12-02T02:32:27+00:00" }, + { + "name": "minishlink/web-push", + "version": "v6.0.5", + "source": { + "type": "git", + "url": "https://github.com/web-push-libs/web-push-php.git", + "reference": "d87e9e3034ca2b95b1822b1b335e7761c14b89f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-push-libs/web-push-php/zipball/d87e9e3034ca2b95b1822b1b335e7761c14b89f6", + "reference": "d87e9e3034ca2b95b1822b1b335e7761c14b89f6", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^7.0.1|^6.2", + "php": ">=7.2", + "web-token/jwt-key-mgmt": "^2.0", + "web-token/jwt-signature": "^2.0", + "web-token/jwt-signature-algorithm-ecdsa": "^2.0", + "web-token/jwt-util-ecc": "^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.14", + "phpstan/phpstan": "^0.11|^0.12", + "phpunit/phpunit": "^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Minishlink\\WebPush\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Louis Lagrange", + "email": "lagrange.louis@gmail.com", + "homepage": "https://github.com/Minishlink" + } + ], + "description": "Web Push library for PHP", + "homepage": "https://github.com/web-push-libs/web-push-php", + "keywords": [ + "Push API", + "WebPush", + "notifications", + "push", + "web" + ], + "time": "2021-04-08T15:22:50+00:00" + }, { "name": "mobiledetect/mobiledetectlib", "version": "2.8.37", @@ -3003,6 +3185,107 @@ ], "time": "2017-02-14T16:28:37+00:00" }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "time": "2019-04-30T12:38:16+00:00" + }, { "name": "psr/http-message", "version": "1.0.1", @@ -3248,6 +3531,67 @@ ], "time": "2021-02-17T21:57:51+00:00" }, + { + "name": "spomky-labs/base64url", + "version": "v2.0.4", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/base64url.git", + "reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/base64url/zipball/7752ce931ec285da4ed1f4c5aa27e45e097be61d", + "reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.11|^0.12", + "phpstan/phpstan-beberlei-assert": "^0.11|^0.12", + "phpstan/phpstan-deprecation-rules": "^0.11|^0.12", + "phpstan/phpstan-phpunit": "^0.11|^0.12", + "phpstan/phpstan-strict-rules": "^0.11|^0.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "Base64Url\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky-Labs/base64url/contributors" + } + ], + "description": "Base 64 URL Safe Encoding/Decoding PHP Library", + "homepage": "https://github.com/Spomky-Labs/base64url", + "keywords": [ + "base64", + "rfc4648", + "safe", + "url" + ], + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2020-11-03T09:10:25+00:00" + }, { "name": "symfony/polyfill-intl-idn", "version": "v1.19.0", @@ -3765,6 +4109,361 @@ "description": "A multi-language port of Browserscope's user agent parser.", "time": "2020-02-21T09:54:14+00:00" }, + { + "name": "web-token/jwt-core", + "version": "v2.2.10", + "source": { + "type": "git", + "url": "https://github.com/web-token/jwt-core.git", + "reference": "53beb6f6c1eec4fa93c1c3e5d9e5701e71fa1678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-token/jwt-core/zipball/53beb6f6c1eec4fa93c1c3e5d9e5701e71fa1678", + "reference": "53beb6f6c1eec4fa93c1c3e5d9e5701e71fa1678", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.17|^0.9", + "ext-json": "*", + "ext-mbstring": "*", + "fgrosse/phpasn1": "^2.0", + "php": ">=7.2", + "spomky-labs/base64url": "^1.0|^2.0" + }, + "conflict": { + "spomky-labs/jose": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jose\\Component\\Core\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-token/jwt-framework/contributors" + } + ], + "description": "Core component of the JWT Framework.", + "homepage": "https://github.com/web-token", + "keywords": [ + "JOSE", + "JWE", + "JWK", + "JWKSet", + "JWS", + "Jot", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "bundle", + "jwa", + "jwt", + "symfony" + ], + "funding": [ + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-03-17T14:55:52+00:00" + }, + { + "name": "web-token/jwt-key-mgmt", + "version": "v2.2.10", + "source": { + "type": "git", + "url": "https://github.com/web-token/jwt-key-mgmt.git", + "reference": "0b116379515700d237b4e5de86879078ccb09d8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-token/jwt-key-mgmt/zipball/0b116379515700d237b4e5de86879078ccb09d8a", + "reference": "0b116379515700d237b4e5de86879078ccb09d8a", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "web-token/jwt-core": "^2.0" + }, + "suggest": { + "ext-sodium": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys", + "php-http/httplug": "To enable JKU/X5U support.", + "php-http/message-factory": "To enable JKU/X5U support.", + "web-token/jwt-util-ecc": "To use EC key analyzers." + }, + "type": "library", + "autoload": { + "psr-4": { + "Jose\\Component\\KeyManagement\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-token/jwt-key-mgmt/contributors" + } + ], + "description": "Key Management component of the JWT Framework.", + "homepage": "https://github.com/web-token", + "keywords": [ + "JOSE", + "JWE", + "JWK", + "JWKSet", + "JWS", + "Jot", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "bundle", + "jwa", + "jwt", + "symfony" + ], + "funding": [ + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-03-17T14:55:52+00:00" + }, + { + "name": "web-token/jwt-signature", + "version": "v2.2.10", + "source": { + "type": "git", + "url": "https://github.com/web-token/jwt-signature.git", + "reference": "015b59aaf3b6e8fb9f5bd1338845b7464c7d8103" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-token/jwt-signature/zipball/015b59aaf3b6e8fb9f5bd1338845b7464c7d8103", + "reference": "015b59aaf3b6e8fb9f5bd1338845b7464c7d8103", + "shasum": "" + }, + "require": { + "web-token/jwt-core": "^2.1" + }, + "suggest": { + "web-token/jwt-signature-algorithm-ecdsa": "ECDSA Based Signature Algorithms", + "web-token/jwt-signature-algorithm-eddsa": "EdDSA Based Signature Algorithms", + "web-token/jwt-signature-algorithm-experimental": "Experimental Signature Algorithms", + "web-token/jwt-signature-algorithm-hmac": "HMAC Based Signature Algorithms", + "web-token/jwt-signature-algorithm-none": "None Signature Algorithm", + "web-token/jwt-signature-algorithm-rsa": "RSA Based Signature Algorithms" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jose\\Component\\Signature\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-token/jwt-signature/contributors" + } + ], + "description": "Signature component of the JWT Framework.", + "homepage": "https://github.com/web-token", + "keywords": [ + "JOSE", + "JWE", + "JWK", + "JWKSet", + "JWS", + "Jot", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "bundle", + "jwa", + "jwt", + "symfony" + ], + "funding": [ + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-03-01T19:55:28+00:00" + }, + { + "name": "web-token/jwt-signature-algorithm-ecdsa", + "version": "v2.2.10", + "source": { + "type": "git", + "url": "https://github.com/web-token/jwt-signature-algorithm-ecdsa.git", + "reference": "44cbbb4374c51f1cf48b82ae761efbf24e1a8591" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-token/jwt-signature-algorithm-ecdsa/zipball/44cbbb4374c51f1cf48b82ae761efbf24e1a8591", + "reference": "44cbbb4374c51f1cf48b82ae761efbf24e1a8591", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "web-token/jwt-signature": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jose\\Component\\Signature\\Algorithm\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-token/jwt-framework/contributors" + } + ], + "description": "ECDSA Based Signature Algorithms the JWT Framework.", + "homepage": "https://github.com/web-token", + "keywords": [ + "JOSE", + "JWE", + "JWK", + "JWKSet", + "JWS", + "Jot", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "bundle", + "jwa", + "jwt", + "symfony" + ], + "funding": [ + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-01-21T19:18:03+00:00" + }, + { + "name": "web-token/jwt-util-ecc", + "version": "v2.2.10", + "source": { + "type": "git", + "url": "https://github.com/web-token/jwt-util-ecc.git", + "reference": "915f3fde86f5236c205620d61177b9ef43863deb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-token/jwt-util-ecc/zipball/915f3fde86f5236c205620d61177b9ef43863deb", + "reference": "915f3fde86f5236c205620d61177b9ef43863deb", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.17|^0.9" + }, + "suggest": { + "ext-bcmath": "GMP or BCMath is highly recommended to improve the library performance", + "ext-gmp": "GMP or BCMath is highly recommended to improve the library performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jose\\Component\\Core\\Util\\Ecc\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-token/jwt-framework/contributors" + } + ], + "description": "ECC Tools for the JWT Framework.", + "homepage": "https://github.com/web-token", + "keywords": [ + "JOSE", + "JWE", + "JWK", + "JWKSet", + "JWS", + "Jot", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "bundle", + "jwa", + "jwt", + "symfony" + ], + "funding": [ + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-03-24T13:35:17+00:00" + }, { "name": "xemlock/htmlpurifier-html5", "version": "v0.1.11", @@ -4001,7 +4700,7 @@ }, "platform-dev": [], "platform-overrides": { - "php": "7.0" + "php": "7.2" }, "plugin-api-version": "1.1.0" } diff --git a/src/Model/Subscription.php b/src/Model/Subscription.php index aaaa7db7af..dd81ee2d63 100644 --- a/src/Model/Subscription.php +++ b/src/Model/Subscription.php @@ -27,6 +27,7 @@ namespace Friendica\Model; use Friendica\Core\Logger; +use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Util\Crypto; @@ -131,6 +132,7 @@ class Subscription $subscriptions = DBA::select('subscription', [], ['uid' => $notification['uid'], $type => true]); while ($subscription = DBA::fetch($subscriptions)) { Logger::info('Push notification', ['id' => $subscription['id'], 'uid' => $subscription['uid'], 'type' => $type]); + Worker::add(PRIORITY_HIGH, 'PushSubscription', $subscription['id']); } DBA::close($subscriptions); } diff --git a/src/Worker/PushSubscription.php b/src/Worker/PushSubscription.php new file mode 100644 index 0000000000..7095c67943 --- /dev/null +++ b/src/Worker/PushSubscription.php @@ -0,0 +1,59 @@ +. + * + */ + +namespace Friendica\Worker; + +use Friendica\Core\Logger; +use Friendica\Database\DBA; +use Minishlink\WebPush\WebPush; +use Minishlink\WebPush\Subscription; + +Class PushSubscription +{ + public static function execute(int $sid) + { + $subscription = DBA::selectFirst('subscription', [], ['id' => $sid]); + + $notification = [ + 'subscription' => Subscription::create([ + 'endpoint' => $subscription['endpoint'], + 'publicKey' => $subscription['pubkey'], + 'authToken' => $subscription['secret'], + ]), + 'payload' => null, + ]; + + $webPush = new WebPush(); + + $report = $webPush->sendOneNotification( + $notification['subscription'], + $notification['payload'] + ); + + $endpoint = $report->getRequest()->getUri()->__toString(); + + if ($report->isSuccess()) { + Logger::info('Message sent successfully for subscription', ['endpoint' => $endpoint]); + } else { + Logger::info('Message failed to sent for subscription', ['endpoint' => $endpoint, 'reason' => $report->getReason()]); + } + } +}