+
{_heading_crawler}
{control crawlerForm}
+
+
+
+
{_heading_azure_auth}
+
+
+ {control azureAuthForm}
+
diff --git a/src/Web/AdminModule/UserModule/Control/ExternalAuthList/ExternalAuthListControl.php b/src/Web/AdminModule/UserModule/Control/ExternalAuthList/ExternalAuthListControl.php
new file mode 100644
index 00000000..f3b665d1
--- /dev/null
+++ b/src/Web/AdminModule/UserModule/Control/ExternalAuthList/ExternalAuthListControl.php
@@ -0,0 +1,29 @@
+getTemplate();
+ assert($template instanceof ExternalAuthListTemplate);
+
+ $template->externalAuths = $this->queryBus->dispatch(FindExternalAuthenticationsQuery::create(
+ userId: $this->userId,
+ ));
+ }
+}
diff --git a/src/Web/AdminModule/UserModule/Control/ExternalAuthList/ExternalAuthListControlFactoryInterface.php b/src/Web/AdminModule/UserModule/Control/ExternalAuthList/ExternalAuthListControlFactoryInterface.php
new file mode 100644
index 00000000..03a3f6c8
--- /dev/null
+++ b/src/Web/AdminModule/UserModule/Control/ExternalAuthList/ExternalAuthListControlFactoryInterface.php
@@ -0,0 +1,10 @@
+ */
+ public array $externalAuths;
+}
diff --git a/src/Web/AdminModule/UserModule/Control/ExternalAuthList/templates/externalAuthListControl.latte b/src/Web/AdminModule/UserModule/Control/ExternalAuthList/templates/externalAuthListControl.latte
new file mode 100644
index 00000000..980ecac9
--- /dev/null
+++ b/src/Web/AdminModule/UserModule/Control/ExternalAuthList/templates/externalAuthListControl.latte
@@ -0,0 +1,28 @@
+{templateType App\Web\AdminModule\UserModule\Control\ExternalAuthList\ExternalAuthListTemplate}
+
+{if 0 < count($externalAuths)}
+
+
+
+
+
+
+ {_auth_type} |
+ {_resource_owner_id} |
+
+
+
+
+ {$externalAuth->providerCode} |
+ {$externalAuth->resourceOwnerId} |
+
+
+
+
+
+
+{else}
+
+{/if}
diff --git a/src/Web/AdminModule/UserModule/Presenter/EditUserPresenter.php b/src/Web/AdminModule/UserModule/Presenter/EditUserPresenter.php
index 66635a81..5e454539 100644
--- a/src/Web/AdminModule/UserModule/Presenter/EditUserPresenter.php
+++ b/src/Web/AdminModule/UserModule/Presenter/EditUserPresenter.php
@@ -7,6 +7,8 @@
use App\Application\Acl\UserResource;
use App\ReadModel\User\UserView;
use App\Web\AdminModule\Presenter\AdminPresenter;
+use App\Web\AdminModule\UserModule\Control\ExternalAuthList\ExternalAuthListControl;
+use App\Web\AdminModule\UserModule\Control\ExternalAuthList\ExternalAuthListControlFactoryInterface;
use App\Web\AdminModule\UserModule\Control\NotificationPreferences\Event\NotificationPreferencesProcessingFailedEvent;
use App\Web\AdminModule\UserModule\Control\NotificationPreferences\Event\NotificationPreferencesUpdatedEvent;
use App\Web\AdminModule\UserModule\Control\NotificationPreferences\NotificationPreferencesControl;
@@ -31,6 +33,7 @@ final class EditUserPresenter extends AdminPresenter
public function __construct(
private readonly UserFormControlFactoryInterface $userFormControlFactory,
private readonly NotificationPreferencesControlFactoryInterface $notificationPreferencesControlFactory,
+ private readonly ExternalAuthListControlFactoryInterface $externalAuthListControlFactory,
private readonly QueryBusInterface $queryBus,
) {
parent::__construct();
@@ -91,4 +94,11 @@ protected function createComponentNotificationPreferences(): NotificationPrefere
return $control;
}
+
+ protected function createComponentExternalAuthList(): ExternalAuthListControl
+ {
+ return $this->externalAuthListControlFactory->create(
+ userId: $this->userView->id->toString(),
+ );
+ }
}
diff --git a/src/Web/AdminModule/UserModule/Presenter/templates/EditUser.default.latte b/src/Web/AdminModule/UserModule/Presenter/templates/EditUser.default.latte
index 4bbe03c1..e5662109 100644
--- a/src/Web/AdminModule/UserModule/Presenter/templates/EditUser.default.latte
+++ b/src/Web/AdminModule/UserModule/Presenter/templates/EditUser.default.latte
@@ -15,10 +15,18 @@
{control userForm}
-
+
{_notification_preferences}
{control notificationPreferences}
+
+
+
+
{_external_auth_list}
+
+
+ {control externalAuthList}
+
diff --git a/src/Web/FrontModule/Presenter/OAuthPresenter.php b/src/Web/FrontModule/Presenter/OAuthPresenter.php
new file mode 100644
index 00000000..2dbf4719
--- /dev/null
+++ b/src/Web/FrontModule/Presenter/OAuthPresenter.php
@@ -0,0 +1,43 @@
+logger->error($error->getMessage(), [
+ 'exception' => $error,
+ ]);
+
+ $this->subscribeFlashMessage(FlashMessage::error('authentication_failure.' . $flowName));
+ $this->redirect(':Front:SignIn:');
+ }
+
+ protected function onAuthenticationFailed(string $flowName, OAuthExceptionInterface $error): never
+ {
+ $this->subscribeFlashMessage(FlashMessage::error('authentication_failure.' . $flowName));
+ $this->redirect(':Front:SignIn:');
+ }
+
+ protected function onUserAuthenticated(string $flowName): never
+ {
+ $this->redirect(':Admin:Dashboard:');
+ }
+}
diff --git a/src/Web/FrontModule/Presenter/SignInPresenter.php b/src/Web/FrontModule/Presenter/SignInPresenter.php
index a5005c73..267dadc9 100644
--- a/src/Web/FrontModule/Presenter/SignInPresenter.php
+++ b/src/Web/FrontModule/Presenter/SignInPresenter.php
@@ -9,6 +9,8 @@
use App\Web\FrontModule\Control\SignIn\SignInControl;
use App\Web\FrontModule\Control\SignIn\SignInControlFactoryInterface;
use SixtyEightPublishers\FlashMessageBundle\Domain\FlashMessage;
+use SixtyEightPublishers\OAuth\OAuthFlowInterface;
+use SixtyEightPublishers\OAuth\OAuthFlowProviderInterface;
final class SignInPresenter extends FrontPresenter
{
@@ -17,10 +19,28 @@ final class SignInPresenter extends FrontPresenter
public function __construct(
private readonly SignInControlFactoryInterface $signInControlFactory,
+ private readonly OAuthFlowProviderInterface $oauthFlowProvider,
) {
parent::__construct();
}
+ protected function beforeRender(): void
+ {
+ parent::beforeRender();
+
+ $template = $this->getTemplate();
+ assert($template instanceof SignInTemplate);
+
+ $template->backLink = !empty($this->backLink) ? $this->backLink : null;
+ $template->enabledOauthTypes = array_map(
+ static fn (OAuthFlowInterface $flow): string => $flow->getName(),
+ array_filter(
+ $this->oauthFlowProvider->all(),
+ static fn (OauthFlowInterface $flow): bool => $flow->isEnabled(),
+ ),
+ );
+ }
+
protected function createComponentSignIn(): SignInControl
{
$control = $this->signInControlFactory->create();
diff --git a/src/Web/FrontModule/Presenter/SignInTemplate.php b/src/Web/FrontModule/Presenter/SignInTemplate.php
index 6e5f3342..cf606df3 100644
--- a/src/Web/FrontModule/Presenter/SignInTemplate.php
+++ b/src/Web/FrontModule/Presenter/SignInTemplate.php
@@ -8,4 +8,8 @@
final class SignInTemplate extends DefaultPresenterTemplate
{
+ public ?string $backLink = null;
+
+ /** @var array
*/
+ public array $enabledOauthTypes;
}
diff --git a/src/Web/FrontModule/Presenter/templates/SignIn.default.latte b/src/Web/FrontModule/Presenter/templates/SignIn.default.latte
index c7e3bdbb..f555dfc7 100644
--- a/src/Web/FrontModule/Presenter/templates/SignIn.default.latte
+++ b/src/Web/FrontModule/Presenter/templates/SignIn.default.latte
@@ -1,9 +1,58 @@
+{templateType App\Web\FrontModule\Presenter\SignInTemplate}
+
{block #content}
+ {control signIn}
+
+
+
+
+
+ {_oauth_divider}
+
+
+
+
-{control signIn}
+
+{/block}
-
+{define login-icon-azure}
+
+{/define}
diff --git a/src/Web/Router/RouterFactory.php b/src/Web/Router/RouterFactory.php
index 0a168ad2..8d20e930 100644
--- a/src/Web/Router/RouterFactory.php
+++ b/src/Web/Router/RouterFactory.php
@@ -44,6 +44,11 @@ public function create(): RouteList
'locale' => $this->profiles->default()->locale(),
]);
+ $router->addRoute('oauth//', [
+ 'module' => 'Front',
+ 'presenter' => 'OAuth',
+ ]);
+
$router->addRoute('project//[/][/]', [
'module' => 'Admin:Project',
'action' => 'default',
diff --git a/src/Web/Ui/templates/forms/imports.latte b/src/Web/Ui/templates/forms/imports.latte
index 09f8622e..5988103a 100644
--- a/src/Web/Ui/templates/forms/imports.latte
+++ b/src/Web/Ui/templates/forms/imports.latte
@@ -117,10 +117,35 @@
{/define}
{define #input-type-text}
-
+ {if null === $control->getOption('clipboard')}
+
+ {else}
+ {var $clipboardAction = $control->isDisabled() ? 'copy' : $control->getOption('clipboard')}
+
+
+
+
+
+
+
+ {/if}
{/define}
{define #input-type-color-picker}
diff --git a/translations/App_Web_AdminModule_ApplicationModule_Control_AzureAuthSettingsForm_AzureAuthSettingsFormControl.cs.neon b/translations/App_Web_AdminModule_ApplicationModule_Control_AzureAuthSettingsForm_AzureAuthSettingsFormControl.cs.neon
new file mode 100644
index 00000000..037d9988
--- /dev/null
+++ b/translations/App_Web_AdminModule_ApplicationModule_Control_AzureAuthSettingsForm_AzureAuthSettingsFormControl.cs.neon
@@ -0,0 +1,21 @@
+enabled:
+ field: Zapnuto
+
+client_id:
+ field: 'ID aplikace (klienta)'
+ required: Vyplňte prosím ID aplikace.
+
+client_secret:
+ field: Tajný kód klienta
+ required: Vyplňte prosím tajný kód klienta.
+
+tenant_id:
+ field: 'ID adresáře (tenanta)'
+ description: 'Vyplňte pouze pokud je v nastavení aplikace na webu Azure nastaveno "Podporované typy účtu" na možnost "Jen účty v tomto adresáři organizace" - jeden tenant. Jinak ponechte prázdné.'
+
+callback_uri:
+ field: Callback URI
+ description: 'V nastavení aplikace na webu Azure nastavte jako "Identifikátor URI pro přesměrování".'
+
+save:
+ field: Uložit
diff --git a/translations/App_Web_AdminModule_ApplicationModule_Control_AzureAuthSettingsForm_AzureAuthSettingsFormControl.en.neon b/translations/App_Web_AdminModule_ApplicationModule_Control_AzureAuthSettingsForm_AzureAuthSettingsFormControl.en.neon
new file mode 100644
index 00000000..9baa401c
--- /dev/null
+++ b/translations/App_Web_AdminModule_ApplicationModule_Control_AzureAuthSettingsForm_AzureAuthSettingsFormControl.en.neon
@@ -0,0 +1,21 @@
+enabled:
+ field: Enabled
+
+client_id:
+ field: 'Application (client) ID'
+ required: Please enter a application ID.
+
+client_secret:
+ field: Client secret code
+ required: Please enter a client secret code.
+
+tenant_id:
+ field: 'Directory (tenant) ID'
+ description: 'Fill only if the "Supported account types" option in the application settings on the Azure site is set to "Accounts in this organizational directory only" - single tenant. Otherwise, leave blank.'
+
+callback_uri:
+ field: Callback URI
+ description: 'In the application settings on the Azure site, set as the "Redirect URI".'
+
+save:
+ field: Save
diff --git a/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.cs.neon b/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.cs.neon
index 00a79bbf..823e67e0 100644
--- a/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.cs.neon
+++ b/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.cs.neon
@@ -3,6 +3,7 @@ heading_localization: Lokalizace
heading_environments: Prostředí
heading_api_cache: Výkon
heading_crawler: Crawler
+heading_azure_auth: Autentizace pomocí Azure AD
message:
localization_settings_updated: Nastavení lokalizace bylo uloženo.
@@ -13,3 +14,5 @@ message:
crawler_settings_update_failed: Při ukládaní nastavení došlo k chybě.
environments_updated: Nastavení prostředí bylo uloženo.
environments_update_failed: Při ukládaní nastavení došlo k chybě.
+ azure_auth_updated: Nastavení Azure AD bylo uloženo.
+ azure_auth_update_failed: Při ukládaní nastavení došlo k chybě.
diff --git a/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.en.neon b/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.en.neon
index fb47cd3c..0f3942df 100644
--- a/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.en.neon
+++ b/translations/App_Web_AdminModule_ApplicationModule_Presenter_SettingsPresenter.en.neon
@@ -3,6 +3,7 @@ heading_localization: Localization
heading_environments: Environments
heading_api_cache: Performance
heading_crawler: Crawler
+heading_azure_auth: Authentication with Azure AD
message:
localization_settings_updated: The localization settings have been saved.
diff --git a/translations/App_Web_AdminModule_UserModule_Control_ExternalAuthList_ExternalAuthListControl.cs.neon b/translations/App_Web_AdminModule_UserModule_Control_ExternalAuthList_ExternalAuthListControl.cs.neon
new file mode 100644
index 00000000..d1822815
--- /dev/null
+++ b/translations/App_Web_AdminModule_UserModule_Control_ExternalAuthList_ExternalAuthListControl.cs.neon
@@ -0,0 +1,3 @@
+auth_type: Typ autentizace
+resource_owner_id: ID uživatele
+no_rows: Uživatel nepoužívá žádnou externí autentizaci.
diff --git a/translations/App_Web_AdminModule_UserModule_Control_ExternalAuthList_ExternalAuthListControl.en.neon b/translations/App_Web_AdminModule_UserModule_Control_ExternalAuthList_ExternalAuthListControl.en.neon
new file mode 100644
index 00000000..8e44ab44
--- /dev/null
+++ b/translations/App_Web_AdminModule_UserModule_Control_ExternalAuthList_ExternalAuthListControl.en.neon
@@ -0,0 +1,3 @@
+auth_type: Authentication type
+resource_owner_id: User ID
+no_rows: The user does not use any external authentication.
diff --git a/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.cs.neon b/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.cs.neon
index b25fceed..900e665d 100644
--- a/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.cs.neon
+++ b/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.cs.neon
@@ -1,6 +1,7 @@
page_title: Upravit uživatele
heading_basic: Základní informace
notification_preferences: Nastavení notifikací
+external_auth_list: Externí autentizace
back_to_list: Zpět na výpis uživatelů
message:
diff --git a/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.en.neon b/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.en.neon
index c23efcc8..51833579 100644
--- a/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.en.neon
+++ b/translations/App_Web_AdminModule_UserModule_Presenter_EditUserPresenter.en.neon
@@ -1,6 +1,7 @@
page_title: Edit user
heading_basic: Basic information
notification_preferences: Notification settings
+external_auth_list: External authentication
back_to_list: Back to the user list
message:
diff --git a/translations/App_Web_FrontModule_Presenter_OAuthPresenter.cs.neon b/translations/App_Web_FrontModule_Presenter_OAuthPresenter.cs.neon
new file mode 100644
index 00000000..5a0e921d
--- /dev/null
+++ b/translations/App_Web_FrontModule_Presenter_OAuthPresenter.cs.neon
@@ -0,0 +1,3 @@
+message:
+ authentication_failure:
+ azure: Přihlášení skrze Azure AD se nezdařilo.
diff --git a/translations/App_Web_FrontModule_Presenter_OAuthPresenter.en.neon b/translations/App_Web_FrontModule_Presenter_OAuthPresenter.en.neon
new file mode 100644
index 00000000..f17339ba
--- /dev/null
+++ b/translations/App_Web_FrontModule_Presenter_OAuthPresenter.en.neon
@@ -0,0 +1,3 @@
+message:
+ authentication_failure:
+ azure: Login via Azure AD failed.
diff --git a/translations/App_Web_FrontModule_Presenter_SignInPresenter.cs.neon b/translations/App_Web_FrontModule_Presenter_SignInPresenter.cs.neon
index cdd2c7dd..a0ba8bf6 100644
--- a/translations/App_Web_FrontModule_Presenter_SignInPresenter.cs.neon
+++ b/translations/App_Web_FrontModule_Presenter_SignInPresenter.cs.neon
@@ -1,5 +1,9 @@
page_title: Přihlášení
forgot_your_password: Zapomenuté heslo?
+oauth_divider: Nebo
+
+login_with:
+ azure: Přihlásit se přes Azure
message:
user_authentication_failed: Nesprávné přihlašovací údaje.
diff --git a/translations/App_Web_FrontModule_Presenter_SignInPresenter.en.neon b/translations/App_Web_FrontModule_Presenter_SignInPresenter.en.neon
index 50206272..70539604 100644
--- a/translations/App_Web_FrontModule_Presenter_SignInPresenter.en.neon
+++ b/translations/App_Web_FrontModule_Presenter_SignInPresenter.en.neon
@@ -1,5 +1,9 @@
page_title: Sign in
forgot_your_password: Forgot Password?
+oauth_divider: Or
+
+login_with:
+ azure: Sign in with Azure
message:
user_authentication_failed: Incorrect credentials.
diff --git a/translations/layout.cs.neon b/translations/layout.cs.neon
index 47125acf..9351028d 100644
--- a/translations/layout.cs.neon
+++ b/translations/layout.cs.neon
@@ -51,5 +51,9 @@ alert:
text: Výchozí jazyk pro tento projekt není nastaven.
link_text: Nastavte jej prosím v editaci projektu.
+clipboard:
+ success_copy: Zkopírováno
+ error_copy: Kopírování se nezdařilo
+
message:
locale_change_failed: Jazyk se nepovedlo změnit.
diff --git a/translations/layout.en.neon b/translations/layout.en.neon
index 6f193e4f..efd70611 100644
--- a/translations/layout.en.neon
+++ b/translations/layout.en.neon
@@ -51,5 +51,9 @@ alert:
text: The default locale for this project is not set.
link_text: Please set it in the app settings.
+clipboard:
+ success_copy: Copied
+ error_copy: Copying failed
+
message:
locale_change_failed: The language could not be changed.
diff --git a/yarn.lock b/yarn.lock
index 88e74c06..dfaebb4f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2117,6 +2117,15 @@ cli-boxes@^2.2.1:
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
+clipboard@^2.0.11:
+ version "2.0.11"
+ resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5"
+ integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==
+ dependencies:
+ good-listener "^1.2.2"
+ select "^1.1.2"
+ tiny-emitter "^2.0.0"
+
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
@@ -2614,6 +2623,11 @@ del@^4.1.1:
pify "^4.0.1"
rimraf "^2.6.3"
+delegate@^3.1.2:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
+ integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
+
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -3339,6 +3353,13 @@ globby@^6.1.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
+good-listener@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
+ integrity sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==
+ dependencies:
+ delegate "^3.1.2"
+
got@^11.8.5, got@^9.6.0:
version "11.8.5"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046"
@@ -5370,6 +5391,11 @@ select-hose@^2.0.0:
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
+select@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
+ integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==
+
selfsigned@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56"
@@ -5804,6 +5830,11 @@ thunky@^1.0.2:
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
+tiny-emitter@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
+ integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
+
tippy.js@^6.3.7:
version "6.3.7"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"