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

typescriptize enabledExternalAuthType props

Yuki Takei 2 лет назад
Родитель
Сommit
aaf3e4334f

+ 49 - 47
apps/app/src/components/LoginForm.tsx

@@ -2,6 +2,7 @@ import React, {
   useState, useEffect, useCallback,
 } from 'react';
 
+import type { IExternalAuthProviderType } from '@growi/core';
 import { LoadingSpinner } from '@growi/ui/dist/components';
 import { useTranslation } from 'next-i18next';
 import { useRouter } from 'next/router';
@@ -20,6 +21,44 @@ import styles from './LoginForm.module.scss';
 
 const moduleClass = styles['login-form'];
 
+
+const ExternalAuthButton = ({ authType }: {authType: IExternalAuthProviderType}): JSX.Element => {
+  const { t } = useTranslation();
+
+  const authIcon = {
+    google: <span className="growi-custom-icons align-bottom">google</span>,
+    github: <span className="growi-custom-icons align-bottom">github</span>,
+    facebook: <span className="growi-custom-icons align-bottom">facebook</span>,
+    oidc: <span className="growi-custom-icons align-bottom">openid</span>,
+    saml: <span className="material-symbols-outlined align-bottom">key</span>,
+  };
+  const authBtn = `btn-auth-${authType.toString()}`;
+  const signin = {
+    google: 'Google',
+    github: 'GitHub',
+    facebook: 'Facebook',
+    oidc: 'OIDC',
+    saml: 'SAML',
+  };
+
+  const handleLoginWithExternalAuth = () => {
+    window.location.href = `/passport/${authType.toString()}`;
+  };
+
+  return (
+    <button
+      key={`btn-auth-${authType.toString()}`}
+      type="button"
+      className={`btn btn-secondary ${authBtn} my-2 col-10 col-sm-7 mx-auto d-flex`}
+      onClick={handleLoginWithExternalAuth}
+    >
+      <span>{authIcon[authType.toString()]}</span>
+      <span className="flex-grow-1">{t('Sign in with External auth', { signin: signin[authType.toString()] })}</span>
+    </button>
+  );
+};
+
+
 type LoginFormProps = {
   username?: string,
   name?: string,
@@ -31,7 +70,7 @@ type LoginFormProps = {
   isLocalStrategySetup: boolean,
   isLdapStrategySetup: boolean,
   isLdapSetupFailed: boolean,
-  objOfIsExternalAuthEnableds?: any,
+  enabledExternalAuthType?: IExternalAuthProviderType[],
   isMailerSetup?: boolean,
   externalAccountLoginError?: IExternalAccountLoginError,
 }
@@ -42,10 +81,10 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
 
   const {
     isLocalStrategySetup, isLdapStrategySetup, isLdapSetupFailed, isPasswordResetEnabled,
-    isEmailAuthenticationEnabled, registrationMode, registrationWhitelist, isMailerSetup, objOfIsExternalAuthEnableds,
+    isEmailAuthenticationEnabled, registrationMode, registrationWhitelist, isMailerSetup, enabledExternalAuthType,
   } = props;
   const isLocalOrLdapStrategiesEnabled = isLocalStrategySetup || isLdapStrategySetup;
-  const isSomeExternalAuthEnabled = Object.values(objOfIsExternalAuthEnableds).some(elem => elem);
+  const isSomeExternalAuthEnabled = enabledExternalAuthType != null && enabledExternalAuthType.length > 0;
 
   // states
   const [isRegistering, setIsRegistering] = useState(false);
@@ -81,12 +120,6 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
     return t(key);
   }, [t]);
 
-  const handleLoginWithExternalAuth = useCallback((e) => {
-    const auth = e.currentTarget.id;
-
-    window.location.href = `/passport/${auth}`;
-  }, []);
-
   const resetLoginErrors = useCallback(() => {
     if (loginErrors.length === 0) return;
     setLoginErrors([]);
@@ -265,38 +298,12 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
   ]);
 
 
-  const renderExternalAuthInput = useCallback((auth) => {
-    const authIcon = {
-      google: <span className="growi-custom-icons align-bottom">google</span>,
-      github: <span className="growi-custom-icons align-bottom">github</span>,
-      facebook: <span className="growi-custom-icons align-bottom">facebook</span>,
-      oidc: <span className="growi-custom-icons align-bottom">openid</span>,
-      saml: <span className="material-symbols-outlined align-bottom">key</span>,
-    };
-    const authBtn = `btn-auth-${auth}`;
-    const signin = {
-      google: 'Google',
-      github: 'GitHub',
-      facebook: 'Facebook',
-      oidc: 'OIDC',
-      saml: 'SAML',
-    };
-
-    return (
-      <button
-        key={`btn-auth-${auth}`}
-        type="button"
-        className={`btn btn-secondary ${authBtn} my-2 col-10 col-sm-7 mx-auto d-flex`}
-        onClick={handleLoginWithExternalAuth}
-      >
-        <span>{authIcon[auth]}</span>
-        <span className="flex-grow-1">{t('Sign in with External auth', { signin: signin[auth] })}</span>
-      </button>
-    );
-  }, [handleLoginWithExternalAuth, t]);
-
   const renderExternalAuthLoginForm = useCallback(() => {
-    const { objOfIsExternalAuthEnableds } = props;
+    const { enabledExternalAuthType } = props;
+
+    if (enabledExternalAuthType == null) {
+      return <></>;
+    }
 
     return (
       <>
@@ -304,16 +311,11 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
           <p className="text-white mb-0">{t('or')}</p>
         </div>
         <div className="mt-2">
-          {Object.keys(objOfIsExternalAuthEnableds).map((auth) => {
-            if (!objOfIsExternalAuthEnableds[auth]) {
-              return;
-            }
-            return renderExternalAuthInput(auth);
-          })}
+          { enabledExternalAuthType.map(authType => <ExternalAuthButton authType={authType} />) }
         </div>
       </>
     );
-  }, [props, t, renderExternalAuthInput]);
+  }, [props, t, enabledExternalAuthType]);
 
   const resetRegisterErrors = useCallback(() => {
     if (registerErrors.length === 0) return;

+ 16 - 15
apps/app/src/pages/login/index.page.tsx

@@ -1,6 +1,7 @@
 import React from 'react';
 
-import {
+import { IExternalAuthProviderType } from '@growi/core';
+import type {
   NextPage, GetServerSideProps, GetServerSidePropsContext,
 } from 'next';
 import { useTranslation } from 'next-i18next';
@@ -10,11 +11,11 @@ import Head from 'next/head';
 import { NoLoginLayout } from '~/components/Layout/NoLoginLayout';
 import { LoginForm } from '~/components/LoginForm';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
-import { IExternalAccountLoginError, isExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
+import type { IExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
+import { isExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
 import type { RegistrationMode } from '~/interfaces/registration-mode';
-import {
-  CommonProps, getServerSideCommonProps, generateCustomTitle, getNextI18NextConfig,
-} from '~/pages/utils/commons';
+import type { CommonProps } from '~/pages/utils/commons';
+import { getServerSideCommonProps, generateCustomTitle, getNextI18NextConfig } from '~/pages/utils/commons';
 import {
   useCsrfToken,
   useCurrentPathname,
@@ -27,7 +28,7 @@ type Props = CommonProps & {
   registrationMode: RegistrationMode,
   pageWithMetaStr: string,
   isMailerSetup: boolean,
-  enabledStrategies: unknown,
+  enabledExternalAuthType: IExternalAuthProviderType[],
   registrationWhitelist: string[],
   isLocalStrategySetup: boolean,
   isLdapStrategySetup: boolean,
@@ -55,7 +56,7 @@ const LoginPage: NextPage<Props> = (props: Props) => {
         <title>{title}</title>
       </Head>
       <LoginForm
-        objOfIsExternalAuthEnableds={props.enabledStrategies}
+        enabledExternalAuthType={props.enabledExternalAuthType}
         isLocalStrategySetup={props.isLocalStrategySetup}
         isLdapStrategySetup={props.isLdapStrategySetup}
         isLdapSetupFailed={props.isLdapSetupFailed}
@@ -88,15 +89,15 @@ function injectEnabledStrategies(context: GetServerSidePropsContext, props: Prop
     configManager,
   } = crowi;
 
-  const enabledStrategies = {
-    google: configManager.getConfig('crowi', 'security:passport-google:isEnabled'),
-    github: configManager.getConfig('crowi', 'security:passport-github:isEnabled'),
-    facebook: false,
-    saml: configManager.getConfig('crowi', 'security:passport-saml:isEnabled'),
-    oidc: configManager.getConfig('crowi', 'security:passport-oidc:isEnabled'),
-  };
+  props.enabledExternalAuthType = [
+    configManager.getConfig('crowi', 'security:passport-google:isEnabled') === true ? IExternalAuthProviderType.google : undefined,
+    configManager.getConfig('crowi', 'security:passport-github:isEnabled') === true ? IExternalAuthProviderType.github : undefined,
+    // configManager.getConfig('crowi', 'security:passport-facebook:isEnabled') ?? IExternalAuthProviderType.facebook : undefined,
+    configManager.getConfig('crowi', 'security:passport-saml:isEnabled') === true ? IExternalAuthProviderType.saml : undefined,
+    configManager.getConfig('crowi', 'security:passport-oidc:isEnabled') === true ? IExternalAuthProviderType.oidc : undefined,
 
-  props.enabledStrategies = enabledStrategies;
+  ]
+    .filter((authType): authType is Exclude<typeof authType, undefined> => authType != null);
 }
 
 async function injectServerConfigurations(context: GetServerSidePropsContext, props: Props): Promise<void> {

+ 2 - 1
packages/core/src/interfaces/external-account.ts

@@ -5,9 +5,10 @@ import type { IUser } from './user';
 export const IExternalAuthProviderType = {
   ldap: 'ldap',
   saml: 'saml',
-  oicd: 'oidc',
+  oidc: 'oidc',
   google: 'google',
   github: 'github',
+  facebook: 'facebook',
 } as const;
 
 export type IExternalAuthProviderType = typeof IExternalAuthProviderType[keyof typeof IExternalAuthProviderType]