Просмотр исходного кода

fix non-auto fixable biome errors

Futa Arai 3 месяцев назад
Родитель
Сommit
b6ddc52149
38 измененных файлов с 354 добавлено и 178 удалено
  1. 1 0
      apps/app/src/client/components/Admin/AuditLog/AuditLogDisableMode.tsx
  2. 3 0
      apps/app/src/client/components/Admin/AuditLog/AuditLogSettings.tsx
  3. 3 1
      apps/app/src/client/components/Admin/AuditLog/SearchUsernameTypeahead.tsx
  4. 5 1
      apps/app/src/client/components/Admin/AuditLog/SelectActionDropdown.tsx
  5. 8 6
      apps/app/src/client/components/Admin/Customize/CustomizeLayoutSetting.tsx
  6. 13 4
      apps/app/src/client/components/Admin/Customize/CustomizeLogoSetting.tsx
  7. 6 5
      apps/app/src/client/components/Admin/Customize/CustomizeNoscriptSetting.tsx
  8. 5 5
      apps/app/src/client/components/Admin/Customize/CustomizeScriptSetting.tsx
  9. 8 6
      apps/app/src/client/components/Admin/Customize/CustomizeSidebarSetting.tsx
  10. 4 0
      apps/app/src/client/components/Admin/Customize/CustomizeTitle.tsx
  11. 2 2
      apps/app/src/client/components/Admin/Customize/PagingSizeUncontrolledDropdown.jsx
  12. 7 5
      apps/app/src/client/components/Admin/Customize/ThemeColorBox.tsx
  13. 4 0
      apps/app/src/client/components/Admin/Notification/GlobalNotification.jsx
  14. 4 5
      apps/app/src/client/components/Admin/Notification/GlobalNotificationList.jsx
  15. 5 2
      apps/app/src/client/components/Admin/Notification/ManageGlobalNotification.tsx
  16. 18 14
      apps/app/src/client/components/Admin/Notification/NotificationSetting.jsx
  17. 2 0
      apps/app/src/client/components/Admin/Notification/UserTriggerNotification.jsx
  18. 1 1
      apps/app/src/client/components/Admin/Security/GitHubSecuritySetting.jsx
  19. 22 7
      apps/app/src/client/components/Admin/Security/GitHubSecuritySettingContents.tsx
  20. 1 1
      apps/app/src/client/components/Admin/Security/GoogleSecuritySetting.jsx
  21. 24 7
      apps/app/src/client/components/Admin/Security/GoogleSecuritySettingContents.tsx
  22. 1 3
      apps/app/src/client/components/Admin/Security/LdapAuthTest.tsx
  23. 1 1
      apps/app/src/client/components/Admin/Security/LdapSecuritySetting.jsx
  24. 36 15
      apps/app/src/client/components/Admin/Security/LdapSecuritySettingContents.tsx
  25. 1 1
      apps/app/src/client/components/Admin/Security/LocalSecuritySetting.jsx
  26. 7 8
      apps/app/src/client/components/Admin/Security/LocalSecuritySettingContents.tsx
  27. 1 1
      apps/app/src/client/components/Admin/Security/OidcSecuritySetting.jsx
  28. 50 14
      apps/app/src/client/components/Admin/Security/OidcSecuritySettingContents.tsx
  29. 1 1
      apps/app/src/client/components/Admin/Security/SamlSecuritySetting.jsx
  30. 48 13
      apps/app/src/client/components/Admin/Security/SamlSecuritySettingContents.tsx
  31. 1 1
      apps/app/src/client/components/Admin/Security/SecurityManagement.tsx
  32. 47 36
      apps/app/src/client/components/Admin/Security/SecurityManagementContents.jsx
  33. 1 1
      apps/app/src/client/components/Admin/Security/SecuritySetting/CommentManageRightsSettings.tsx
  34. 2 1
      apps/app/src/client/components/Admin/Security/SecuritySetting/PageAccessRightsSettings.tsx
  35. 2 1
      apps/app/src/client/components/Admin/Security/SecuritySetting/PageDeleteRightsSettings.tsx
  36. 2 8
      apps/app/src/client/components/Admin/Security/SecuritySetting/PageListDisplaySettings.tsx
  37. 6 1
      apps/app/src/client/components/Admin/Security/SecuritySetting/SessionMaxAgeSettings.tsx
  38. 1 0
      apps/app/src/client/components/Admin/Security/SecuritySetting/UserHomepageDeletionSettings.tsx

+ 1 - 0
apps/app/src/client/components/Admin/AuditLog/AuditLogDisableMode.tsx

@@ -20,6 +20,7 @@ export const AuditLogDisableMode: FC = () => {
               </h1>
               </h1>
               <h3
               <h3
                 // eslint-disable-next-line react/no-danger
                 // eslint-disable-next-line react/no-danger
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('audit_log_management.disable_mode_explanation'),
                   __html: t('audit_log_management.disable_mode_explanation'),
                 }}
                 }}

+ 3 - 0
apps/app/src/client/components/Admin/AuditLog/AuditLogSettings.tsx

@@ -34,6 +34,7 @@ export const AuditLogSettings: FC = () => {
         <br />
         <br />
         <b
         <b
           // eslint-disable-next-line react/no-danger
           // eslint-disable-next-line react/no-danger
+          // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('admin:audit_log_management.fixed_by_env_var', {
             __html: t('admin:audit_log_management.fixed_by_env_var', {
               key: 'ACTIVITY_EXPIRATION_SECONDS',
               key: 'ACTIVITY_EXPIRATION_SECONDS',
@@ -53,10 +54,12 @@ export const AuditLogSettings: FC = () => {
           href={t('admin:audit_log_management.docs_url.log_type')}
           href={t('admin:audit_log_management.docs_url.log_type')}
           target="_blank"
           target="_blank"
           rel="noopener noreferrer"
           rel="noopener noreferrer"
+          aria-label="Help"
         >
         >
           <span className="material-symbols-outlined" aria-hidden="true">
           <span className="material-symbols-outlined" aria-hidden="true">
             help
             help
           </span>
           </span>
+          <span className="visually-hidden">Help</span>
         </a>
         </a>
       </h4>
       </h4>
       <p className="form-text text-muted">
       <p className="form-text text-muted">

+ 3 - 1
apps/app/src/client/components/Admin/AuditLog/SearchUsernameTypeahead.tsx

@@ -74,7 +74,9 @@ const SearchUsernameTypeaheadSubstance: ForwardRefRenderFunction<
 
 
   const allUser: UserDataType[] = [];
   const allUser: UserDataType[] = [];
   const pushToAllUser = (usernames: string[], category: CategoryType) => {
   const pushToAllUser = (usernames: string[], category: CategoryType) => {
-    usernames.forEach((username) => allUser.push({ username, category }));
+    usernames.forEach((username) => {
+      allUser.push({ username, category });
+    });
   };
   };
   pushToAllUser(activeUsernames, Categories.activeUser);
   pushToAllUser(activeUsernames, Categories.activeUser);
   pushToAllUser(inactiveUsernames, Categories.inactiveUser);
   pushToAllUser(inactiveUsernames, Categories.inactiveUser);

+ 5 - 1
apps/app/src/client/components/Admin/AuditLog/SelectActionDropdown.tsx

@@ -142,6 +142,7 @@ export const SelectActionDropdown: FC<Props> = (props: Props) => {
                 <input
                 <input
                   type="checkbox"
                   type="checkbox"
                   className="form-check-input"
                   className="form-check-input"
+                  id={`checkboxCategory${item.actionCategory}`}
                   defaultChecked
                   defaultChecked
                   onChange={(e) => {
                   onChange={(e) => {
                     multipleActionCheckboxChangedHandler(
                     multipleActionCheckboxChangedHandler(
@@ -150,7 +151,10 @@ export const SelectActionDropdown: FC<Props> = (props: Props) => {
                     );
                     );
                   }}
                   }}
                 />
                 />
-                <label className="form-label form-check-label">
+                <label
+                  className="form-label form-check-label"
+                  htmlFor={`checkboxCategory${item.actionCategory}`}
+                >
                   {t(`admin:audit_log_action_category.${item.actionCategory}`)}
                   {t(`admin:audit_log_action_category.${item.actionCategory}`)}
                 </label>
                 </label>
               </div>
               </div>

+ 8 - 6
apps/app/src/client/components/Admin/Customize/CustomizeLayoutSetting.tsx

@@ -66,10 +66,11 @@ const CustomizeLayoutSetting = (): JSX.Element => {
           <div className="d-flex justify-content-around mt-5">
           <div className="d-flex justify-content-around mt-5">
             <div className="row row-cols-2">
             <div className="row row-cols-2">
               <div className="col">
               <div className="col">
-                <div
+                <button
+                  type="button"
                   className={`card border border-4 ${!isContainerFluid ? 'border-primary' : ''}`}
                   className={`card border border-4 ${!isContainerFluid ? 'border-primary' : ''}`}
                   onClick={() => setIsContainerFluid(false)}
                   onClick={() => setIsContainerFluid(false)}
-                  role="button"
+                  aria-pressed={!isContainerFluid}
                 >
                 >
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   <img
                   <img
@@ -80,13 +81,14 @@ const CustomizeLayoutSetting = (): JSX.Element => {
                   <div className="card-body text-center">
                   <div className="card-body text-center">
                     {t('customize_settings.layout_options.default')}
                     {t('customize_settings.layout_options.default')}
                   </div>
                   </div>
-                </div>
+                </button>
               </div>
               </div>
               <div className="col">
               <div className="col">
-                <div
+                <button
+                  type="button"
                   className={`card border border-4 ${isContainerFluid ? 'border-primary' : ''}`}
                   className={`card border border-4 ${isContainerFluid ? 'border-primary' : ''}`}
                   onClick={() => setIsContainerFluid(true)}
                   onClick={() => setIsContainerFluid(true)}
-                  role="button"
+                  aria-pressed={isContainerFluid}
                 >
                 >
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   <img
                   <img
@@ -97,7 +99,7 @@ const CustomizeLayoutSetting = (): JSX.Element => {
                   <div className="card-body text-center">
                   <div className="card-body text-center">
                     {t('customize_settings.layout_options.expanded')}
                     {t('customize_settings.layout_options.expanded')}
                   </div>
                   </div>
-                </div>
+                </button>
               </div>
               </div>
             </div>
             </div>
           </div>
           </div>

+ 13 - 4
apps/app/src/client/components/Admin/Customize/CustomizeLogoSetting.tsx

@@ -128,7 +128,11 @@ const CustomizeLogoSetting = (): JSX.Element => {
                     </label>
                     </label>
                   </div>
                   </div>
                 </h4>
                 </h4>
-                <img src={DEFAULT_LOGO} width="64" />
+                <img
+                  src={DEFAULT_LOGO}
+                  width="64"
+                  alt={t('admin:customize_settings.default_logo')}
+                />
               </div>
               </div>
               <div className="col-md-6 col-12">
               <div className="col-md-6 col-12">
                 <h4>
                 <h4>
@@ -153,9 +157,9 @@ const CustomizeLogoSetting = (): JSX.Element => {
                   </div>
                   </div>
                 </h4>
                 </h4>
                 <div className="row mb-3">
                 <div className="row mb-3">
-                  <label className="col-sm-4 col-12 col-form-label text-start">
+                  <span className="col-sm-4 col-12 col-form-label text-start">
                     {t('admin:customize_settings.current_logo')}
                     {t('admin:customize_settings.current_logo')}
-                  </label>
+                  </span>
                   <div className="col-sm-8 col-12">
                   <div className="col-sm-8 col-12">
                     {isCustomizedLogoUploaded && (
                     {isCustomizedLogoUploaded && (
                       <>
                       <>
@@ -164,6 +168,7 @@ const CustomizeLogoSetting = (): JSX.Element => {
                             src={CUSTOMIZED_LOGO}
                             src={CUSTOMIZED_LOGO}
                             id="settingBrandLogo"
                             id="settingBrandLogo"
                             width="64"
                             width="64"
+                            alt={t('admin:customize_settings.current_logo')}
                           />
                           />
                         </p>
                         </p>
                         <button
                         <button
@@ -178,11 +183,15 @@ const CustomizeLogoSetting = (): JSX.Element => {
                   </div>
                   </div>
                 </div>
                 </div>
                 <div className="row">
                 <div className="row">
-                  <label className="col-sm-4 col-12 col-form-label text-start">
+                  <label
+                    className="col-sm-4 col-12 col-form-label text-start"
+                    htmlFor="uploadLogoInput"
+                  >
                     {t('admin:customize_settings.upload_new_logo')}
                     {t('admin:customize_settings.upload_new_logo')}
                   </label>
                   </label>
                   <div className="col-sm-8 col-12">
                   <div className="col-sm-8 col-12">
                     <input
                     <input
+                      id="uploadLogoInput"
                       type="file"
                       type="file"
                       onChange={onSelectFile}
                       onChange={onSelectFile}
                       name="brandLogo"
                       name="brandLogo"

+ 6 - 5
apps/app/src/client/components/Admin/Customize/CustomizeNoscriptSetting.tsx

@@ -62,6 +62,7 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
             <CardBody className="px-0 py-2">
             <CardBody className="px-0 py-2">
               <span
               <span
                 // eslint-disable-next-line react/no-danger
                 // eslint-disable-next-line react/no-danger
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('admin:customize_settings.custom_noscript_detail'),
                   __html: t('admin:customize_settings.custom_noscript_detail'),
                 }}
                 }}
@@ -78,11 +79,11 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
               />
               />
             </div>
             </div>
 
 
-            <a
-              className="text-muted"
+            <button
+              type="button"
+              className="btn btn-link text-muted p-0"
               data-bs-toggle="collapse"
               data-bs-toggle="collapse"
-              href="#collapseExampleHtml"
-              role="button"
+              data-bs-target="#collapseExampleHtml"
               aria-expanded="false"
               aria-expanded="false"
               aria-controls="collapseExampleHtml"
               aria-controls="collapseExampleHtml"
             >
             >
@@ -93,7 +94,7 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
                 navigate_next
                 navigate_next
               </span>
               </span>
               Example for Google Tag Manager
               Example for Google Tag Manager
-            </a>
+            </button>
             <div className="collapse" id="collapseExampleHtml">
             <div className="collapse" id="collapseExampleHtml">
               <PrismAsyncLight style={oneDark} language="javascript">
               <PrismAsyncLight style={oneDark} language="javascript">
                 {`<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
                 {`<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"

+ 5 - 5
apps/app/src/client/components/Admin/Customize/CustomizeScriptSetting.tsx

@@ -74,11 +74,11 @@ const CustomizeScriptSetting = (props: Props): JSX.Element => {
               />
               />
             </div>
             </div>
 
 
-            <a
-              className="text-muted"
+            <button
+              type="button"
+              className="btn btn-link text-muted p-0"
               data-bs-toggle="collapse"
               data-bs-toggle="collapse"
-              href="#collapseExampleScript"
-              role="button"
+              data-bs-target="#collapseExampleScript"
               aria-expanded="false"
               aria-expanded="false"
               aria-controls="collapseExampleScript"
               aria-controls="collapseExampleScript"
             >
             >
@@ -89,7 +89,7 @@ const CustomizeScriptSetting = (props: Props): JSX.Element => {
                 navigate_next
                 navigate_next
               </span>
               </span>
               Example for Google Tag Manager
               Example for Google Tag Manager
-            </a>
+            </button>
             <div className="collapse" id="collapseExampleScript">
             <div className="collapse" id="collapseExampleScript">
               <PrismAsyncLight style={oneDark} language="javascript">
               <PrismAsyncLight style={oneDark} language="javascript">
                 {`(function(w,d,s,l,i){
                 {`(function(w,d,s,l,i){

+ 8 - 6
apps/app/src/client/components/Admin/Customize/CustomizeSidebarSetting.tsx

@@ -53,26 +53,28 @@ const CustomizeSidebarsetting = (): JSX.Element => {
           <div className="d-flex justify-content-around mt-5">
           <div className="d-flex justify-content-around mt-5">
             <div className="row row-cols-2">
             <div className="row row-cols-2">
               <div className="col">
               <div className="col">
-                <div
+                <button
+                  type="button"
                   className={`card border border-4 ${isSidebarCollapsedMode ? 'border-primary' : ''}`}
                   className={`card border border-4 ${isSidebarCollapsedMode ? 'border-primary' : ''}`}
                   onClick={() => setIsSidebarCollapsedMode(true)}
                   onClick={() => setIsSidebarCollapsedMode(true)}
-                  role="button"
+                  aria-pressed={isSidebarCollapsedMode}
                 >
                 >
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   <img src={collapsedIconFileName} alt="Collapsed Mode" />
                   <img src={collapsedIconFileName} alt="Collapsed Mode" />
                   <div className="card-body text-center">Collapsed Mode</div>
                   <div className="card-body text-center">Collapsed Mode</div>
-                </div>
+                </button>
               </div>
               </div>
               <div className="col">
               <div className="col">
-                <div
+                <button
+                  type="button"
                   className={`card border border-4 ${!isSidebarCollapsedMode ? 'border-primary' : ''}`}
                   className={`card border border-4 ${!isSidebarCollapsedMode ? 'border-primary' : ''}`}
                   onClick={() => setIsSidebarCollapsedMode(false)}
                   onClick={() => setIsSidebarCollapsedMode(false)}
-                  role="button"
+                  aria-pressed={!isSidebarCollapsedMode}
                 >
                 >
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   {/* eslint-disable-next-line @next/next/no-img-element */}
                   <img src={dockIconFileName} alt="Dock Mode" />
                   <img src={dockIconFileName} alt="Dock Mode" />
                   <div className="card-body  text-center">Dock Mode</div>
                   <div className="card-body  text-center">Dock Mode</div>
-                </div>
+                </button>
               </div>
               </div>
             </div>
             </div>
           </div>
           </div>

+ 4 - 0
apps/app/src/client/components/Admin/Customize/CustomizeTitle.tsx

@@ -57,6 +57,7 @@ export const CustomizeTitle: FC = () => {
             <CardBody className="px-0 py-2">
             <CardBody className="px-0 py-2">
               {/* eslint-disable react/no-danger */}
               {/* eslint-disable react/no-danger */}
               <p
               <p
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('admin:customize_settings.custom_title_detail'),
                   __html: t('admin:customize_settings.custom_title_detail'),
                 }}
                 }}
@@ -64,6 +65,7 @@ export const CustomizeTitle: FC = () => {
               <ul>
               <ul>
                 <li>
                 <li>
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'admin:customize_settings.custom_title_detail_placeholder1',
                         'admin:customize_settings.custom_title_detail_placeholder1',
@@ -73,6 +75,7 @@ export const CustomizeTitle: FC = () => {
                 </li>
                 </li>
                 <li>
                 <li>
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'admin:customize_settings.custom_title_detail_placeholder2',
                         'admin:customize_settings.custom_title_detail_placeholder2',
@@ -82,6 +85,7 @@ export const CustomizeTitle: FC = () => {
                 </li>
                 </li>
                 <li>
                 <li>
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'admin:customize_settings.custom_title_detail_placeholder3',
                         'admin:customize_settings.custom_title_detail_placeholder3',

+ 2 - 2
apps/app/src/client/components/Admin/Customize/PagingSizeUncontrolledDropdown.jsx

@@ -20,7 +20,7 @@ const PagingSizeUncontrolledDropdown = (props) => {
       <div className="row">
       <div className="row">
         <div className="offset-md-2 col-md-7 text-start">
         <div className="offset-md-2 col-md-7 text-start">
           <div className="my-0 w-100">
           <div className="my-0 w-100">
-            <label className="form-label">{props.label}</label>
+            <span className="form-label">{props.label}</span>
           </div>
           </div>
           <UncontrolledDropdown>
           <UncontrolledDropdown>
             <DropdownToggle className="text-end col-6" caret>
             <DropdownToggle className="text-end col-6" caret>
@@ -34,7 +34,7 @@ const PagingSizeUncontrolledDropdown = (props) => {
                     role="presentation"
                     role="presentation"
                     onClick={() => dropdownItemOnClickHandler(num)}
                     onClick={() => dropdownItemOnClickHandler(num)}
                   >
                   >
-                    <a role="menuitem">{num}</a>
+                    {num}
                   </DropdownItem>
                   </DropdownItem>
                 );
                 );
               })}
               })}

+ 7 - 5
apps/app/src/client/components/Admin/Customize/ThemeColorBox.tsx

@@ -26,14 +26,15 @@ export const ThemeColorBox = (props: Props): JSX.Element => {
   } = metadata;
   } = metadata;
 
 
   return (
   return (
-    <div
+    <button
+      type="button"
       id={`theme-option-${name}`}
       id={`theme-option-${name}`}
       className={`${themeOptionClass} d-flex flex-column align-items-center ${isSelected ? 'active' : ''}`}
       className={`${themeOptionClass} d-flex flex-column align-items-center ${isSelected ? 'active' : ''}`}
       onClick={onSelected}
       onClick={onSelected}
+      aria-pressed={isSelected}
     >
     >
-      <a
+      <div
         id={name}
         id={name}
-        role="button"
         className={`
         className={`
           m-0 rounded rounded-3
           m-0 rounded rounded-3
           border border-4 border-primary ${isSelected ? '' : 'border-opacity-10'}`}
           border border-4 border-primary ${isSelected ? '' : 'border-opacity-10'}`}
@@ -45,6 +46,7 @@ export const ThemeColorBox = (props: Props): JSX.Element => {
           height="64"
           height="64"
           className="rounded"
           className="rounded"
         >
         >
+          <title>{name}</title>
           <path d="M32.5,0V36.364L64,20.437V0Z" fill={lightBg} />
           <path d="M32.5,0V36.364L64,20.437V0Z" fill={lightBg} />
           <path d="M32.5,36.364V64H64V20.438Z" fill={darkBg} />
           <path d="M32.5,36.364V64H64V20.438Z" fill={darkBg} />
           <path
           <path
@@ -73,7 +75,7 @@ export const ThemeColorBox = (props: Props): JSX.Element => {
             fill={darkIcon}
             fill={darkIcon}
           />
           />
         </svg>
         </svg>
-      </a>
+      </div>
       <span className={`mt-2 ${isSelected ? '' : 'opacity-25'}`}>
       <span className={`mt-2 ${isSelected ? '' : 'opacity-25'}`}>
         <b>{name}</b>
         <b>{name}</b>
       </span>
       </span>
@@ -84,6 +86,6 @@ export const ThemeColorBox = (props: Props): JSX.Element => {
           Plugin
           Plugin
         </span>
         </span>
       )}
       )}
-    </div>
+    </button>
   );
   );
 };
 };

+ 4 - 0
apps/app/src/client/components/Admin/Notification/GlobalNotification.jsx

@@ -42,6 +42,7 @@ const GlobalNotification = (props) => {
       <p className="card custom-card bg-body-tertiary">
       <p className="card custom-card bg-body-tertiary">
         {/* eslint-disable-next-line react/no-danger */}
         {/* eslint-disable-next-line react/no-danger */}
         <span
         <span
+          // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('notification_settings.link_notification_help'),
             __html: t('notification_settings.link_notification_help'),
           }}
           }}
@@ -68,6 +69,7 @@ const GlobalNotification = (props) => {
             >
             >
               {/* eslint-disable-next-line react/no-danger */}
               {/* eslint-disable-next-line react/no-danger */}
               <span
               <span
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('notification_settings.just_me_notification_help'),
                   __html: t('notification_settings.just_me_notification_help'),
                 }}
                 }}
@@ -98,6 +100,7 @@ const GlobalNotification = (props) => {
             >
             >
               {/* eslint-disable-next-line react/no-danger */}
               {/* eslint-disable-next-line react/no-danger */}
               <span
               <span
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('notification_settings.group_notification_help'),
                   __html: t('notification_settings.group_notification_help'),
                 }}
                 }}
@@ -137,6 +140,7 @@ const GlobalNotification = (props) => {
             <th>
             <th>
               {t('notification_settings.trigger_path')}{' '}
               {t('notification_settings.trigger_path')}{' '}
               <span
               <span
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('notification_settings.trigger_path_help'),
                   __html: t('notification_settings.trigger_path_help'),
                 }}
                 }}

+ 4 - 5
apps/app/src/client/components/Admin/Notification/GlobalNotificationList.jsx

@@ -105,7 +105,9 @@ class GlobalNotificationList extends React.Component {
                   <label
                   <label
                     className="form-label form-check-label"
                     className="form-label form-check-label"
                     htmlFor={notification._id}
                     htmlFor={notification._id}
-                  />
+                  >
+                    <span className="visually-hidden">{t('Enable')}</span>
+                  </label>
                 </div>
                 </div>
               </td>
               </td>
               <td>{notification.triggerPath}</td>
               <td>{notification.triggerPath}</td>
@@ -175,10 +177,7 @@ class GlobalNotificationList extends React.Component {
                     <span className="material-symbols-outlined">settings</span>{' '}
                     <span className="material-symbols-outlined">settings</span>{' '}
                     <span className="caret"></span>
                     <span className="caret"></span>
                   </button>
                   </button>
-                  <div
-                    className="dropdown-menu dropdown-menu-right"
-                    aria-labelledby="dropdownMenuButton"
-                  >
+                  <div className="dropdown-menu dropdown-menu-right">
                     <a
                     <a
                       className="dropdown-item"
                       className="dropdown-item"
                       href={urljoin(
                       href={urljoin(

+ 5 - 2
apps/app/src/client/components/Admin/Notification/ManageGlobalNotification.tsx

@@ -71,8 +71,8 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
   }, [notExistsGlobalNotification, router]);
   }, [notExistsGlobalNotification, router]);
 
 
   const onChangeTriggerEvents = useCallback(
   const onChangeTriggerEvents = useCallback(
-    (triggerEvent) => {
-      let newTriggerEvents;
+    (triggerEvent: string) => {
+      let newTriggerEvents: string[];
 
 
       if (triggerEvents.has(triggerEvent)) {
       if (triggerEvents.has(triggerEvent)) {
         newTriggerEvents = [...triggerEvents].filter(
         newTriggerEvents = [...triggerEvents].filter(
@@ -150,6 +150,7 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
               {t('notification_settings.trigger_path')}
               {t('notification_settings.trigger_path')}
               {/* eslint-disable-next-line react/no-danger */}
               {/* eslint-disable-next-line react/no-danger */}
               <small
               <small
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t(
                   __html: t(
                     'notification_settings.trigger_path_help',
                     'notification_settings.trigger_path_help',
@@ -233,6 +234,7 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
                 {!isMailerSetup && (
                 {!isMailerSetup && (
                   <span
                   <span
                     className="form-text text-muted"
                     className="form-text text-muted"
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('admin:mailer_setup_required'),
                       __html: t('admin:mailer_setup_required'),
                     }}
                     }}
@@ -270,6 +272,7 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
               <p className="p-2">
               <p className="p-2">
                 {/* eslint-disable-next-line react/no-danger */}
                 {/* eslint-disable-next-line react/no-danger */}
                 <span
                 <span
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('notification_settings.channel_desc'),
                     __html: t('notification_settings.channel_desc'),
                   }}
                   }}

+ 18 - 14
apps/app/src/client/components/Admin/Notification/NotificationSetting.jsx

@@ -1,4 +1,4 @@
-import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
 import { SlackbotType } from '@growi/slack';
 import { SlackbotType } from '@growi/slack';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
@@ -18,6 +18,21 @@ const logger = loggerFactory('growi:NotificationSetting');
 
 
 let retrieveErrors = null;
 let retrieveErrors = null;
 
 
+const SettingsIcon = () => (
+  <span className="material-symbols-outlined">settings</span>
+);
+
+const navTabMapping = {
+  user_trigger_notification: {
+    Icon: SettingsIcon,
+    i18n: 'User trigger notification',
+  },
+  global_notification: {
+    Icon: SettingsIcon,
+    i18n: 'Global notification',
+  },
+};
+
 // eslint-disable-next-line react/prop-types
 // eslint-disable-next-line react/prop-types
 const Badge = ({ isEnabled }) => {
 const Badge = ({ isEnabled }) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
@@ -65,6 +80,7 @@ const SlackIntegrationListItem = ({ isEnabled, currentBotType }) => {
         <ul className="mt-2 ps-4">
         <ul className="mt-2 ps-4">
           {/* eslint-disable-next-line react/no-danger */}
           {/* eslint-disable-next-line react/no-danger */}
           <li
           <li
+            // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
               __html: t('external_notification.caution_enabled'),
               __html: t('external_notification.caution_enabled'),
             }}
             }}
@@ -93,6 +109,7 @@ const LegacySlackIntegrationListItem = ({ isEnabled }) => {
             {/* eslint-disable-next-line react/no-danger */}
             {/* eslint-disable-next-line react/no-danger */}
             <span
             <span
               className="text-danger"
               className="text-danger"
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t('slack_integration_legacy.alert_deplicated'),
                 __html: t('slack_integration_legacy.alert_deplicated'),
               }}
               }}
@@ -137,19 +154,6 @@ function NotificationSetting(props) {
     fetchData();
     fetchData();
   }, [fetchData]);
   }, [fetchData]);
 
 
-  const navTabMapping = useMemo(() => {
-    return {
-      user_trigger_notification: {
-        Icon: () => <span className="material-symbols-outlined">settings</span>,
-        i18n: 'User trigger notification',
-      },
-      global_notification: {
-        Icon: () => <span className="material-symbols-outlined">settings</span>,
-        i18n: 'Global notification',
-      },
-    };
-  }, []);
-
   const { isSlackbotConfigured, isSlackLegacyConfigured, currentBotType } =
   const { isSlackbotConfigured, isSlackLegacyConfigured, currentBotType } =
     adminNotificationContainer.state;
     adminNotificationContainer.state;
   const isSlackEnabled = isSlackbotConfigured;
   const isSlackEnabled = isSlackbotConfigured;

+ 2 - 0
apps/app/src/client/components/Admin/Notification/UserTriggerNotification.jsx

@@ -115,6 +115,7 @@ class UserTriggerNotification extends React.Component {
                 <p className="p-2 mb-0">
                 <p className="p-2 mb-0">
                   {/* eslint-disable-next-line react/no-danger */}
                   {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('notification_settings.pattern_desc'),
                       __html: t('notification_settings.pattern_desc'),
                     }}
                     }}
@@ -143,6 +144,7 @@ class UserTriggerNotification extends React.Component {
                 <p className="p-2 mb-0">
                 <p className="p-2 mb-0">
                   {/* eslint-disable-next-line react/no-danger */}
                   {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('notification_settings.channel_desc'),
                       __html: t('notification_settings.channel_desc'),
                     }}
                     }}

+ 1 - 1
apps/app/src/client/components/Admin/Security/GitHubSecuritySetting.jsx

@@ -22,7 +22,7 @@ const GitHubSecurityManagement = (props) => {
 
 
   useEffect(() => {
   useEffect(() => {
     fetchGitHubSecuritySettingsData();
     fetchGitHubSecuritySettingsData();
-  }, [adminGitHubSecurityContainer, fetchGitHubSecuritySettingsData]);
+  }, [fetchGitHubSecuritySettingsData]);
 
 
   return <GitHubSecuritySettingContents />;
   return <GitHubSecuritySettingContents />;
 };
 };

+ 22 - 7
apps/app/src/client/components/Admin/Security/GitHubSecuritySettingContents.tsx

@@ -108,11 +108,15 @@ const GitHubSecurityManagementContents = (props: Props) => {
         </div>
         </div>
 
 
         <div className="row mb-4">
         <div className="row mb-4">
-          <label className="form-label col-12 col-md-3 text-start text-md-end py-2">
+          <label
+            className="form-label col-12 col-md-3 text-start text-md-end py-2"
+            htmlFor="gitHubCallbackUrl"
+          >
             {t('security_settings.callback_URL')}
             {t('security_settings.callback_URL')}
           </label>
           </label>
           <div className="col-12 col-md-6">
           <div className="col-12 col-md-6">
             <input
             <input
+              id="gitHubCallbackUrl"
               className="form-control"
               className="form-control"
               type="text"
               type="text"
               value={gitHubCallbackUrl}
               value={gitHubCallbackUrl}
@@ -127,6 +131,7 @@ const GitHubSecurityManagementContents = (props: Props) => {
               <div className="alert alert-danger">
               <div className="alert alert-danger">
                 <span className="material-symbols-outlined">error</span>
                 <span className="material-symbols-outlined">error</span>
                 <span // eslint-disable-next-line max-len
                 <span // eslint-disable-next-line max-len
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('alert.siteUrl_is_not_set', {
                     __html: t('alert.siteUrl_is_not_set', {
                       link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
                       link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
@@ -160,6 +165,7 @@ const GitHubSecurityManagementContents = (props: Props) => {
                 />
                 />
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
                   <small
                   <small
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('security_settings.Use env var if empty', {
                       __html: t('security_settings.Use env var if empty', {
                         env: 'OAUTH_GITHUB_CLIENT_ID',
                         env: 'OAUTH_GITHUB_CLIENT_ID',
@@ -185,6 +191,7 @@ const GitHubSecurityManagementContents = (props: Props) => {
                 />
                 />
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
                   <small
                   <small
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('security_settings.Use env var if empty', {
                       __html: t('security_settings.Use env var if empty', {
                         env: 'OAUTH_GITHUB_CLIENT_SECRET',
                         env: 'OAUTH_GITHUB_CLIENT_SECRET',
@@ -213,15 +220,20 @@ const GitHubSecurityManagementContents = (props: Props) => {
                   <label
                   <label
                     className="form-check-label"
                     className="form-check-label"
                     htmlFor="bindByUserNameGitHub"
                     htmlFor="bindByUserNameGitHub"
-                    dangerouslySetInnerHTML={{
-                      __html: t(
-                        'security_settings.Treat email matching as identical',
-                      ),
-                    }}
-                  />
+                  >
+                    <span
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                      dangerouslySetInnerHTML={{
+                        __html: t(
+                          'security_settings.Treat email matching as identical',
+                        ),
+                      }}
+                    />
+                  </label>
                 </div>
                 </div>
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
                   <small
                   <small
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'security_settings.Treat email matching as identical_warn',
                         'security_settings.Treat email matching as identical_warn',
@@ -262,6 +274,7 @@ const GitHubSecurityManagementContents = (props: Props) => {
             <ol id="collapseHelpForGitHubOauth" className="collapse mb-0">
             <ol id="collapseHelpForGitHubOauth" className="collapse mb-0">
               {/* eslint-disable-next-line max-len */}
               {/* eslint-disable-next-line max-len */}
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.GitHub.register_1', {
                   __html: t('security_settings.OAuth.GitHub.register_1', {
                     link: '<a href="https://github.com/settings/developers" target=_blank>GitHub Developer Settings</a>',
                     link: '<a href="https://github.com/settings/developers" target=_blank>GitHub Developer Settings</a>',
@@ -269,6 +282,7 @@ const GitHubSecurityManagementContents = (props: Props) => {
                 }}
                 }}
               />
               />
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.GitHub.register_2', {
                   __html: t('security_settings.OAuth.GitHub.register_2', {
                     url: gitHubCallbackUrl,
                     url: gitHubCallbackUrl,
@@ -276,6 +290,7 @@ const GitHubSecurityManagementContents = (props: Props) => {
                 }}
                 }}
               />
               />
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.GitHub.register_3'),
                   __html: t('security_settings.OAuth.GitHub.register_3'),
                 }}
                 }}

+ 1 - 1
apps/app/src/client/components/Admin/Security/GoogleSecuritySetting.jsx

@@ -22,7 +22,7 @@ const GoogleSecurityManagement = (props) => {
 
 
   useEffect(() => {
   useEffect(() => {
     fetchGoogleSecuritySettingsData();
     fetchGoogleSecuritySettingsData();
-  }, [adminGoogleSecurityContainer, fetchGoogleSecuritySettingsData]);
+  }, [fetchGoogleSecuritySettingsData]);
 
 
   return <GoogleSecurityManagementContents />;
   return <GoogleSecurityManagementContents />;
 };
 };

+ 24 - 7
apps/app/src/client/components/Admin/Security/GoogleSecuritySettingContents.tsx

@@ -108,11 +108,15 @@ const GoogleSecurityManagementContents = (props: Props) => {
         </div>
         </div>
 
 
         <div className="row mb-5">
         <div className="row mb-5">
-          <label className="form-label col-12 col-md-3 text-start text-md-end py-2">
+          <label
+            className="form-label col-12 col-md-3 text-start text-md-end py-2"
+            htmlFor="googleCallbackUrl"
+          >
             {t('security_settings.callback_URL')}
             {t('security_settings.callback_URL')}
           </label>
           </label>
           <div className="col-12 col-md-6">
           <div className="col-12 col-md-6">
             <input
             <input
+              id="googleCallbackUrl"
               className="form-control"
               className="form-control"
               type="text"
               type="text"
               value={googleCallbackUrl}
               value={googleCallbackUrl}
@@ -128,6 +132,7 @@ const GoogleSecurityManagementContents = (props: Props) => {
                 <span className="material-symbols-outlined">error</span>
                 <span className="material-symbols-outlined">error</span>
                 <span
                 <span
                   // eslint-disable-next-line max-len
                   // eslint-disable-next-line max-len
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('alert.siteUrl_is_not_set', {
                     __html: t('alert.siteUrl_is_not_set', {
                       link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
                       link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
@@ -161,6 +166,7 @@ const GoogleSecurityManagementContents = (props: Props) => {
                 />
                 />
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
                   <small
                   <small
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('security_settings.Use env var if empty', {
                       __html: t('security_settings.Use env var if empty', {
                         env: 'OAUTH_GOOGLE_CLIENT_ID',
                         env: 'OAUTH_GOOGLE_CLIENT_ID',
@@ -186,6 +192,7 @@ const GoogleSecurityManagementContents = (props: Props) => {
                 />
                 />
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
                   <small
                   <small
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('security_settings.Use env var if empty', {
                       __html: t('security_settings.Use env var if empty', {
                         env: 'OAUTH_GOOGLE_CLIENT_SECRET',
                         env: 'OAUTH_GOOGLE_CLIENT_SECRET',
@@ -214,15 +221,20 @@ const GoogleSecurityManagementContents = (props: Props) => {
                   <label
                   <label
                     className="form-check-label"
                     className="form-check-label"
                     htmlFor="bindByUserNameGoogle"
                     htmlFor="bindByUserNameGoogle"
-                    dangerouslySetInnerHTML={{
-                      __html: t(
-                        'security_settings.Treat email matching as identical',
-                      ),
-                    }}
-                  />
+                  >
+                    <span
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                      dangerouslySetInnerHTML={{
+                        __html: t(
+                          'security_settings.Treat email matching as identical',
+                        ),
+                      }}
+                    />
+                  </label>
                 </div>
                 </div>
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
                   <small
                   <small
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'security_settings.Treat email matching as identical_warn',
                         'security_settings.Treat email matching as identical_warn',
@@ -263,6 +275,7 @@ const GoogleSecurityManagementContents = (props: Props) => {
             <ol id="collapseHelpForGoogleOauth" className="collapse mb-0">
             <ol id="collapseHelpForGoogleOauth" className="collapse mb-0">
               {/* eslint-disable-next-line max-len */}
               {/* eslint-disable-next-line max-len */}
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.Google.register_1', {
                   __html: t('security_settings.OAuth.Google.register_1', {
                     link: '<a href="https://console.cloud.google.com/apis/credentials" target=_blank>Google Cloud Platform API Manager</a>',
                     link: '<a href="https://console.cloud.google.com/apis/credentials" target=_blank>Google Cloud Platform API Manager</a>',
@@ -270,16 +283,19 @@ const GoogleSecurityManagementContents = (props: Props) => {
                 }}
                 }}
               />
               />
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.Google.register_2'),
                   __html: t('security_settings.OAuth.Google.register_2'),
                 }}
                 }}
               />
               />
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.Google.register_3'),
                   __html: t('security_settings.OAuth.Google.register_3'),
                 }}
                 }}
               />
               />
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.Google.register_4', {
                   __html: t('security_settings.OAuth.Google.register_4', {
                     url: googleCallbackUrl,
                     url: googleCallbackUrl,
@@ -287,6 +303,7 @@ const GoogleSecurityManagementContents = (props: Props) => {
                 }}
                 }}
               />
               />
               <li
               <li
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.OAuth.Google.register_5'),
                   __html: t('security_settings.OAuth.Google.register_5'),
                 }}
                 }}

+ 1 - 3
apps/app/src/client/components/Admin/Security/LdapAuthTest.tsx

@@ -125,9 +125,7 @@ export const LdapAuthTest = (props: LdapAuthTestProps): JSX.Element => {
       </div>
       </div>
 
 
       <div className="mt-4">
       <div className="mt-4">
-        <label className="form-label">
-          <h5>Logs</h5>
-        </label>
+        <h5 className="form-label">Logs</h5>
         <textarea
         <textarea
           id="taLogs"
           id="taLogs"
           className="col form-control"
           className="col form-control"

+ 1 - 1
apps/app/src/client/components/Admin/Security/LdapSecuritySetting.jsx

@@ -22,7 +22,7 @@ const LdapSecuritySetting = (props) => {
 
 
   useEffect(() => {
   useEffect(() => {
     fetchLdapSecuritySettingsData();
     fetchLdapSecuritySettingsData();
-  }, [adminLdapSecurityContainer, fetchLdapSecuritySettingsData]);
+  }, [fetchLdapSecuritySettingsData]);
 
 
   return <LdapSecuritySettingContents />;
   return <LdapSecuritySettingContents />;
 };
 };

+ 36 - 15
apps/app/src/client/components/Admin/Security/LdapSecuritySettingContents.tsx

@@ -158,6 +158,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                 <p
                 <p
                   className="form-text text-muted"
                   className="form-text text-muted"
                   // eslint-disable-next-line react/no-danger
                   // eslint-disable-next-line react/no-danger
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.ldap.server_url_detail'),
                     __html: t('security_settings.ldap.server_url_detail'),
                   }}
                   }}
@@ -171,9 +172,9 @@ const LdapSecuritySettingContents = (props: Props) => {
           </div>
           </div>
 
 
           <div className="row my-3">
           <div className="row my-3">
-            <label className="form-label text-start text-md-end col-md-3 col-form-label">
+            <span className="form-label text-start text-md-end col-md-3 col-form-label">
               <strong>{t('security_settings.ldap.bind_mode')}</strong>
               <strong>{t('security_settings.ldap.bind_mode')}</strong>
-            </label>
+            </span>
             <div className="col-md-9">
             <div className="col-md-9">
               <div className="dropdown">
               <div className="dropdown">
                 <button
                 <button
@@ -194,10 +195,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                     </span>
                     </span>
                   )}
                   )}
                 </button>
                 </button>
-                <div
-                  className="dropdown-menu"
-                  aria-labelledby="dropdownMenuButton"
-                >
+                <div className="dropdown-menu">
                   <button
                   <button
                     className="dropdown-item"
                     className="dropdown-item"
                     type="button"
                     type="button"
@@ -222,11 +220,15 @@ const LdapSecuritySettingContents = (props: Props) => {
           </div>
           </div>
 
 
           <div className="row my-3">
           <div className="row my-3">
-            <label className="form-label text-start text-md-end col-md-3 col-form-label">
+            <label
+              className="form-label text-start text-md-end col-md-3 col-form-label"
+              htmlFor="ldapBindDN"
+            >
               <strong>Bind DN</strong>
               <strong>Bind DN</strong>
             </label>
             </label>
             <div className="col-md-9">
             <div className="col-md-9">
               <input
               <input
+                id="ldapBindDN"
                 className="form-control"
                 className="form-control"
                 type="text"
                 type="text"
                 {...register('ldapBindDN')}
                 {...register('ldapBindDN')}
@@ -238,6 +240,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                     <br />
                     <br />
                     {/* eslint-disable-next-line react/no-danger */}
                     {/* eslint-disable-next-line react/no-danger */}
                     <span
                     <span
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.ldap.bind_DN_user_detail2',
                           'security_settings.ldap.bind_DN_user_detail2',
@@ -302,11 +305,15 @@ const LdapSecuritySettingContents = (props: Props) => {
           </div>
           </div>
 
 
           <div className="row my-3">
           <div className="row my-3">
-            <label className="form-label text-start text-md-end col-md-3 col-form-label">
+            <label
+              className="form-label text-start text-md-end col-md-3 col-form-label"
+              htmlFor="ldapSearchFilter"
+            >
               <strong>{t('security_settings.ldap.search_filter')}</strong>
               <strong>{t('security_settings.ldap.search_filter')}</strong>
             </label>
             </label>
             <div className="col-md-9">
             <div className="col-md-9">
               <input
               <input
+                id="ldapSearchFilter"
                 className="form-control"
                 className="form-control"
                 type="text"
                 type="text"
                 {...register('ldapSearchFilter')}
                 {...register('ldapSearchFilter')}
@@ -317,6 +324,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                   <br />
                   <br />
                   {/* eslint-disable-next-line react/no-danger */}
                   {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('security_settings.ldap.search_filter_detail2'),
                       __html: t('security_settings.ldap.search_filter_detail2'),
                     }}
                     }}
@@ -324,6 +332,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                   <br />
                   <br />
                   {/* eslint-disable-next-line react/no-danger */}
                   {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('security_settings.ldap.search_filter_detail3'),
                       __html: t('security_settings.ldap.search_filter_detail3'),
                     }}
                     }}
@@ -367,6 +376,7 @@ const LdapSecuritySettingContents = (props: Props) => {
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 {/* eslint-disable-next-line react/no-danger */}
                 {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.ldap.username_detail'),
                     __html: t('security_settings.ldap.username_detail'),
                   }}
                   }}
@@ -393,17 +403,22 @@ const LdapSecuritySettingContents = (props: Props) => {
                 <label
                 <label
                   className="form-check-label"
                   className="form-check-label"
                   htmlFor="isSameUsernameTreatedAsIdenticalUser"
                   htmlFor="isSameUsernameTreatedAsIdenticalUser"
-                  // eslint-disable-next-line react/no-danger
-                  dangerouslySetInnerHTML={{
-                    __html: t(
-                      'security_settings.Treat username matching as identical',
-                    ),
-                  }}
-                />
+                >
+                  <span
+                    // eslint-disable-next-line react/no-danger
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                    dangerouslySetInnerHTML={{
+                      __html: t(
+                        'security_settings.Treat username matching as identical',
+                      ),
+                    }}
+                  />
+                </label>
               </div>
               </div>
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 {/* eslint-disable-next-line react/no-danger */}
                 {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.Treat username matching as identical_warn',
                       'security_settings.Treat username matching as identical_warn',
@@ -476,6 +491,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                 <small>
                 <small>
                   {/* eslint-disable-next-line react/no-danger */}
                   {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'security_settings.ldap.group_search_base_DN_detail',
                         'security_settings.ldap.group_search_base_DN_detail',
@@ -507,6 +523,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                 <small>
                 <small>
                   {/* eslint-disable react/no-danger */}
                   {/* eslint-disable react/no-danger */}
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'security_settings.ldap.group_search_filter_detail1',
                         'security_settings.ldap.group_search_filter_detail1',
@@ -515,6 +532,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                   />
                   />
                   <br />
                   <br />
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'security_settings.ldap.group_search_filter_detail2',
                         'security_settings.ldap.group_search_filter_detail2',
@@ -523,6 +541,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                   />
                   />
                   <br />
                   <br />
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'security_settings.ldap.group_search_filter_detail3',
                         'security_settings.ldap.group_search_filter_detail3',
@@ -537,6 +556,7 @@ const LdapSecuritySettingContents = (props: Props) => {
                   {t('security_settings.example')}:
                   {t('security_settings.example')}:
                   {/* eslint-disable-next-line react/no-danger */}
                   {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
                         'security_settings.ldap.group_search_filter_detail4',
                         'security_settings.ldap.group_search_filter_detail4',
@@ -567,6 +587,7 @@ const LdapSecuritySettingContents = (props: Props) => {
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 {/* eslint-disable-next-line react/no-danger */}
                 {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.ldap.group_search_user_DN_property_detail',
                       'security_settings.ldap.group_search_user_DN_property_detail',

+ 1 - 1
apps/app/src/client/components/Admin/Security/LocalSecuritySetting.jsx

@@ -22,7 +22,7 @@ const LocalSecuritySetting = (props) => {
 
 
   useEffect(() => {
   useEffect(() => {
     fetchLocalSecuritySettingsData();
     fetchLocalSecuritySettingsData();
-  }, [adminLocalSecurityContainer, fetchLocalSecuritySettingsData]);
+  }, [fetchLocalSecuritySettingsData]);
 
 
   return <LocalSecuritySettingContents />;
   return <LocalSecuritySettingContents />;
 };
 };

+ 7 - 8
apps/app/src/client/components/Admin/Security/LocalSecuritySettingContents.tsx

@@ -76,6 +76,7 @@ const LocalSecuritySettingContents = (props: Props): JSX.Element => {
         <p
         <p
           className="alert alert-info"
           className="alert alert-info"
           // eslint-disable-next-line max-len
           // eslint-disable-next-line max-len
+          // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('security_settings.Local.note for the only env option', {
             __html: t('security_settings.Local.note for the only env option', {
               env: 'LOCAL_STRATEGY_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS',
               env: 'LOCAL_STRATEGY_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS',
@@ -142,10 +143,7 @@ const LocalSecuritySettingContents = (props: Props): JSX.Element => {
                   {registrationMode === 'Closed' &&
                   {registrationMode === 'Closed' &&
                     t('security_settings.registration_mode.closed')}
                     t('security_settings.registration_mode.closed')}
                 </button>
                 </button>
-                <div
-                  className="dropdown-menu"
-                  aria-labelledby="dropdownMenuButton"
-                >
+                <div className="dropdown-menu">
                   <button
                   <button
                     className="dropdown-item"
                     className="dropdown-item"
                     type="button"
                     type="button"
@@ -189,6 +187,7 @@ const LocalSecuritySettingContents = (props: Props): JSX.Element => {
           <div className="row">
           <div className="row">
             <div className="col-12 col-md-4 text-start text-md-end">
             <div className="col-12 col-md-4 text-start text-md-end">
               <strong
               <strong
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t(
                   __html: t(
                     'security_settings.The whitelist of registration permission E-mail address',
                     'security_settings.The whitelist of registration permission E-mail address',
@@ -214,9 +213,9 @@ const LocalSecuritySettingContents = (props: Props): JSX.Element => {
           </div>
           </div>
 
 
           <div className="row">
           <div className="row">
-            <label className="col-12 col-md-4 text-start text-md-end  col-form-label">
+            <span className="col-12 col-md-4 text-start text-md-end col-form-label">
               {t('security_settings.Local.password_reset_by_users')}
               {t('security_settings.Local.password_reset_by_users')}
-            </label>
+            </span>
             <div className="col-12 col-md-8">
             <div className="col-12 col-md-8">
               <div className="form-check form-switch form-check-success">
               <div className="form-check form-switch form-check-success">
                 <input
                 <input
@@ -253,9 +252,9 @@ const LocalSecuritySettingContents = (props: Props): JSX.Element => {
           </div>
           </div>
 
 
           <div className="row">
           <div className="row">
-            <label className="col-12 col-md-4 text-start text-md-end  col-form-label">
+            <span className="col-12 col-md-4 text-start text-md-end col-form-label">
               {t('security_settings.Local.email_authentication')}
               {t('security_settings.Local.email_authentication')}
-            </label>
+            </span>
             <div className="col-12 col-md-8">
             <div className="col-12 col-md-8">
               <div className="form-check form-switch form-check-success">
               <div className="form-check form-switch form-check-success">
                 <input
                 <input

+ 1 - 1
apps/app/src/client/components/Admin/Security/OidcSecuritySetting.jsx

@@ -22,7 +22,7 @@ const OidcSecurityManagement = (props) => {
 
 
   useEffect(() => {
   useEffect(() => {
     fetchOidcSecuritySettingsData();
     fetchOidcSecuritySettingsData();
-  }, [adminOidcSecurityContainer, fetchOidcSecuritySettingsData]);
+  }, [fetchOidcSecuritySettingsData]);
 
 
   return <OidcSecurityManagementContents />;
   return <OidcSecurityManagementContents />;
 };
 };

+ 50 - 14
apps/app/src/client/components/Admin/Security/OidcSecuritySettingContents.tsx

@@ -159,11 +159,15 @@ const OidcSecurityManagementContents = (props: Props) => {
       </div>
       </div>
 
 
       <div className="row mb-5">
       <div className="row mb-5">
-        <label className="text-start text-md-end col-md-3 col-form-label">
+        <label
+          className="text-start text-md-end col-md-3 col-form-label"
+          htmlFor="oidcCallbackUrl"
+        >
           {t('security_settings.callback_URL')}
           {t('security_settings.callback_URL')}
         </label>
         </label>
         <div className="col-md-6">
         <div className="col-md-6">
           <input
           <input
+            id="oidcCallbackUrl"
             className="form-control"
             className="form-control"
             type="text"
             type="text"
             value={oidcCallbackUrl}
             value={oidcCallbackUrl}
@@ -177,6 +181,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               <span className="material-symbols-outlined">error</span>
               <span className="material-symbols-outlined">error</span>
               <span
               <span
                 // eslint-disable-next-line max-len
                 // eslint-disable-next-line max-len
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('alert.siteUrl_is_not_set', {
                   __html: t('alert.siteUrl_is_not_set', {
                     link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
                     link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
@@ -226,6 +231,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.Use env var if empty', {
                     __html: t('security_settings.Use env var if empty', {
                       env: 'OAUTH_OIDC_ISSUER_HOST',
                       env: 'OAUTH_OIDC_ISSUER_HOST',
@@ -251,6 +257,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.Use env var if empty', {
                     __html: t('security_settings.Use env var if empty', {
                       env: 'OAUTH_OIDC_CLIENT_ID',
                       env: 'OAUTH_OIDC_CLIENT_ID',
@@ -276,6 +283,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.Use env var if empty', {
                     __html: t('security_settings.Use env var if empty', {
                       env: 'OAUTH_OIDC_CLIENT_SECRET',
                       env: 'OAUTH_OIDC_CLIENT_SECRET',
@@ -301,6 +309,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -326,6 +335,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -351,6 +361,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -376,6 +387,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -401,6 +413,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -426,6 +439,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -451,6 +465,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -476,6 +491,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
                       'security_settings.OAuth.OIDC.Use discovered URL if empty',
@@ -505,6 +521,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.OAuth.OIDC.id_detail'),
                     __html: t('security_settings.OAuth.OIDC.id_detail'),
                   }}
                   }}
@@ -528,6 +545,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.OAuth.OIDC.username_detail'),
                     __html: t('security_settings.OAuth.OIDC.username_detail'),
                   }}
                   }}
@@ -551,6 +569,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.OAuth.OIDC.name_detail'),
                     __html: t('security_settings.OAuth.OIDC.name_detail'),
                   }}
                   }}
@@ -574,6 +593,7 @@ const OidcSecurityManagementContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.OAuth.OIDC.mapping_detail', {
                     __html: t('security_settings.OAuth.OIDC.mapping_detail', {
                       target: t('Email'),
                       target: t('Email'),
@@ -585,11 +605,15 @@ const OidcSecurityManagementContents = (props: Props) => {
           </div>
           </div>
 
 
           <div className="row mb-4">
           <div className="row mb-4">
-            <label className="form-label text-start text-md-end col-md-3 col-form-label">
+            <label
+              className="form-label text-start text-md-end col-md-3 col-form-label"
+              htmlFor="oidcCallbackUrlPreview"
+            >
               {t('security_settings.callback_URL')}
               {t('security_settings.callback_URL')}
             </label>
             </label>
             <div className="col-md-6">
             <div className="col-md-6">
               <input
               <input
+                id="oidcCallbackUrlPreview"
                 className="form-control"
                 className="form-control"
                 type="text"
                 type="text"
                 defaultValue={oidcCallbackUrl}
                 defaultValue={oidcCallbackUrl}
@@ -605,6 +629,7 @@ const OidcSecurityManagementContents = (props: Props) => {
                   <span className="material-symbols-outlined">error</span>
                   <span className="material-symbols-outlined">error</span>
                   <span
                   <span
                     // eslint-disable-next-line max-len
                     // eslint-disable-next-line max-len
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('alert.siteUrl_is_not_set', {
                       __html: t('alert.siteUrl_is_not_set', {
                         link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
                         link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
@@ -635,15 +660,20 @@ const OidcSecurityManagementContents = (props: Props) => {
                 <label
                 <label
                   className="form-label form-check-label"
                   className="form-label form-check-label"
                   htmlFor="bindByUserName-oidc"
                   htmlFor="bindByUserName-oidc"
-                  dangerouslySetInnerHTML={{
-                    __html: t(
-                      'security_settings.Treat username matching as identical',
-                    ),
-                  }}
-                />
+                >
+                  <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                    dangerouslySetInnerHTML={{
+                      __html: t(
+                        'security_settings.Treat username matching as identical',
+                      ),
+                    }}
+                  />
+                </label>
               </div>
               </div>
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.Treat username matching as identical_warn',
                       'security_settings.Treat username matching as identical_warn',
@@ -672,15 +702,20 @@ const OidcSecurityManagementContents = (props: Props) => {
                 <label
                 <label
                   className="form-label form-check-label"
                   className="form-label form-check-label"
                   htmlFor="bindByEmail-oidc"
                   htmlFor="bindByEmail-oidc"
-                  dangerouslySetInnerHTML={{
-                    __html: t(
-                      'security_settings.Treat email matching as identical',
-                    ),
-                  }}
-                />
+                >
+                  <span
+                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                    dangerouslySetInnerHTML={{
+                      __html: t(
+                        'security_settings.Treat email matching as identical',
+                      ),
+                    }}
+                  />
+                </label>
               </div>
               </div>
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small
                 <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t(
                     __html: t(
                       'security_settings.Treat email matching as identical_warn',
                       'security_settings.Treat email matching as identical_warn',
@@ -723,6 +758,7 @@ const OidcSecurityManagementContents = (props: Props) => {
           <ol id="collapseHelpForOidcOauth" className="collapse mb-0">
           <ol id="collapseHelpForOidcOauth" className="collapse mb-0">
             <li>{t('security_settings.OAuth.OIDC.register_1')}</li>
             <li>{t('security_settings.OAuth.OIDC.register_1')}</li>
             <li
             <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t('security_settings.OAuth.OIDC.register_2', {
                 __html: t('security_settings.OAuth.OIDC.register_2', {
                   url: oidcCallbackUrl,
                   url: oidcCallbackUrl,

+ 1 - 1
apps/app/src/client/components/Admin/Security/SamlSecuritySetting.jsx

@@ -22,7 +22,7 @@ const SamlSecurityManagement = (props) => {
 
 
   useEffect(() => {
   useEffect(() => {
     fetchSamlSecuritySettingsData();
     fetchSamlSecuritySettingsData();
-  }, [adminSamlSecurityContainer, fetchSamlSecuritySettingsData]);
+  }, [fetchSamlSecuritySettingsData]);
 
 
   return <SamlSecuritySettingContents />;
   return <SamlSecuritySettingContents />;
 };
 };

+ 48 - 13
apps/app/src/client/components/Admin/Security/SamlSecuritySettingContents.tsx

@@ -94,6 +94,7 @@ const SamlSecurityManagementContents = (props: Props) => {
       {useOnlyEnvVars && (
       {useOnlyEnvVars && (
         <p
         <p
           className="alert alert-info"
           className="alert alert-info"
+          // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('security_settings.SAML.note for the only env option', {
             __html: t('security_settings.SAML.note for the only env option', {
               env: 'SAML_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS',
               env: 'SAML_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS',
@@ -134,11 +135,15 @@ const SamlSecurityManagementContents = (props: Props) => {
       </div>
       </div>
 
 
       <div className="row mb-5">
       <div className="row mb-5">
-        <label className="text-start text-md-end col-md-3 col-form-label">
+        <label
+          className="text-start text-md-end col-md-3 col-form-label"
+          htmlFor="samlCallbackUrl"
+        >
           {t('security_settings.callback_URL')}
           {t('security_settings.callback_URL')}
         </label>
         </label>
         <div className="col-md-6">
         <div className="col-md-6">
           <input
           <input
+            id="samlCallbackUrl"
             className="form-control"
             className="form-control"
             type="text"
             type="text"
             defaultValue={samlCallbackUrl}
             defaultValue={samlCallbackUrl}
@@ -154,6 +159,7 @@ const SamlSecurityManagementContents = (props: Props) => {
               <span className="material-symbols-outlined">error</span>
               <span className="material-symbols-outlined">error</span>
               <span
               <span
                 // eslint-disable-next-line max-len
                 // eslint-disable-next-line max-len
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('alert.siteUrl_is_not_set', {
                   __html: t('alert.siteUrl_is_not_set', {
                     link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
                     link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
@@ -227,6 +233,7 @@ const SamlSecurityManagementContents = (props: Props) => {
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.SAML.Use env var if empty',
                           'security_settings.SAML.Use env var if empty',
@@ -256,6 +263,7 @@ const SamlSecurityManagementContents = (props: Props) => {
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.SAML.Use env var if empty',
                           'security_settings.SAML.Use env var if empty',
@@ -303,6 +311,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.SAML.Use env var if empty',
                           'security_settings.SAML.Use env var if empty',
@@ -355,6 +364,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.SAML.Use env var if empty',
                           'security_settings.SAML.Use env var if empty',
@@ -375,6 +385,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t('security_settings.SAML.username_detail'),
                         __html: t('security_settings.SAML.username_detail'),
                       }}
                       }}
@@ -392,6 +403,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.SAML.Use env var if empty',
                           'security_settings.SAML.Use env var if empty',
@@ -412,6 +424,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t('security_settings.SAML.mapping_detail', {
                         __html: t('security_settings.SAML.mapping_detail', {
                           target: 'Email',
                           target: 'Email',
@@ -431,6 +444,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.SAML.Use env var if empty',
                           'security_settings.SAML.Use env var if empty',
@@ -454,6 +468,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     {/* eslint-disable-next-line max-len */}
                     {/* eslint-disable-next-line max-len */}
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t('security_settings.SAML.mapping_detail', {
                         __html: t('security_settings.SAML.mapping_detail', {
                           target: t(
                           target: t(
@@ -476,6 +491,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small>
                     <small>
                       <span
                       <span
+                        // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                         dangerouslySetInnerHTML={{
                         dangerouslySetInnerHTML={{
                           __html: t(
                           __html: t(
                             'security_settings.SAML.Use env var if empty',
                             'security_settings.SAML.Use env var if empty',
@@ -485,6 +501,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                       />
                       />
                       <br />
                       <br />
                       <span
                       <span
+                        // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                         dangerouslySetInnerHTML={{
                         dangerouslySetInnerHTML={{
                           __html: t(
                           __html: t(
                             'security_settings.Use default if both are empty',
                             'security_settings.Use default if both are empty',
@@ -507,6 +524,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     {/* eslint-disable-next-line max-len */}
                     {/* eslint-disable-next-line max-len */}
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t('security_settings.SAML.mapping_detail', {
                         __html: t('security_settings.SAML.mapping_detail', {
                           target: t(
                           target: t(
@@ -529,6 +547,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small>
                     <small>
                       <span
                       <span
+                        // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                         dangerouslySetInnerHTML={{
                         dangerouslySetInnerHTML={{
                           __html: t(
                           __html: t(
                             'security_settings.SAML.Use env var if empty',
                             'security_settings.SAML.Use env var if empty',
@@ -538,6 +557,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                       />
                       />
                       <br />
                       <br />
                       <span
                       <span
+                        // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                         dangerouslySetInnerHTML={{
                         dangerouslySetInnerHTML={{
                           __html: t(
                           __html: t(
                             'security_settings.Use default if both are empty',
                             'security_settings.Use default if both are empty',
@@ -573,15 +593,20 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
               <label
               <label
                 className="form-label form-check-label"
                 className="form-label form-check-label"
                 htmlFor="bindByUserName-SAML"
                 htmlFor="bindByUserName-SAML"
-                dangerouslySetInnerHTML={{
-                  __html: t(
-                    'security_settings.Treat username matching as identical',
-                  ),
-                }}
-              />
+              >
+                <span
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t(
+                      'security_settings.Treat username matching as identical',
+                    ),
+                  }}
+                />
+              </label>
             </div>
             </div>
             <p className="form-text text-muted">
             <p className="form-text text-muted">
               <small
               <small
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t(
                   __html: t(
                     'security_settings.Treat username matching as identical_warn',
                     'security_settings.Treat username matching as identical_warn',
@@ -608,15 +633,20 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
               <label
               <label
                 className="form-label form-check-label"
                 className="form-label form-check-label"
                 htmlFor="bindByEmail-SAML"
                 htmlFor="bindByEmail-SAML"
-                dangerouslySetInnerHTML={{
-                  __html: t(
-                    'security_settings.Treat email matching as identical',
-                  ),
-                }}
-              />
+              >
+                <span
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t(
+                      'security_settings.Treat email matching as identical',
+                    ),
+                  }}
+                />
+              </label>
             </div>
             </div>
             <p className="form-text text-muted">
             <p className="form-text text-muted">
               <small
               <small
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t(
                   __html: t(
                     'security_settings.Treat email matching as identical_warn',
                     'security_settings.Treat email matching as identical_warn',
@@ -632,6 +662,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
 
 
           <p className="form-text text-muted">
           <p className="form-text text-muted">
             <small
             <small
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t(
                 __html: t(
                   'security_settings.SAML.attr_based_login_control_detail',
                   'security_settings.SAML.attr_based_login_control_detail',
@@ -695,6 +726,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                         <Collapse isOpen={isHelpOpened}>
                         <Collapse isOpen={isHelpOpened}>
                           <div className="accordion-body">
                           <div className="accordion-body">
                             <p
                             <p
+                              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                               dangerouslySetInnerHTML={{
                               dangerouslySetInnerHTML={{
                                 __html: t(
                                 __html: t(
                                   'security_settings.SAML.attr_based_login_control_rule_help',
                                   'security_settings.SAML.attr_based_login_control_rule_help',
@@ -702,6 +734,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                               }}
                               }}
                             />
                             />
                             <p
                             <p
+                              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                               dangerouslySetInnerHTML={{
                               dangerouslySetInnerHTML={{
                                 __html: t(
                                 __html: t(
                                   'security_settings.SAML.attr_based_login_control_rule_example1',
                                   'security_settings.SAML.attr_based_login_control_rule_example1',
@@ -709,6 +742,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                               }}
                               }}
                             />
                             />
                             <p
                             <p
+                              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                               dangerouslySetInnerHTML={{
                               dangerouslySetInnerHTML={{
                                 __html: t(
                                 __html: t(
                                   'security_settings.SAML.attr_based_login_control_rule_example2',
                                   'security_settings.SAML.attr_based_login_control_rule_example2',
@@ -729,6 +763,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
                     <small
                     <small
+                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
                         __html: t(
                         __html: t(
                           'security_settings.SAML.Use env var if empty',
                           'security_settings.SAML.Use env var if empty',

+ 1 - 1
apps/app/src/client/components/Admin/Security/SecurityManagement.tsx

@@ -25,7 +25,7 @@ const SecurityManagement = (props: Props) => {
 
 
   useEffect(() => {
   useEffect(() => {
     fetchGeneralSecuritySettingsData();
     fetchGeneralSecuritySettingsData();
-  }, [adminGeneralSecurityContainer, fetchGeneralSecuritySettingsData]);
+  }, [fetchGeneralSecuritySettingsData]);
 
 
   return <SecurityManagementContents />;
   return <SecurityManagementContents />;
 };
 };

+ 47 - 36
apps/app/src/client/components/Admin/Security/SecurityManagementContents.jsx

@@ -1,4 +1,4 @@
-import React, { useMemo, useState } from 'react';
+import React, { useState } from 'react';
 import Link from 'next/link';
 import Link from 'next/link';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import { TabContent, TabPane } from 'reactstrap';
 import { TabContent, TabPane } from 'reactstrap';
@@ -13,6 +13,52 @@ import SamlSecuritySetting from './SamlSecuritySetting';
 import { SecuritySetting } from './SecuritySetting';
 import { SecuritySetting } from './SecuritySetting';
 import ShareLinkSetting from './ShareLinkSetting';
 import ShareLinkSetting from './ShareLinkSetting';
 
 
+const PassportLocalIcon = () => (
+  <span className="material-symbols-outlined">groups</span>
+);
+const PassportLdapIcon = () => (
+  <span className="material-symbols-outlined">network_node</span>
+);
+const PassportSamlIcon = () => (
+  <span className="material-symbols-outlined">key</span>
+);
+const PassportOidcIcon = () => (
+  <span className="material-symbols-outlined">key</span>
+);
+const PassportGoogleIcon = () => (
+  <span className="growi-custom-icons align-bottom">google</span>
+);
+const PassportGitHubIcon = () => (
+  <span className="growi-custom-icons align-bottom">github</span>
+);
+
+const navTabMapping = {
+  passport_local: {
+    Icon: PassportLocalIcon,
+    i18n: 'ID/Pass',
+  },
+  passport_ldap: {
+    Icon: PassportLdapIcon,
+    i18n: 'LDAP',
+  },
+  passport_saml: {
+    Icon: PassportSamlIcon,
+    i18n: 'SAML',
+  },
+  passport_oidc: {
+    Icon: PassportOidcIcon,
+    i18n: 'OIDC',
+  },
+  passport_google: {
+    Icon: PassportGoogleIcon,
+    i18n: 'Google',
+  },
+  passport_github: {
+    Icon: PassportGitHubIcon,
+    i18n: 'GitHub',
+  },
+};
+
 const SecurityManagementContents = () => {
 const SecurityManagementContents = () => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 
@@ -26,41 +72,6 @@ const SecurityManagementContents = () => {
     setActiveComponents(activeComponents.add(selectedTab));
     setActiveComponents(activeComponents.add(selectedTab));
   };
   };
 
 
-  const navTabMapping = useMemo(() => {
-    return {
-      passport_local: {
-        Icon: () => <span className="material-symbols-outlined">groups</span>,
-        i18n: 'ID/Pass',
-      },
-      passport_ldap: {
-        Icon: () => (
-          <span className="material-symbols-outlined">network_node</span>
-        ),
-        i18n: 'LDAP',
-      },
-      passport_saml: {
-        Icon: () => <span className="material-symbols-outlined">key</span>,
-        i18n: 'SAML',
-      },
-      passport_oidc: {
-        Icon: () => <span className="material-symbols-outlined">key</span>,
-        i18n: 'OIDC',
-      },
-      passport_google: {
-        Icon: () => (
-          <span className="growi-custom-icons align-bottom">google</span>
-        ),
-        i18n: 'Google',
-      },
-      passport_github: {
-        Icon: () => (
-          <span className="growi-custom-icons align-bottom">github</span>
-        ),
-        i18n: 'GitHub',
-      },
-    };
-  }, []);
-
   return (
   return (
     <div data-testid="admin-security">
     <div data-testid="admin-security">
       <div className="mb-5">
       <div className="mb-5">

+ 1 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting/CommentManageRightsSettings.tsx

@@ -39,7 +39,7 @@ export const CommentManageRightsSettings: React.FC<Props> = ({
                   t('security_settings.read_only_users_comment.deny')}
                   t('security_settings.read_only_users_comment.deny')}
               </span>
               </span>
             </button>
             </button>
-            <div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
+            <div className="dropdown-menu">
               <button
               <button
                 className="dropdown-item"
                 className="dropdown-item"
                 type="button"
                 type="button"

+ 2 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting/PageAccessRightsSettings.tsx

@@ -40,7 +40,7 @@ export const PageAccessRightsSettings: React.FC<Props> = ({
                   t('security_settings.guest_mode.readonly')}
                   t('security_settings.guest_mode.readonly')}
               </span>
               </span>
             </button>
             </button>
-            <div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
+            <div className="dropdown-menu">
               <button
               <button
                 className="dropdown-item"
                 className="dropdown-item"
                 type="button"
                 type="button"
@@ -70,6 +70,7 @@ export const PageAccessRightsSettings: React.FC<Props> = ({
               <br />
               <br />
               {/* eslint-disable-next-line react/no-danger */}
               {/* eslint-disable-next-line react/no-danger */}
               <b
               <b
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('security_settings.Fixed by env var', {
                   __html: t('security_settings.Fixed by env var', {
                     key: 'FORCE_WIKI_MODE',
                     key: 'FORCE_WIKI_MODE',

+ 2 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting/PageDeleteRightsSettings.tsx

@@ -172,7 +172,7 @@ export const PageDeleteRightsSettings: React.FC<Props> = ({
               {t(getDeleteConfigValueForT(currentState))}
               {t(getDeleteConfigValueForT(currentState))}
             </span>
             </span>
           </button>
           </button>
-          <div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
+          <div className="dropdown-menu">
             {isRecursiveDeletion(deletionType) ? (
             {isRecursiveDeletion(deletionType) ? (
               <button
               <button
                 className="dropdown-item"
                 className="dropdown-item"
@@ -332,6 +332,7 @@ export const PageDeleteRightsSettings: React.FC<Props> = ({
                         <span className="material-symbols-outlined">info</span>
                         <span className="material-symbols-outlined">info</span>
                         {/* eslint-disable-next-line react/no-danger */}
                         {/* eslint-disable-next-line react/no-danger */}
                         <span
                         <span
+                          // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                           dangerouslySetInnerHTML={{
                           dangerouslySetInnerHTML={{
                             __html: t(
                             __html: t(
                               'security_settings.page_delete_rights_caution',
                               'security_settings.page_delete_rights_caution',

+ 2 - 8
apps/app/src/client/components/Admin/Security/SecuritySetting/PageListDisplaySettings.tsx

@@ -58,10 +58,7 @@ export const PageListDisplaySettings: React.FC<Props> = ({
                         t('security_settings.always_hidden')}
                         t('security_settings.always_hidden')}
                     </span>
                     </span>
                   </button>
                   </button>
-                  <div
-                    className="dropdown-menu"
-                    aria-labelledby="isShowRestrictedByOwner"
-                  >
+                  <div className="dropdown-menu">
                     <button
                     <button
                       className="dropdown-item"
                       className="dropdown-item"
                       type="button"
                       type="button"
@@ -108,10 +105,7 @@ export const PageListDisplaySettings: React.FC<Props> = ({
                         t('security_settings.always_hidden')}
                         t('security_settings.always_hidden')}
                     </span>
                     </span>
                   </button>
                   </button>
-                  <div
-                    className="dropdown-menu"
-                    aria-labelledby="isShowRestrictedByGroup"
-                  >
+                  <div className="dropdown-menu">
                     <button
                     <button
                       className="dropdown-item"
                       className="dropdown-item"
                       type="button"
                       type="button"

+ 6 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting/SessionMaxAgeSettings.tsx

@@ -11,11 +11,15 @@ export const SessionMaxAgeSettings: React.FC<Props> = ({ register, t }) => {
     <>
     <>
       <h4>{t('security_settings.session')}</h4>
       <h4>{t('security_settings.session')}</h4>
       <div className="row">
       <div className="row">
-        <label className="text-start text-md-end col-md-3 col-form-label">
+        <label
+          className="text-start text-md-end col-md-3 col-form-label"
+          htmlFor="sessionMaxAge"
+        >
           {t('security_settings.max_age')}
           {t('security_settings.max_age')}
         </label>
         </label>
         <div className="col-md-8">
         <div className="col-md-8">
           <input
           <input
+            id="sessionMaxAge"
             className="form-control col-md-4"
             className="form-control col-md-4"
             type="text"
             type="text"
             {...register('sessionMaxAge')}
             {...register('sessionMaxAge')}
@@ -24,6 +28,7 @@ export const SessionMaxAgeSettings: React.FC<Props> = ({ register, t }) => {
           {/* eslint-disable-next-line react/no-danger */}
           {/* eslint-disable-next-line react/no-danger */}
           <p
           <p
             className="form-text text-muted"
             className="form-text text-muted"
+            // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
               __html: t('security_settings.max_age_desc'),
               __html: t('security_settings.max_age_desc'),
             }}
             }}

+ 1 - 0
apps/app/src/client/components/Admin/Security/SecuritySetting/UserHomepageDeletionSettings.tsx

@@ -69,6 +69,7 @@ export const UserHomepageDeletionSettings: React.FC<Props> = ({
           </div>
           </div>
           <p
           <p
             className="form-text text-muted small mt-2"
             className="form-text text-muted small mt-2"
+            // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
               __html: t('security_settings.user_homepage_deletion.desc'),
               __html: t('security_settings.user_homepage_deletion.desc'),
             }}
             }}