Преглед изворни кода

Merge pull request #2036 from weseek/support/reactify-login-page-send-params

Support/reactify login page send params
Yuki Takei пре 6 година
родитељ
комит
5aa89cfd3c
3 измењених фајлова са 79 додато и 49 уклоњено
  1. 40 45
      src/client/js/components/LoginForm.jsx
  2. 21 1
      src/client/js/nologin.jsx
  3. 18 3
      src/server/views/login.html

+ 40 - 45
src/client/js/components/LoginForm.jsx

@@ -8,13 +8,6 @@ class LoginForm extends React.Component {
   constructor(props) {
   constructor(props) {
     super(props);
     super(props);
 
 
-    this.isRegistrationEnabled = false;
-    this.registrationMode = 'Closed';
-    this.registrationWhiteList = [];
-    this.isLocalStrategySetup = false;
-    this.isLdapStrategySetup = false;
-    this.objOfIsExternalAuthEnableds = {};
-
     this.switchForm = this.switchForm.bind(this);
     this.switchForm = this.switchForm.bind(this);
     this.renderLocalOrLdapLoginForm = this.renderLocalOrLdapLoginForm.bind(this);
     this.renderLocalOrLdapLoginForm = this.renderLocalOrLdapLoginForm.bind(this);
     this.renderExternalAuthLoginForm = this.renderExternalAuthLoginForm.bind(this);
     this.renderExternalAuthLoginForm = this.renderExternalAuthLoginForm.bind(this);
@@ -22,24 +15,6 @@ class LoginForm extends React.Component {
     this.renderRegisterForm = this.renderRegisterForm.bind(this);
     this.renderRegisterForm = this.renderRegisterForm.bind(this);
   }
   }
 
 
-  componentWillMount() {
-    // [TODO][GW-1913] get params from server with axios
-    this.isRegistrationEnabled = true;
-    this.registrationMode = 'Open';
-    this.registrationWhiteList = [];
-    this.isLocalStrategySetup = true;
-    this.isLdapStrategySetup = true;
-    this.objOfIsExternalAuthEnableds = {
-      google: true,
-      github: true,
-      facebook: true,
-      twitter: true,
-      oidc: true,
-      saml: true,
-      basic: true,
-    };
-  }
-
   // for flip [TODO][GW-1865] use state or react component for flip
   // for flip [TODO][GW-1865] use state or react component for flip
   switchForm(e) {
   switchForm(e) {
     if (e.target.id === 'register') {
     if (e.target.id === 'register') {
@@ -51,7 +26,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">
@@ -62,7 +37,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
@@ -81,7 +56,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>
@@ -99,9 +74,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>
@@ -117,7 +92,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 (
@@ -126,8 +102,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);
@@ -153,10 +129,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 />
@@ -194,14 +176,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>
                   );
                   );
                 })}
                 })}
@@ -219,7 +201,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>
@@ -246,11 +228,18 @@ class LoginForm extends React.Component {
   }
   }
 
 
   render() {
   render() {
-    const { t, isRegistering } = this.props;
+    const {
+      t,
+      isRegistering,
+      isLocalStrategySetup,
+      isLdapStrategySetup,
+      isRegistrationEnabled,
+      objOfIsExternalAuthEnableds,
+    } = this.props;
 
 
-    const isLocalOrLdapStrategiesEnabled = this.isLocalStrategySetup || this.isLdapStrategySetup;
+    const isLocalOrLdapStrategiesEnabled = isLocalStrategySetup || isLdapStrategySetup;
     const registerFormClass = isRegistering ? 'to-flip' : '';
     const registerFormClass = isRegistering ? 'to-flip' : '';
-    const isSomeExternalAuthEnabled = Object.values(this.objOfIsExternalAuthEnableds).some(elem => elem);
+    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">
@@ -259,7 +248,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.switchForm}>
                     <a href="#register" id="register" className="link-switch" onClick={this.switchForm}>
@@ -269,7 +258,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>
@@ -289,6 +278,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

@@ -31,8 +31,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}>
@@ -42,6 +56,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,

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

@@ -104,15 +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-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>