فهرست منبع

Merge remote-tracking branch 'origin/support/reactify-login-page-stock' into support/switch-registration-form

itizawa 6 سال پیش
والد
کامیت
6cbef0334e
3فایلهای تغییر یافته به همراه81 افزوده شده و 25 حذف شده
  1. 41 21
      src/client/js/components/LoginForm.jsx
  2. 21 1
      src/client/js/nologin.jsx
  3. 19 3
      src/server/views/login.html

+ 41 - 21
src/client/js/components/LoginForm.jsx

@@ -56,7 +56,7 @@ class LoginForm extends React.Component {
   }
   }
 
 
   renderLocalOrLdapLoginForm() {
   renderLocalOrLdapLoginForm() {
-    const { t, csrf } = this.props;
+    const { t, csrf, isLdapStrategySetup } = this.props;
 
 
     return (
     return (
       <form role="form" action="/login" method="post">
       <form role="form" action="/login" method="post">
@@ -67,7 +67,7 @@ class LoginForm extends React.Component {
             </span>
             </span>
           </div>
           </div>
           <input type="text" className="form-control" placeholder="Username or E-mail" name="loginForm[username]" />
           <input type="text" className="form-control" placeholder="Username or E-mail" name="loginForm[username]" />
-          {this.isLdapStrategySetup && (
+          {isLdapStrategySetup && (
             <div className="input-group-append">
             <div className="input-group-append">
               <small className="input-group-text text-success">
               <small className="input-group-text text-success">
                 <i className="icon-fw icon-check"></i> LDAP
                 <i className="icon-fw icon-check"></i> LDAP
@@ -86,7 +86,7 @@ class LoginForm extends React.Component {
         </div>
         </div>
 
 
         <div className="input-group justify-content-center d-flex mt-5">
         <div className="input-group justify-content-center d-flex mt-5">
-          {/* [TODO][GW-1913] An AppContainer gets csrf data */}
+          {/* [TODO][GW-2112] An AppContainer gets csrf data */}
           <input type="hidden" name="_csrf" value={csrf} />
           <input type="hidden" name="_csrf" value={csrf} />
           <button type="submit" id="login" className="btn btn-fill login px-0 py-2">
           <button type="submit" id="login" className="btn btn-fill login px-0 py-2">
             <div className="eff"></div>
             <div className="eff"></div>
@@ -104,9 +104,9 @@ class LoginForm extends React.Component {
     const { t, csrf } = this.props;
     const { t, csrf } = this.props;
     return (
     return (
       <div key={auth} className="input-group justify-content-center d-flex mt-5">
       <div key={auth} className="input-group justify-content-center d-flex mt-5">
-        {/* [TODO][GW-1913] use onClick, and delete form tag */}
+        {/* [TODO][GW-2112] use onClick, and delete form tag */}
         <form role="form" action={`/passport/${auth}`} className="d-inline-flex flex-column">
         <form role="form" action={`/passport/${auth}`} className="d-inline-flex flex-column">
-          {/* [TODO][GW-1913] An AppContainer gets csrf data */}
+          {/* [TODO][GW-2112] An AppContainer gets csrf data */}
           <input type="hidden" name="_csrf" value={csrf} />
           <input type="hidden" name="_csrf" value={csrf} />
           <button type="submit" className="btn btn-fill px-0 py-2" id={auth}>
           <button type="submit" className="btn btn-fill px-0 py-2" id={auth}>
             <div className="eff"></div>
             <div className="eff"></div>
@@ -122,7 +122,8 @@ class LoginForm extends React.Component {
   }
   }
 
 
   renderExternalAuthLoginForm() {
   renderExternalAuthLoginForm() {
-    const isExternalAuthCollapsible = this.isLocalStrategySetup || this.isLdapStrategySetup;
+    const { isLocalStrategySetup, isLdapStrategySetup, objOfIsExternalAuthEnableds } = this.props;
+    const isExternalAuthCollapsible = isLocalStrategySetup || isLdapStrategySetup;
     const collapsibleClass = isExternalAuthCollapsible ? 'collapse collapse-external-auth collapse-anchor' : '';
     const collapsibleClass = isExternalAuthCollapsible ? 'collapse collapse-external-auth collapse-anchor' : '';
 
 
     return (
     return (
@@ -131,8 +132,8 @@ class LoginForm extends React.Component {
         <div id="external-auth" className={`external-auth ${collapsibleClass}`}>
         <div id="external-auth" className={`external-auth ${collapsibleClass}`}>
           <div className="spacer"></div>
           <div className="spacer"></div>
           <div className="d-flex flex-row justify-content-between flex-wrap">
           <div className="d-flex flex-row justify-content-between flex-wrap">
-            {Object.keys(this.objOfIsExternalAuthEnableds).map((auth) => {
-              if (!this.objOfIsExternalAuthEnableds[auth]) {
+            {Object.keys(objOfIsExternalAuthEnableds).map((auth) => {
+              if (!objOfIsExternalAuthEnableds[auth]) {
                 return;
                 return;
               }
               }
               return this.renderExternalAuthInput(auth);
               return this.renderExternalAuthInput(auth);
@@ -158,10 +159,16 @@ class LoginForm extends React.Component {
   }
   }
 
 
   renderRegisterForm() {
   renderRegisterForm() {
-    const { t, csrf } = this.props;
+    const {
+      t,
+      csrf,
+      registrationMode,
+      registrationWhiteList,
+    } = this.props;
+
     return (
     return (
       <div className="back">
       <div className="back">
-        {this.registrationMode === 'Restricted' && (
+        {registrationMode === 'Restricted' && (
           <p className="alert alert-warning">
           <p className="alert alert-warning">
             {t('page_register.notice.restricted')}
             {t('page_register.notice.restricted')}
             <br />
             <br />
@@ -199,14 +206,14 @@ class LoginForm extends React.Component {
             <input type="email" className="form-control" placeholder={t('Email')} name="registerForm[email]" defaultValue={this.props.email} required />
             <input type="email" className="form-control" placeholder={t('Email')} name="registerForm[email]" defaultValue={this.props.email} required />
           </div>
           </div>
 
 
-          {this.registrationWhiteList.length > 0 && (
+          {registrationWhiteList.length > 0 && (
             <>
             <>
               <p className="form-text">{t('page_register.form_help.email')}</p>
               <p className="form-text">{t('page_register.form_help.email')}</p>
               <ul>
               <ul>
-                {this.registrationWhiteList.map((elem) => {
+                {registrationWhiteList.map((elem) => {
                   return (
                   return (
-                    <li>
-                      <code>{{ elem }}</code>
+                    <li key={elem}>
+                      <code>{elem}</code>
                     </li>
                     </li>
                   );
                   );
                 })}
                 })}
@@ -224,7 +231,7 @@ class LoginForm extends React.Component {
           </div>
           </div>
 
 
           <div className="input-group justify-content-center mt-5">
           <div className="input-group justify-content-center mt-5">
-            {/* [TODO][GW-1913] An AppContainer gets csrf data */}
+            {/* [TODO][GW-2112] An AppContainer gets csrf data */}
             <input type="hidden" name="_csrf" value={csrf} />
             <input type="hidden" name="_csrf" value={csrf} />
             <button type="submit" className="btn btn-fill px-0 py-2" id="register">
             <button type="submit" className="btn btn-fill px-0 py-2" id="register">
               <div className="eff"></div>
               <div className="eff"></div>
@@ -251,11 +258,18 @@ class LoginForm extends React.Component {
   }
   }
 
 
   render() {
   render() {
-    const { t } = this.props;
+    const {
+      t,
+      isRegistering,
+      isLocalStrategySetup,
+      isLdapStrategySetup,
+      isRegistrationEnabled,
+      objOfIsExternalAuthEnableds,
+    } = this.props;
 
 
-    const isLocalOrLdapStrategiesEnabled = this.isLocalStrategySetup || this.isLdapStrategySetup;
-    const registerFormClass = this.state.isRegistering ? 'to-flip' : '';
-    const isSomeExternalAuthEnabled = Object.values(this.objOfIsExternalAuthEnableds).some(elem => elem);
+    const isLocalOrLdapStrategiesEnabled = isLocalStrategySetup || isLdapStrategySetup;
+    const registerFormClass = isRegistering ? 'to-flip' : '';
+    const isSomeExternalAuthEnabled = Object.values(objOfIsExternalAuthEnableds).some(elem => elem);
 
 
     return (
     return (
       <div className={`login-dialog mx-auto flipper ${registerFormClass}`} id="login-dialog">
       <div className={`login-dialog mx-auto flipper ${registerFormClass}`} id="login-dialog">
@@ -264,7 +278,7 @@ class LoginForm extends React.Component {
             <div className="front">
             <div className="front">
               {isLocalOrLdapStrategiesEnabled && this.renderLocalOrLdapLoginForm()}
               {isLocalOrLdapStrategiesEnabled && this.renderLocalOrLdapLoginForm()}
               {isSomeExternalAuthEnabled && this.renderExternalAuthLoginForm()}
               {isSomeExternalAuthEnabled && this.renderExternalAuthLoginForm()}
-              {this.isRegistrationEnabled && (
+              {isRegistrationEnabled && (
                 <div className="row">
                 <div className="row">
                   <div className="col-12 text-right py-2">
                   <div className="col-12 text-right py-2">
                     <a href="#register" id="register" className="link-switch" onClick={this.onClickSwitchFormBtn}>
                     <a href="#register" id="register" className="link-switch" onClick={this.onClickSwitchFormBtn}>
@@ -274,7 +288,7 @@ class LoginForm extends React.Component {
                 </div>
                 </div>
               )}
               )}
             </div>
             </div>
-            {this.isRegistrationEnabled && this.renderRegisterForm()}
+            {isRegistrationEnabled && this.renderRegisterForm()}
             <a href="https://growi.org" className="link-growi-org pl-3">
             <a href="https://growi.org" className="link-growi-org pl-3">
               <span className="growi">GROWI</span>.<span className="org">ORG</span>
               <span className="growi">GROWI</span>.<span className="org">ORG</span>
             </a>
             </a>
@@ -293,6 +307,12 @@ LoginForm.propTypes = {
   name: PropTypes.string,
   name: PropTypes.string,
   email: PropTypes.string,
   email: PropTypes.string,
   csrf: PropTypes.string,
   csrf: PropTypes.string,
+  isRegistrationEnabled: PropTypes.bool,
+  registrationMode: PropTypes.string,
+  registrationWhiteList: PropTypes.array,
+  isLocalStrategySetup: PropTypes.bool,
+  isLdapStrategySetup: PropTypes.bool,
+  objOfIsExternalAuthEnableds: PropTypes.object,
 };
 };
 
 
 export default withTranslation()(LoginForm);
 export default withTranslation()(LoginForm);

+ 21 - 1
src/client/js/nologin.jsx

@@ -30,8 +30,22 @@ if (loginFormElem) {
   const username = loginFormElem.dataset.username;
   const username = loginFormElem.dataset.username;
   const name = loginFormElem.dataset.name;
   const name = loginFormElem.dataset.name;
   const email = loginFormElem.dataset.email;
   const email = loginFormElem.dataset.email;
-  // [TODO][GW-1913] An AppContainer gets csrf data
+  // [TODO][GW-2112] An AppContainer gets csrf data
   const csrf = loginFormElem.dataset.csrf;
   const csrf = loginFormElem.dataset.csrf;
+  const isRegistrationEnabled = loginFormElem.dataset.isRegistrationEnabled === 'true';
+  const registrationMode = loginFormElem.dataset.registrationMode;
+  const registrationWhiteList = loginFormElem.dataset.registrationWhiteList.split(',');
+  const isLocalStrategySetup = loginFormElem.dataset.isLocalStrategySetup === 'true';
+  const isLdapStrategySetup = loginFormElem.dataset.isLdapStrategySetup === 'true';
+  const objOfIsExternalAuthEnableds = {
+    google: loginFormElem.dataset.isGoogleAuthEnabled === 'true',
+    github: loginFormElem.dataset.isGithubAuthEnabled === 'true',
+    facebook: loginFormElem.dataset.isFacebookAuthEnabled === 'true',
+    twitter: loginFormElem.dataset.isTwitterAuthEnabled === 'true',
+    saml: loginFormElem.dataset.isSamlAuthEnabled === 'true',
+    oidc: loginFormElem.dataset.isOidcAuthEnabled === 'true',
+    basic: loginFormElem.dataset.isBasicAuthEnabled === 'true',
+  };
 
 
   ReactDOM.render(
   ReactDOM.render(
     <I18nextProvider i18n={i18n}>
     <I18nextProvider i18n={i18n}>
@@ -40,6 +54,12 @@ if (loginFormElem) {
         name={name}
         name={name}
         email={email}
         email={email}
         csrf={csrf}
         csrf={csrf}
+        isRegistrationEnabled={isRegistrationEnabled}
+        registrationMode={registrationMode}
+        registrationWhiteList={registrationWhiteList}
+        isLocalStrategySetup={isLocalStrategySetup}
+        isLdapStrategySetup={isLdapStrategySetup}
+        objOfIsExternalAuthEnableds={objOfIsExternalAuthEnableds}
       />
       />
     </I18nextProvider>,
     </I18nextProvider>,
     loginFormElem,
     loginFormElem,

+ 19 - 3
src/server/views/login.html

@@ -104,14 +104,30 @@
           </div>
           </div>
         </div>
         </div>
       </div>
       </div>
-        {% set isRegistrationEnabled = passportService.isLocalStrategySetup && getConfig('crowi', 'security:registrationMode') != 'Closed' %}
 
 
-      <!-- [TODO][GW-1913] An AppContainer gets csrf data -->
-      <div id="login-form"
+      {% set registrationMode = getConfig('crowi', 'security:registrationMode') %}
+      {% set isRegistrationEnabled = passportService.isLocalStrategySetup && registrationMode != 'Closed' %}
+
+      <!-- [TODO][GW-2112] An AppContainer gets csrf data -->
+      <div
+        id="login-form"
+        data-is-registering="{{ req.query.register or req.body.registerForm or isRegistering }}"
         data-username ="{{ req.body.registerForm.username }}"
         data-username ="{{ req.body.registerForm.username }}"
         data-name ="{{ req.body.registerForm.name }}"
         data-name ="{{ req.body.registerForm.name }}"
         data-email ="{{ req.body.registerForm.email }}"
         data-email ="{{ req.body.registerForm.email }}"
         data-csrf="{{ csrf() }}"
         data-csrf="{{ csrf() }}"
+        data-is-registration-enabled="{{ isRegistrationEnabled }}"
+        data-registration-mode = "{{ registrationMode }}"
+        data-registration-white-list = "{{ getConfig('crowi', 'security:registrationWhiteList') }}"
+        data-is-local-strategy-setup = "{{ passportService.isLocalStrategySetup }}"
+        data-is-ldap-strategy-setup = "{{ passportService.isLdapStrategySetup}}"
+        data-is-google-auth-enabled = "{{ getConfig('crowi', 'security:passport-google:isEnabled') }}"
+        data-is-github-auth-enabled = "{{ getConfig('crowi', 'security:passport-github:isEnabled') }}"
+        data-is-facebook-auth-enabled = "{{ getConfig('crowi', 'security:passport-facebook:isEnabled') }}"
+        data-is-twitter-auth-enabled = "{{ getConfig('crowi', 'security:passport-twitter:isEnabled') }}"
+        data-is-saml-auth-enabled = "{{ getConfig('crowi', 'security:passport-saml:isEnabled') }}"
+        data-is-oidc-auth-enabled = "{{ getConfig('crowi', 'security:passport-oidc:isEnabled') }}"
+        data-is-basic-auth-enabled = "{{ getConfig('crowi', 'security:passport-basic:isEnabled') }}"
       ></div>
       ></div>
     </div>
     </div>
   </div>
   </div>