diff --git a/components/UrlRule.php b/components/UrlRule.php new file mode 100644 index 0000000..ef774ef --- /dev/null +++ b/components/UrlRule.php @@ -0,0 +1,40 @@ +getPathInfo(); + if (str_starts_with($path, WellKnownService::URL_PREFIX)) { + return WellKnownService::instance($path)->getRuleRoute() ?? false; + } + + return false; + } +} diff --git a/config.php b/config.php index faefe29..20353ef 100644 --- a/config.php +++ b/config.php @@ -27,7 +27,9 @@ //[NotificationInfoWidget::class, \humhub\widgets\BaseStack::EVENT_RUN, [Events::class, 'onNotificationInfoWidget']] ], 'consoleControllerMap' => [ - 'firebase' => 'humhub\modules\fcmPush\commands\SendController' + 'firebase' => 'humhub\modules\fcmPush\commands\SendController', + ], + 'urlManagerRules' => [ + ['class' => 'humhub\modules\fcmPush\components\UrlRule'], ], ]; -?> \ No newline at end of file diff --git a/controllers/WellKnownController.php b/controllers/WellKnownController.php new file mode 100644 index 0000000..281c91e --- /dev/null +++ b/controllers/WellKnownController.php @@ -0,0 +1,19 @@ +renderFile(); + } +} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6bcd58e..a2f5355 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,7 @@ Changelog 2.0.3 (Unreleased) ----------------------- - Enh: Endpoint to test push status +- Enh: Add possibility to profile `.well-known` files 2.0.2 (May 28, 2024) ----------------------- diff --git a/models/ConfigureForm.php b/models/ConfigureForm.php index 45ec387..b6b5c1d 100644 --- a/models/ConfigureForm.php +++ b/models/ConfigureForm.php @@ -3,6 +3,8 @@ namespace humhub\modules\fcmPush\models; use humhub\modules\fcmPush\Module; +use humhub\modules\fcmPush\services\WellKnownService; +use humhub\widgets\Link; use Yii; use yii\base\InvalidArgumentException; use yii\base\Model; @@ -24,6 +26,10 @@ class ConfigureForm extends Model public $disableAuthChoicesIos; + public $fileAssetLinks; + + public $fileAppleAssociation; + /** * Validate JSON field params * @@ -39,8 +45,7 @@ private function validateJsonParams($arrayPattern, $arrayCheck) if (isset($arrayCheck[$key])) { if (empty($arrayCheck[$key])) { $errors["empty"] .= $errors["empty"] == "" ? "\"$key\"" : ", \"$key\""; - } - else { + } else { $condition = false; switch ($value['type']) { case "string": @@ -85,6 +90,7 @@ public function rules() [['enableEmailGoService', 'disableAuthChoicesIos'], 'boolean'], [['senderId'], 'number'], [['serverKey', 'json', 'humhubApiKey'], 'safe'], + [['fileAssetLinks', 'fileAppleAssociation'], 'string'], ['json', function ($attribute, $params, $validator) { if (empty($this->$attribute)) { return; @@ -141,15 +147,33 @@ public function attributeLabels() 'json' => Yii::t('FcmPushModule.base', 'Service Account (JSON file)'), 'serverKey' => Yii::t('FcmPushModule.base', 'Cloud Messaging API (Legacy)'), 'disableAuthChoicesIos' => Yii::t('FcmPushModule.base', 'Disable AuthChoices on iOS App'), + 'fileAssetLinks' => Yii::t('FcmPushModule.base', 'Well-known file {fileName}', [ + 'fileName' => '"' . WellKnownService::getFileName('fileAssetLinks') . '"', + ]), + 'fileAppleAssociation' => Yii::t('FcmPushModule.base', 'Well-known file {fileName}', [ + 'fileName' => '"' . WellKnownService::getFileName('fileAppleAssociation') . '"', + ]), ]; } public function attributeHints() { return [ - 'humhubInstallId' => 'Use this ID to register your API Key.', - 'serverKey' => 'Please switch to the new "Firebase Cloud Messaging API (V1)" and enter a JSON file in the field above. The old legacy API is only temporarily available for existing installations and is no longer supported or maintained. ', - 'json' => 'Paste the content of the service account JSON files here. You can find more information in the module instructions.' + 'humhubInstallId' => Yii::t('FcmPushModule.base', 'Use this ID to register your API Key.'), + 'serverKey' => Yii::t('FcmPushModule.base', 'Please switch to the new "Firebase Cloud Messaging API (V1)" and enter a JSON file in the field above. The old legacy API is only temporarily available for existing installations and is no longer supported or maintained.'), + 'json' => Yii::t('FcmPushModule.base', 'Paste the content of the service account JSON files here. You can find more information in the module instructions.'), + 'fileAssetLinks' => Yii::t('FcmPushModule.base', 'URL to the file {fileNameLink}', [ + 'fileNameLink' => Link::to( + WellKnownService::getFileName('fileAssetLinks'), + WellKnownService::getFileRoute('fileAssetLinks'), + )->target('_blank'), + ]), + 'fileAppleAssociation' => Yii::t('FcmPushModule.base', 'URL to the file {fileNameLink}', [ + 'fileNameLink' => Link::to( + WellKnownService::getFileName('fileAppleAssociation'), + WellKnownService::getFileRoute('fileAppleAssociation'), + )->target('_blank'), + ]), ]; } @@ -170,7 +194,8 @@ public function loadSettings() $this->serverKey = $settings->get('serverKey'); $this->humhubApiKey = $settings->get('humhubApiKey'); $this->disableAuthChoicesIos = $settings->get('disableAuthChoicesIos'); - + $this->fileAssetLinks = $settings->get('fileAssetLinks'); + $this->fileAppleAssociation = $settings->get('fileAppleAssociation'); return true; } @@ -186,6 +211,8 @@ public function saveSettings() $module->settings->set('serverKey', $this->serverKey); $module->settings->set('humhubApiKey', $this->humhubApiKey); $module->settings->set('disableAuthChoicesIos', $this->disableAuthChoicesIos); + $module->settings->set('fileAssetLinks', $this->fileAssetLinks); + $module->settings->set('fileAppleAssociation', $this->fileAppleAssociation); return true; } @@ -197,7 +224,7 @@ public function getJsonAsArray() public static function getInstance() { - $config = new static; + $config = new static(); $config->loadSettings(); return $config; diff --git a/services/WellKnownService.php b/services/WellKnownService.php new file mode 100644 index 0000000..96c3d3e --- /dev/null +++ b/services/WellKnownService.php @@ -0,0 +1,83 @@ + 'assetlinks.json', + 'fileAppleAssociation' => 'apple-app-site-association', + ]; + + private ?string $file; + + public function __construct(string $path) + { + $this->file = preg_replace('#^' . preg_quote(self::URL_PREFIX) . '#', '', $path); + } + + public static function instance(string $path): self + { + return new self($path); + } + + public static function getFileName(string $settingName): string + { + return self::ALLOWED_FILES[$settingName] ?? ''; + } + + public static function getFileRoute(string $settingName): array + { + return [self::URL_ROUTE, 'file' => self::getFileName($settingName)]; + } + + public function isAllowed(): bool + { + return in_array($this->file, self::ALLOWED_FILES); + } + + public function getRuleRoute(): ?array + { + return $this->isAllowed() ? [self::URL_ROUTE, ['file' => $this->file]] : null; + } + + public function getFileContent(): string + { + $settingName = array_search($this->file, self::ALLOWED_FILES); + if ($settingName === false) { + return ''; + } + + /* @var Module $module */ + $module = Yii::$app->getModule('fcm-push'); + + return $module->settings->get($settingName, ''); + } + + public function renderFile(): Response + { + Yii::$app->response->format = Response::FORMAT_JSON; + + try { + Yii::$app->response->data = Json::decode($this->getFileContent()); + } catch (Exception $ex) { + Yii::$app->response->data = ''; + Yii::error('Wrong file format "' . $this->file . '". Error: ' . $ex->getMessage(), 'fcm-push'); + } + + return Yii::$app->response; + } +} diff --git a/views/admin/index.php b/views/admin/index.php index 388ba19..e809321 100644 --- a/views/admin/index.php +++ b/views/admin/index.php @@ -1,12 +1,12 @@