mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-23 04:46:44 +00:00
Expand settings for notifications.
This commit is contained in:
19
.env.example
19
.env.example
@@ -178,25 +178,6 @@ MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
MAILERSEND_API_KEY=
|
||||
|
||||
#
|
||||
# Ntfy notification settings.
|
||||
# defaults to "https://ntfy.sh", but needs a topic or it won't work.
|
||||
# authentication is recommended but not required.
|
||||
#
|
||||
NTFY_SERVER=
|
||||
NTFY_TOPIC=
|
||||
NTFY_AUTH_ENABLED=false
|
||||
NTFY_AUTH_USERNAME=
|
||||
NTFY_AUTH_PASSWORD=
|
||||
|
||||
#
|
||||
# Pushover notification Application/API Token and User token.
|
||||
# Used if you want to receive notifications over pushover.
|
||||
# Both must be configured for this channel to work.
|
||||
#
|
||||
PUSHOVER_APP_TOKEN=
|
||||
PUSHOVER_USER_TOKEN=
|
||||
|
||||
# Firefly III can send you the following messages.
|
||||
SEND_ERROR_MESSAGE=true
|
||||
|
||||
|
@@ -23,23 +23,23 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events\Test;
|
||||
|
||||
use FireflyIII\User;
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class TestNotificationChannel
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public User $user;
|
||||
public OwnerNotifiable $owner;
|
||||
public string $channel;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(string $channel, User $user)
|
||||
public function __construct(string $channel, OwnerNotifiable $owner)
|
||||
{
|
||||
app('log')->debug(sprintf('Triggered TestNotificationChannel("%s") for user #%d (%s)', $channel, $user->id, $user->email));
|
||||
$this->user = $user;
|
||||
app('log')->debug(sprintf('Triggered TestNotificationChannel("%s")', $channel));
|
||||
$this->owner = $owner;
|
||||
$this->channel = $channel;
|
||||
}
|
||||
}
|
||||
|
@@ -117,14 +117,8 @@ class AdminEventHandler
|
||||
*/
|
||||
public function sendTestNotification(TestNotificationChannel $event): void
|
||||
{
|
||||
Log::debug(sprintf('Now in sendTestNotification(#%d, "%s")', $event->user->id, $event->channel));
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
Log::debug(sprintf('Now in sendTestNotification("%s")', $event->channel));
|
||||
|
||||
if (!$repository->hasRole($event->user, 'owner')) {
|
||||
Log::error(sprintf('User #%d is not an owner.', $event->user->id));
|
||||
return;
|
||||
}
|
||||
switch($event->channel) {
|
||||
case 'email':
|
||||
$class = TestNotificationEmail::class;
|
||||
@@ -145,7 +139,7 @@ class AdminEventHandler
|
||||
Log::debug(sprintf('Will send %s as a notification.', $class));
|
||||
|
||||
try {
|
||||
Notification::send($event->user, new $class($event->user->email));
|
||||
Notification::send($event->owner, new $class($event->owner));
|
||||
} catch (\Exception $e) { // @phpstan-ignore-line
|
||||
$message = $e->getMessage();
|
||||
if (str_contains($message, 'Bcc')) {
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Http\Controllers\Admin;
|
||||
use FireflyIII\Events\Test\TestNotificationChannel;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\NotificationRequest;
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -40,12 +41,21 @@ class NotificationController extends Controller
|
||||
$mainTitleIcon = 'fa-hand-spock-o';
|
||||
$subTitle = (string) trans('firefly.title_owner_notifications');
|
||||
$subTitleIcon = 'envelope-o';
|
||||
$slackUrl = app('fireflyconfig')->get('slack_webhook_url', '')->data;
|
||||
|
||||
// notification settings:
|
||||
$slackUrl = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||
$pushoverAppToken = app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
||||
$pushoverUserToken = app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
||||
|
||||
$ntfyServer = app('fireflyconfig')->getEncrypted('ntfy_server', 'https://ntfy.sh')->data;
|
||||
$ntfyTopic = app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data;
|
||||
$ntfyAuth = app('fireflyconfig')->get('ntfy_auth', false)->data;
|
||||
$ntfyUser = app('fireflyconfig')->getEncrypted('ntfy_user', '')->data;
|
||||
$ntfyPass = app('fireflyconfig')->getEncrypted('ntfy_pass', '')->data;
|
||||
|
||||
$channels = config('notifications.channels');
|
||||
$forcedAvailability = [];
|
||||
|
||||
|
||||
|
||||
// admin notification settings:
|
||||
$notifications = [];
|
||||
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||
@@ -60,18 +70,24 @@ class NotificationController extends Controller
|
||||
}
|
||||
|
||||
// validate presence of of Ntfy settings.
|
||||
if('' === (string)config('ntfy-notification-channel.topic')) {
|
||||
if ('' === $ntfyTopic) {
|
||||
Log::warning('No topic name for Ntfy, channel is disabled.');
|
||||
$forcedAvailability['ntfy'] = false;
|
||||
}
|
||||
|
||||
// validate pushover
|
||||
if('' === (string)config('services.pushover.token') || '' === (string)config('services.pushover.user_token')) {
|
||||
if ('' === $pushoverAppToken || '' === $pushoverUserToken) {
|
||||
Log::warning('No Pushover token, channel is disabled.');
|
||||
$forcedAvailability['pushover'] = false;
|
||||
}
|
||||
|
||||
return view('admin.notifications.index', compact('title', 'subTitle', 'forcedAvailability', 'mainTitleIcon', 'subTitleIcon', 'channels', 'slackUrl', 'notifications'));
|
||||
return view('admin.notifications.index',
|
||||
compact(
|
||||
'title', 'subTitle', 'forcedAvailability', 'mainTitleIcon', 'subTitleIcon', 'channels',
|
||||
'slackUrl', 'notifications',
|
||||
'pushoverAppToken', 'pushoverUserToken',
|
||||
'ntfyServer', 'ntfyTopic', 'ntfyAuth', 'ntfyUser', 'ntfyPass'
|
||||
));
|
||||
}
|
||||
|
||||
public function postIndex(NotificationRequest $request): RedirectResponse
|
||||
@@ -83,12 +99,17 @@ class NotificationController extends Controller
|
||||
app('fireflyconfig')->set(sprintf('notification_%s', $key), $all[$key]);
|
||||
}
|
||||
}
|
||||
if ('' === $all['slack_url']) {
|
||||
app('fireflyconfig')->delete('slack_webhook_url');
|
||||
$variables = ['slack_webhook_url', 'pushover_app_token', 'pushover_user_token', 'ntfy_server', 'ntfy_topic', 'ntfy_user', 'ntfy_pass'];
|
||||
foreach ($variables as $variable) {
|
||||
if ('' === $all[$variable]) {
|
||||
app('fireflyconfig')->delete($variable);
|
||||
}
|
||||
if ('' !== $all['slack_url']) {
|
||||
app('fireflyconfig')->set('slack_webhook_url', $all['slack_url']);
|
||||
if ('' !== $all[$variable]) {
|
||||
app('fireflyconfig')->setEncrypted($variable, $all[$variable]);
|
||||
}
|
||||
}
|
||||
app('fireflyconfig')->set('ntfy_auth', $all['ntfy_auth'] ?? false);
|
||||
|
||||
|
||||
session()->flash('success', (string) trans('firefly.notification_settings_saved'));
|
||||
|
||||
@@ -109,10 +130,9 @@ class NotificationController extends Controller
|
||||
case 'slack':
|
||||
case 'pushover':
|
||||
case 'ntfy':
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$owner = new OwnerNotifiable();
|
||||
app('log')->debug(sprintf('Now in testNotification("%s") controller.', $channel));
|
||||
event(new TestNotificationChannel($channel, $user));
|
||||
event(new TestNotificationChannel($channel, $owner));
|
||||
session()->flash('success', (string) trans('firefly.notification_test_executed', ['channel' => $channel]));
|
||||
}
|
||||
|
||||
|
@@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use FireflyIII\Rules\Admin\IsValidDiscordUrl;
|
||||
use FireflyIII\Rules\Admin\IsValidSlackUrl;
|
||||
use FireflyIII\Rules\Admin\IsValidSlackOrDiscordUrl;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
@@ -44,7 +43,16 @@ class NotificationRequest extends FormRequest
|
||||
}
|
||||
$return[$key] = $value;
|
||||
}
|
||||
$return['slack_url'] = $this->convertString('slack_url');
|
||||
$return['slack_webhook_url'] = $this->convertString('slack_webhook_url');
|
||||
|
||||
$return['pushover_app_token'] = $this->convertString('pushover_app_token');
|
||||
$return['pushover_user_token'] = $this->convertString('pushover_user_token');
|
||||
|
||||
$return['ntfy_server'] = $this->convertString('ntfy_server');
|
||||
$return['ntfy_topic'] = $this->convertString('ntfy_topic');
|
||||
$return['ntfy_auth'] = $this->convertBoolean($this->get('ntfy_auth'));
|
||||
$return['ntfy_user'] = $this->convertString('ntfy_user');
|
||||
$return['ntfy_pass'] = $this->convertString('ntfy_pass');
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -54,7 +62,10 @@ class NotificationRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'slack_url' => ['nullable', 'url', 'min:1', new IsValidSlackUrl()],
|
||||
'slack_webhook_url' => ['nullable', 'url', 'min:1', new IsValidSlackOrDiscordUrl()],
|
||||
'ntfy_server' => ['nullable', 'url', 'min:1'],
|
||||
'ntfy_user' => ['required_with:ntfy_pass,ntfy_auth', 'nullable', 'string', 'min:1'],
|
||||
'ntfy_pass' => ['required_with:ntfy_user,ntfy_auth', 'nullable', 'string', 'min:1'],
|
||||
];
|
||||
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||
$rules[sprintf('notification_%s', $key)] = 'in:0,1';
|
||||
|
@@ -107,6 +107,9 @@ class UserInvitation extends Notification
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
|
||||
|
||||
|
||||
$slackUrl = app('fireflyconfig')->get('slack_webhook_url', '')->data;
|
||||
if (UrlValidator::isValidWebhookURL($slackUrl)) {
|
||||
return ['mail', 'slack'];
|
||||
|
70
app/Notifications/Notifiables/OwnerNotifiable.php
Normal file
70
app/Notifications/Notifiables/OwnerNotifiable.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/*
|
||||
* AdminNotifiable.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications\Notifiables;
|
||||
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Str;
|
||||
use NotificationChannels\Pushover\PushoverReceiver;
|
||||
|
||||
class OwnerNotifiable
|
||||
{
|
||||
|
||||
public function routeNotificationForSlack(): string
|
||||
{
|
||||
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||
if (is_array($res)) {
|
||||
$res = '';
|
||||
}
|
||||
return (string) $res;
|
||||
}
|
||||
|
||||
public function routeNotificationForPushover()
|
||||
{
|
||||
$pushoverAppToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
||||
$pushoverUserToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
||||
return PushoverReceiver::withUserKey($pushoverUserToken)
|
||||
->withApplicationToken($pushoverAppToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification routing information for the given driver.
|
||||
*
|
||||
* @param string $driver
|
||||
* @param null|Notification $notification
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function routeNotificationFor($driver, $notification = null)
|
||||
{
|
||||
$method = 'routeNotificationFor' . Str::studly($driver);
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->{$method}($notification); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
return match ($driver) {
|
||||
'mail' => (string) config('firefly.site_owner'),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
}
|
46
app/Notifications/ReturnsAvailableChannels.php
Normal file
46
app/Notifications/ReturnsAvailableChannels.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/*
|
||||
* ReturnsAvailableChannels.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications;
|
||||
|
||||
use FireflyIII\Support\Notifications\UrlValidator;
|
||||
|
||||
class ReturnsAvailableChannels
|
||||
{
|
||||
public static function returnChannels(string $type): array {
|
||||
$channels = ['mail'];
|
||||
|
||||
if('owner' === $type) {
|
||||
$slackUrl = app('fireflyconfig')->get('slack_webhook_url', '')->data;
|
||||
if (UrlValidator::isValidWebhookURL($slackUrl)) {
|
||||
$channels[] = 'slack';
|
||||
}
|
||||
// only the owner can get notifications over
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $channels;
|
||||
}
|
||||
|
||||
}
|
60
app/Notifications/ReturnsSettings.php
Normal file
60
app/Notifications/ReturnsSettings.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/*
|
||||
* ReturnsSettings.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use FireflyIII\User;
|
||||
|
||||
class ReturnsSettings
|
||||
{
|
||||
public static function getSettings(string $channel, string $type, ?User $user): array
|
||||
{
|
||||
if ('ntfy' === $channel) {
|
||||
return self::getNtfySettings($type, $user);
|
||||
}
|
||||
throw new FireflyException(sprintf('Cannot handle channel "%s"', $channel));
|
||||
}
|
||||
|
||||
private static function getNtfySettings(string $type, ?User $user)
|
||||
{
|
||||
$settings = [
|
||||
'ntfy_server' => 'https://ntfy.sh',
|
||||
'ntfy_topic' => '',
|
||||
'ntfy_auth' => false,
|
||||
'ntfy_user' => '',
|
||||
'ntfy_pass' => '',
|
||||
|
||||
];
|
||||
if ('owner' === $type) {
|
||||
$settings['ntfy_server'] = FireflyConfig::getEncrypted('ntfy_server', 'https://ntfy.sh')->data;
|
||||
$settings['ntfy_topic'] = FireflyConfig::getEncrypted('ntfy_topic', '')->data;
|
||||
$settings['ntfy_auth'] = FireflyConfig::get('ntfy_auth', false)->data;
|
||||
$settings['ntfy_user'] = FireflyConfig::getEncrypted('ntfy_user', '')->data;
|
||||
$settings['ntfy_pass'] = FireflyConfig::getEncrypted('ntfy_pass', '')->data;
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
}
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications\Test;
|
||||
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
@@ -35,26 +36,26 @@ class TestNotificationEmail extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
private string $address;
|
||||
private OwnerNotifiable $owner;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*/
|
||||
public function __construct(string $address)
|
||||
public function __construct(OwnerNotifiable $owner)
|
||||
{
|
||||
$this->address = $address;
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @param OwnerNotifiable $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
public function toArray(OwnerNotifiable $notifiable)
|
||||
{
|
||||
return [
|
||||
];
|
||||
@@ -69,23 +70,14 @@ class TestNotificationEmail extends Notification
|
||||
*
|
||||
* @return MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
public function toMail(OwnerNotifiable $notifiable)
|
||||
{
|
||||
$address = (string) config('firefly.site_owner');
|
||||
return (new MailMessage())
|
||||
->markdown('emails.admin-test', ['email' => $this->address])
|
||||
->markdown('emails.admin-test', ['email' => $address])
|
||||
->subject((string) trans('email.admin_test_subject'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Slack representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
*/
|
||||
public function toSlack($notifiable) {}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
@@ -95,7 +87,7 @@ class TestNotificationEmail extends Notification
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
public function via(OwnerNotifiable $notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
@@ -24,9 +24,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications\Test;
|
||||
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Ntfy\Message;
|
||||
use Wijourdil\NtfyNotificationChannel\Channels\NtfyChannel;
|
||||
@@ -40,14 +41,14 @@ class TestNotificationNtfy extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
private string $address;
|
||||
public OwnerNotifiable $owner;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*/
|
||||
public function __construct(string $address)
|
||||
public function __construct(OwnerNotifiable $owner)
|
||||
{
|
||||
$this->address = $address;
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,51 +67,34 @@ class TestNotificationNtfy extends Notification
|
||||
}
|
||||
|
||||
|
||||
public function toNtfy(mixed $notifiable): Message
|
||||
public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
{
|
||||
$settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
|
||||
// overrule config.
|
||||
config(['ntfy-notification-channel.server' => $settings['ntfy_server']]);
|
||||
config(['ntfy-notification-channel.topic' => $settings['ntfy_topic']]);
|
||||
|
||||
if ($settings['ntfy_auth']) {
|
||||
// overrule auth as well.
|
||||
config(['ntfy-notification-channel.authentication.enabled' => true]);
|
||||
config(['ntfy-notification-channel.authentication.username' => $settings['ntfy_user']]);
|
||||
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
||||
}
|
||||
|
||||
$message = new Message();
|
||||
$message->topic(config('ntfy-notification-channel.topic'));
|
||||
$message->title((string)trans('email.admin_test_subject'));
|
||||
$message->body((string)trans('email.admin_test_message', ['channel' => 'ntfy']));
|
||||
$message->tags(['white_check_mark', 'ok_hand']);
|
||||
$message->topic($settings['ntfy_topic']);
|
||||
$message->title((string) trans('email.admin_test_subject'));
|
||||
$message->body((string) trans('email.admin_test_message', ['channel' => 'ntfy']));
|
||||
$message->tags(['white_check_mark']);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Slack representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
*/
|
||||
public function toSlack($notifiable) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
public function via(OwnerNotifiable $notifiable)
|
||||
{
|
||||
return [NtfyChannel::class];
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications\Test;
|
||||
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
@@ -42,73 +44,45 @@ class TestNotificationPushover extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
private string $address;
|
||||
private OwnerNotifiable $owner;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*/
|
||||
public function __construct(string $address)
|
||||
public function __construct(OwnerNotifiable $owner)
|
||||
{
|
||||
$this->address = $address;
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @param OwnerNotifiable $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
public function toArray(OwnerNotifiable $notifiable)
|
||||
{
|
||||
return [
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function toPushover(mixed $notifiable): PushoverMessage
|
||||
public function toPushover(OwnerNotifiable $notifiable): PushoverMessage
|
||||
{
|
||||
Log::debug('Now in toPushover()');
|
||||
|
||||
return PushoverMessage::create((string)trans('email.admin_test_message', ['channel' => 'Pushover']))
|
||||
->title((string)trans('email.admin_test_subject'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Slack representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
*/
|
||||
public function toSlack($notifiable) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
public function via(OwnerNotifiable $notifiable)
|
||||
{
|
||||
return [PushoverChannel::class];
|
||||
}
|
||||
|
@@ -24,11 +24,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications\Test;
|
||||
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
//use Illuminate\Notifications\Slack\SlackMessage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
|
||||
/**
|
||||
* Class TestNotification
|
||||
@@ -37,76 +40,61 @@ class TestNotificationSlack extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
private string $address;
|
||||
private OwnerNotifiable $owner;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*/
|
||||
public function __construct(string $address)
|
||||
public function __construct(OwnerNotifiable $owner)
|
||||
{
|
||||
$this->address = $address;
|
||||
$this->owner =$owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @param OwnerNotifiable $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
public function toArray(OwnerNotifiable $notifiable)
|
||||
{
|
||||
return [
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Slack representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @param OwnerNotifiable $notifiable
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
*/
|
||||
public function toSlack($notifiable) {
|
||||
|
||||
public function toSlack(OwnerNotifiable $notifiable)
|
||||
{
|
||||
// since it's an admin notification, grab the URL from fireflyconfig
|
||||
$url = app('fireflyconfig')->get('slack_webhook_url', '')->data;
|
||||
|
||||
// return (new SlackMessage)
|
||||
// ->text((string)trans('email.admin_test_subject'))
|
||||
// ->to($url);
|
||||
return (new SlackMessage())
|
||||
->content((string)trans('email.admin_test_subject'))
|
||||
->to($url);
|
||||
$url = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||
if ('' !== $url) {
|
||||
return new SlackMessage()->content((string)trans('email.admin_test_subject'))->to($url);
|
||||
//return new SlackMessage()->text((string) trans('email.admin_test_subject'))->to($url);
|
||||
|
||||
}
|
||||
Log::error('Empty slack URL, cannot send notification.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @param OwnerNotifiable $notifiable
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
public function via(OwnerNotifiable $notifiable)
|
||||
{
|
||||
return ['slack'];
|
||||
}
|
||||
|
32
app/Rules/Admin/IsValidSlackOrDiscordUrl.php
Normal file
32
app/Rules/Admin/IsValidSlackOrDiscordUrl.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Rules\Admin;
|
||||
|
||||
use FireflyIII\Support\Validation\ValidatesAmountsTrait;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class IsValidSlackOrDiscordUrl implements ValidationRule
|
||||
{
|
||||
use ValidatesAmountsTrait;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||
{
|
||||
$value = (string)$value;
|
||||
if('' === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!str_starts_with($value, 'https://hooks.slack.com/services/') && !str_starts_with($value, 'https://discord.com/api/webhooks/')) {
|
||||
$fail('validation.active_url')->translate();
|
||||
$message = sprintf('IsValidSlackUrl: "%s" is not a discord or slack URL.', substr($value, 0, 255));
|
||||
Log::debug($message);
|
||||
Log::channel('audit')->info($message);
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,7 +24,7 @@ class IsValidSlackUrl implements ValidationRule
|
||||
|
||||
if(!str_starts_with($value, 'https://hooks.slack.com/services/')) {
|
||||
$fail('validation.active_url')->translate();
|
||||
$message = sprintf('IsValidSlackUrl: "%s" is not a discord URL.', substr($value, 0, 255));
|
||||
$message = sprintf('IsValidSlackUrl: "%s" is not a slack URL.', substr($value, 0, 255));
|
||||
Log::debug($message);
|
||||
Log::channel('audit')->info($message);
|
||||
}
|
||||
|
@@ -289,6 +289,26 @@ class ExpandedForm
|
||||
|
||||
return $html;
|
||||
}
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function passwordWithValue(string $name, string $value, ?array $options = null): string
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
|
||||
try {
|
||||
$html = view('form.password', compact('classes', 'value','name', 'label', 'options'))->render();
|
||||
} catch (\Throwable $e) {
|
||||
app('log')->debug(sprintf('Could not render passwordWithValue(): %s', $e->getMessage()));
|
||||
$html = 'Could not render passwordWithValue.';
|
||||
|
||||
throw new FireflyException($html, 0, $e);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to render a percentage.
|
||||
|
@@ -25,7 +25,10 @@ namespace FireflyIII\Support;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Configuration;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Contracts\Encryption\EncryptException;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class FireflyConfig.
|
||||
@@ -34,7 +37,7 @@ class FireflyConfig
|
||||
{
|
||||
public function delete(string $name): void
|
||||
{
|
||||
$fullName = 'ff-config-'.$name;
|
||||
$fullName = 'ff-config-' . $name;
|
||||
if (\Cache::has($fullName)) {
|
||||
\Cache::forget($fullName);
|
||||
}
|
||||
@@ -46,6 +49,25 @@ class FireflyConfig
|
||||
return 1 === Configuration::where('name', $name)->count();
|
||||
}
|
||||
|
||||
public function getEncrypted(string $name, $default = null): ?Configuration
|
||||
{
|
||||
$result = $this->get($name, $default);
|
||||
if (null === $result) {
|
||||
return null;
|
||||
}
|
||||
if ('' === $result->data) {
|
||||
Log::warning(sprintf('Empty encrypted preference found: "%s"', $name));
|
||||
return $result;
|
||||
}
|
||||
try {
|
||||
$result->data = decrypt($result->data);
|
||||
} catch (DecryptException $e) {
|
||||
Log::error(sprintf('Could not decrypt preference "%s": %s', $name, $e->getMessage()));
|
||||
return $result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|bool|int|string $default
|
||||
*
|
||||
@@ -53,7 +75,7 @@ class FireflyConfig
|
||||
*/
|
||||
public function get(string $name, $default = null): ?Configuration
|
||||
{
|
||||
$fullName = 'ff-config-'.$name;
|
||||
$fullName = 'ff-config-' . $name;
|
||||
if (\Cache::has($fullName)) {
|
||||
return \Cache::get($fullName);
|
||||
}
|
||||
@@ -61,7 +83,7 @@ class FireflyConfig
|
||||
try {
|
||||
/** @var null|Configuration $config */
|
||||
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
|
||||
} catch (\Exception|QueryException $e) {
|
||||
} catch (\Exception | QueryException $e) {
|
||||
throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e);
|
||||
}
|
||||
|
||||
@@ -78,10 +100,18 @@ class FireflyConfig
|
||||
return $this->set($name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set(string $name, $value): Configuration
|
||||
public function setEncrypted(string $name, mixed $value): Configuration
|
||||
{
|
||||
try {
|
||||
$encrypted = encrypt($value);
|
||||
} catch (EncryptException $e) {
|
||||
Log::error(sprintf('Could not encrypt preference "%s": %s', $name, $e->getMessage()));
|
||||
throw new FireflyException(sprintf('Could not encrypt preference "%s". Cowardly refuse to continue.', $name));
|
||||
}
|
||||
return $this->set($name, $encrypted);
|
||||
}
|
||||
|
||||
public function set(string $name, mixed $value): Configuration
|
||||
{
|
||||
try {
|
||||
$config = Configuration::whereName($name)->whereNull('deleted_at')->first();
|
||||
@@ -99,13 +129,13 @@ class FireflyConfig
|
||||
$item->name = $name;
|
||||
$item->data = $value;
|
||||
$item->save();
|
||||
\Cache::forget('ff-config-'.$name);
|
||||
\Cache::forget('ff-config-' . $name);
|
||||
|
||||
return $item;
|
||||
}
|
||||
$config->data = $value;
|
||||
$config->save();
|
||||
\Cache::forget('ff-config-'.$name);
|
||||
\Cache::forget('ff-config-' . $name);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
55
app/User.php
55
app/User.php
@@ -36,7 +36,6 @@ use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use FireflyIII\Models\GroupMembership;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\Role;
|
||||
@@ -54,7 +53,6 @@ use FireflyIII\Notifications\Admin\UserInvitation;
|
||||
use FireflyIII\Notifications\Admin\UserRegistration;
|
||||
use FireflyIII\Notifications\Admin\VersionCheckResult;
|
||||
use FireflyIII\Notifications\Test\TestNotificationDiscord;
|
||||
use FireflyIII\Notifications\Test\TestNotificationSlack;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@@ -65,7 +63,6 @@ use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Passport\HasApiTokens;
|
||||
use Laravel\Passport\Token;
|
||||
use NotificationChannels\Pushover\PushoverReceiver;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
@@ -93,7 +90,7 @@ class User extends Authenticatable
|
||||
public static function routeBinder(string $value): self
|
||||
{
|
||||
if (auth()->check()) {
|
||||
$userId = (int)$value;
|
||||
$userId = (int) $value;
|
||||
$user = self::find($userId);
|
||||
if (null !== $user) {
|
||||
return $user;
|
||||
@@ -102,12 +99,6 @@ class User extends Authenticatable
|
||||
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
public function routeNotificationForPushover()
|
||||
{
|
||||
return PushoverReceiver::withUserKey((string) config('services.pushover.user_token'))
|
||||
->withApplicationToken((string) config('services.pushover.token'));
|
||||
//return (string) config('services.pushover.token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to accounts.
|
||||
@@ -192,7 +183,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function getAdministrationId(): int
|
||||
{
|
||||
$groupId = (int)$this->user_group_id;
|
||||
$groupId = (int) $this->user_group_id;
|
||||
if (0 === $groupId) {
|
||||
throw new FireflyException('User has no administration ID.');
|
||||
}
|
||||
@@ -366,7 +357,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function routeNotificationFor($driver, $notification = null)
|
||||
{
|
||||
$method = 'routeNotificationFor'.Str::studly($driver);
|
||||
$method = 'routeNotificationFor' . Str::studly($driver);
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->{$method}($notification); // @phpstan-ignore-line
|
||||
}
|
||||
@@ -382,7 +373,6 @@ class User extends Authenticatable
|
||||
}
|
||||
|
||||
return match ($driver) {
|
||||
'database' => $this->notifications(),
|
||||
'mail' => $email,
|
||||
default => null,
|
||||
};
|
||||
@@ -404,30 +394,41 @@ class User extends Authenticatable
|
||||
return $this->belongsToMany(Role::class);
|
||||
}
|
||||
|
||||
public function routeNotificationForPushover(Notification $notification)
|
||||
{
|
||||
// this check does not validate if the user is owner, Should be done by notification itself.
|
||||
$appToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
||||
$userToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
||||
|
||||
if (property_exists($notification, 'type') && $notification->type === 'owner') {
|
||||
return PushoverReceiver::withUserKey($userToken)
|
||||
->withApplicationToken($appToken);
|
||||
}
|
||||
|
||||
throw new FireflyException('No pushover token found.');
|
||||
// return PushoverReceiver::withUserKey((string) config('services.pushover.user_token'))
|
||||
// ->withApplicationToken((string) config('services.pushover.token'));
|
||||
//return (string) config('services.pushover.token');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Route notifications for the Slack channel.
|
||||
*/
|
||||
public function routeNotificationForSlack(Notification $notification): ?string
|
||||
{
|
||||
// this check does not validate if the user is owner, Should be done by notification itself.
|
||||
$res = app('fireflyconfig')->get('slack_webhook_url', '')->data;
|
||||
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||
if (is_array($res)) {
|
||||
$res = '';
|
||||
}
|
||||
$res = (string)$res;
|
||||
$res = (string) $res;
|
||||
|
||||
// not the best way to do this, but alas.
|
||||
|
||||
if ($notification instanceof TestNotificationSlack) {
|
||||
if (property_exists($notification, 'type') && $notification->type === 'owner') {
|
||||
return $res;
|
||||
}
|
||||
if ($notification instanceof TestNotificationDiscord) {
|
||||
$res = app('fireflyconfig')->get('discord_webhook_url', '')->data;
|
||||
if (is_array($res)) {
|
||||
$res = '';
|
||||
}
|
||||
return (string)$res;
|
||||
}
|
||||
|
||||
// not the best way to do this, but alas.
|
||||
if ($notification instanceof UserInvitation) {
|
||||
return $res;
|
||||
}
|
||||
@@ -437,12 +438,12 @@ class User extends Authenticatable
|
||||
if ($notification instanceof VersionCheckResult) {
|
||||
return $res;
|
||||
}
|
||||
$pref = app('preferences')->getForUser($this, 'slack_webhook_url', '')->data;
|
||||
$pref = app('preferences')->getEncryptedForUser($this, 'slack_webhook_url', '')->data;
|
||||
if (is_array($pref)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (string)$pref;
|
||||
return (string) $pref;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -24,8 +24,8 @@ return [
|
||||
'channels' => [
|
||||
'email' => ['enabled' => true, 'ui_configurable' => 0,],
|
||||
'slack' => ['enabled' => true, 'ui_configurable' => 1,],
|
||||
'ntfy' => ['enabled' => true, 'ui_configurable' => 0,],
|
||||
'pushover' => ['enabled' => true, 'ui_configurable' => 0,],
|
||||
'ntfy' => ['enabled' => true, 'ui_configurable' => 1,],
|
||||
'pushover' => ['enabled' => true, 'ui_configurable' => 1,],
|
||||
'gotify' => ['enabled' => false, 'ui_configurable' => 0,],
|
||||
'pushbullet' => ['enabled' => false, 'ui_configurable' => 0,],
|
||||
],
|
||||
|
@@ -3,12 +3,12 @@
|
||||
// config for Wijourdil/NtfyNotificationChannel
|
||||
return [
|
||||
|
||||
'server' => env('NTFY_SERVER', 'https://ntfy.sh'),
|
||||
'topic' => env('NTFY_TOPIC', ''),
|
||||
'server' => 'https://ntfy.sh',
|
||||
'topic' => '',
|
||||
'authentication' => [
|
||||
'enabled' => (bool) env('NTFY_AUTH_ENABLED', false),
|
||||
'username' => env('NTFY_AUTH_USERNAME', ''),
|
||||
'password' => env('NTFY_AUTH_PASSWORD', ''),
|
||||
'enabled' => false,
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
],
|
||||
|
||||
];
|
||||
|
@@ -183,6 +183,7 @@ return [
|
||||
'file',
|
||||
'staticText',
|
||||
'password',
|
||||
'passwordWithValue',
|
||||
'nonSelectableAmount',
|
||||
'number',
|
||||
'amountNoCurrency',
|
||||
|
@@ -2497,8 +2497,9 @@ return [
|
||||
'notification_settings' => 'Settings for notifications',
|
||||
'notification_settings_saved' => 'The notification settings have been saved',
|
||||
'available_channels_title' => 'Available channels',
|
||||
'available_channels_expl' => 'These channels are available to send notifications over. To test your confiuration, use the buttons below. Please note that the buttons have no spam control.',
|
||||
'available_channels_expl' => 'These channels are available to send notifications over. To test your configuration, use the buttons below. Please note that the buttons have no spam control.',
|
||||
'notification_channel_name_email' => 'Email',
|
||||
'slack_discord_double' => 'The Slack notification channel can also send notifications to Discord.',
|
||||
'notification_channel_name_slack' => 'Slack',
|
||||
'notification_channel_name_ntfy' => 'Ntfy.sh',
|
||||
'notification_channel_name_pushover' => 'Pushover',
|
||||
|
@@ -264,5 +264,12 @@ return [
|
||||
'webhook_delivery' => 'Delivery',
|
||||
'webhook_response' => 'Response',
|
||||
'webhook_trigger' => 'Trigger',
|
||||
'pushover_app_token' => 'Pushover app token',
|
||||
'pushover_user_token' => 'Pushover user token',
|
||||
'ntfy_server' => 'Ntfy server',
|
||||
'ntfy_topic' => 'Ntfy topic',
|
||||
'ntfy_auth' => 'Ntfy authentication enabled',
|
||||
'ntfy_user' => 'Ntfy username',
|
||||
'ntfy_pass' => 'Ntfy password',
|
||||
];
|
||||
// Ignore this comment
|
||||
|
@@ -24,7 +24,16 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
<p style="margin-top:2em;">{{ 'channel_settings'|_ }}</p>
|
||||
{{ ExpandedForm.text('slack_url', slackUrl, {'label' : 'slack_url_label'|_}) }}
|
||||
{{ ExpandedForm.text('slack_webhook_url', slackUrl, {'label' : 'slack_url_label'|_, helpText: trans('firefly.slack_discord_double')}) }}
|
||||
|
||||
{{ ExpandedForm.text('pushover_app_token', pushoverAppToken, {}) }}
|
||||
{{ ExpandedForm.text('pushover_user_token', pushoverUserToken, {}) }}
|
||||
|
||||
{{ ExpandedForm.text('ntfy_server', ntfyServer, {}) }}
|
||||
{{ ExpandedForm.text('ntfy_topic', ntfyTopic, {}) }}
|
||||
{{ ExpandedForm.checkbox('ntfy_auth','1', ntfyAuth, {}) }}
|
||||
{{ ExpandedForm.text('ntfy_user', ntfyUser, {}) }}
|
||||
{{ ExpandedForm.passwordWithValue('ntfy_pass', ntfyPass, {}) }}
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-success">
|
||||
|
Reference in New Issue
Block a user