From 9e3794a95643002d3d29e0921c76631241c60fcf Mon Sep 17 00:00:00 2001
From: Bubka <858858+Bubka@users.noreply.github.com>
Date: Thu, 5 Jun 2025 13:03:08 +0200
Subject: [PATCH] Add the Preferred icon collection user preference
---
app/Services/IconService.php | 3 ++-
config/2fauth.php | 1 +
.../js/components/formElements/FormSelect.vue | 3 ++-
resources/js/views/settings/Options.vue | 19 +++++++++++++++++++
resources/lang/en/commons.php | 1 +
resources/lang/en/settings.php | 4 ++++
6 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/app/Services/IconService.php b/app/Services/IconService.php
index fdf3770b..94aaf4ed 100644
--- a/app/Services/IconService.php
+++ b/app/Services/IconService.php
@@ -5,6 +5,7 @@ namespace App\Services;
use App\Facades\IconStore;
use App\Facades\LogoLib;
use App\Helpers\Helpers;
+use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
@@ -18,7 +19,7 @@ class IconService
*/
public function buildFromOfficialLogo(?string $service) : ?string
{
- return LogoLib::driver('tfa')->getIcon($service);
+ return LogoLib::driver(Auth::user()->preferences['iconCollection'])->getIcon($service);
}
/**
diff --git a/config/2fauth.php b/config/2fauth.php
index 8c949c40..c4e9fa33 100644
--- a/config/2fauth.php
+++ b/config/2fauth.php
@@ -13,6 +13,7 @@ $preferences = [
'useBasicQrcodeReader' => envUnlessEmpty('USERPREF_DEFAULT__USE_BASIC_QRCODE_READER', false),
'displayMode' => envUnlessEmpty('USERPREF_DEFAULT__DISPLAY_MODE', 'list'),
'showAccountsIcons' => envUnlessEmpty('USERPREF_DEFAULT__SHOW_ACCOUNTS_ICONS', true),
+ 'iconCollection' => envUnlessEmpty('USERPREF_DEFAULT__ICON_COLLECTION', 'selfh'),
'kickUserAfter' => envUnlessEmpty('USERPREF_DEFAULT__KICK_USER_AFTER', 15),
'activeGroup' => 0,
'rememberActiveGroup' => envUnlessEmpty('USERPREF_DEFAULT__REMEMBER_ACTIVE_GROUP', true),
diff --git a/resources/js/components/formElements/FormSelect.vue b/resources/js/components/formElements/FormSelect.vue
index 8ac2e5b1..a9a70d81 100644
--- a/resources/js/components/formElements/FormSelect.vue
+++ b/resources/js/components/formElements/FormSelect.vue
@@ -56,9 +56,10 @@
:aria-invalid="fieldError != undefined"
:aria-errormessage="fieldError != undefined ? valErrorId : undefined"
>
-
+
+
diff --git a/resources/js/views/settings/Options.vue b/resources/js/views/settings/Options.vue
index e9ea99d7..a5aa6abc 100644
--- a/resources/js/views/settings/Options.vue
+++ b/resources/js/views/settings/Options.vue
@@ -23,6 +23,11 @@
{ text: 'settings.forms.dark', value: 'dark', icon: 'moon' },
{ text: 'settings.forms.automatic', value: 'system', icon: 'desktop' },
]
+ const iconCollections = [
+ { text: 'selfh.st', value: 'selfh', url: 'https://selfh.st/icons/' },
+ { text: 'dashboardicons.com', value: 'dashboardicons', url: 'https://dashboardicons.com/' },
+ { text: '2fa.directory', value: 'tfa', url: 'https://2fa.directory/' },
+ ]
const passwordFormats = [
{ text: '12 34 56', value: 2, legend: 'settings.forms.pair', title: 'settings.forms.pair_legend' },
{ text: '123 456', value: 3, legend: 'settings.forms.trio', title: 'settings.forms.trio_legend' },
@@ -74,6 +79,14 @@
return locales
})
+ const iconCollectionUrl = computed(() => {
+ return iconCollections.find(({ value }) => value === user.preferences.iconCollection)?.url
+ })
+
+ const iconCollectionDomain = computed(() => {
+ return iconCollections.find(({ value }) => value === user.preferences.iconCollection)?.text
+ })
+
onMounted(() => {
groups.items.forEach((group) => {
if( group.id > 0 ) {
@@ -145,6 +158,12 @@
savePreference('showAccountsIcons', val)" fieldName="showAccountsIcons" :isLocked="appSettings.lockedPreferences.includes('showAccountsIcons')" label="settings.forms.show_accounts_icons.label" help="settings.forms.show_accounts_icons.help" />
savePreference('getOfficialIcons', val)" fieldName="getOfficialIcons" :isLocked="appSettings.lockedPreferences.includes('getOfficialIcons')" label="settings.forms.get_official_icons.label" help="settings.forms.get_official_icons.help" />
+
+ savePreference('iconCollection', val)" :options="iconCollections" fieldName="iconCollection" :isLocked="appSettings.lockedPreferences.includes('iconCollection')" :isDisabled="!user.preferences.getOfficialIcons" label="settings.forms.icon_collection.label" help="settings.forms.icon_collection.help" :isIndented="true">
+
+
+
+
savePreference('formatPassword', val)" fieldName="formatPassword" :isLocked="appSettings.lockedPreferences.includes('formatPassword')" label="settings.forms.password_format.label" help="settings.forms.password_format.help" />
savePreference('formatPasswordBy', val)" :choices="passwordFormats" fieldName="formatPasswordBy" :isLocked="appSettings.lockedPreferences.includes('formatPasswordBy')" :isDisabled="!user.preferences.formatPassword" />
diff --git a/resources/lang/en/commons.php b/resources/lang/en/commons.php
index 7e92efdb..479b83b3 100644
--- a/resources/lang/en/commons.php
+++ b/resources/lang/en/commons.php
@@ -92,4 +92,5 @@ return [
'x_month' => ':x mos.',
'one_year' => '1 yr.',
'copy_next_password' => 'Copy next password to clipboard',
+ 'visit_x' => 'Visit :website'
];
diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php
index cfd80cb8..7455f3ea 100644
--- a/resources/lang/en/settings.php
+++ b/resources/lang/en/settings.php
@@ -125,6 +125,10 @@ return [
'label' => 'Get official icons',
'help' => '(Try to) Get the official icon of the 2FA issuer when adding an account'
],
+ 'icon_collection' => [
+ 'label' => 'Preferred icons source',
+ 'help' => 'The icons collection to be queried when an official icon is required. Changing this setting does not refresh icons that have already been fetched.'
+ ],
'auto_lock' => [
'label' => 'Auto lock',
'help' => 'Log out the user automatically in case of inactivity. Has no effect when authentication is handled by a proxy and no custom logout url is specified.'