LoginForm.jsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. class LoginForm extends React.Component {
  5. constructor(props) {
  6. super(props);
  7. this.isRegistrationEnabled = false;
  8. this.isLocalStrategySetup = false;
  9. this.isLdapStrategySetup = false;
  10. this.objOfIsExternalAuthEnableds = {};
  11. this.renderLocalOrLdapLoginForm = this.renderLocalOrLdapLoginForm.bind(this);
  12. this.renderExternalAuthLoginForm = this.renderExternalAuthLoginForm.bind(this);
  13. this.renderExternalAuthInput = this.renderExternalAuthInput.bind(this);
  14. }
  15. componentWillMount() {
  16. this.isRegistrationEnabled = true;
  17. this.isLocalStrategySetup = true;
  18. this.isLdapStrategySetup = true;
  19. this.objOfIsExternalAuthEnableds = {
  20. google: true,
  21. github: true,
  22. facebook: true,
  23. twitter: true,
  24. oidc: true,
  25. saml: true,
  26. basic: true,
  27. };
  28. }
  29. renderLocalOrLdapLoginForm() {
  30. const { t } = this.props;
  31. return (
  32. <form className="col-12" role="form" action="/login" method="post">
  33. <div className="input-group mb-3">
  34. <div className="input-group-prepend">
  35. <span className="input-group-text"><i className="icon-user"></i></span>
  36. </div>
  37. <input type="text" className="form-control" placeholder="Username or E-mail" name="loginForm[username]" />
  38. {this.isLdapStrategySetup && (
  39. <div className="input-group-append">
  40. <small className="input-group-text text-success">
  41. <i className="icon-fw icon-check"></i> LDAP
  42. </small>
  43. </div>
  44. )}
  45. </div>
  46. <div className="input-group mb-3">
  47. <div className="input-group-prepend">
  48. <span className="input-group-text"><i className="icon-lock"></i></span>
  49. </div>
  50. <input type="password" className="form-control" placeholder="Password" name="loginForm[password]" />
  51. </div>
  52. <div className="input-group justify-content-center d-flex mt-5">
  53. <input type="hidden" name="_csrf" value="{{ csrf() }}" />
  54. <button type="submit" id="login" className="btn btn-fill login px-0 py-2">
  55. <div className="eff"></div>
  56. <span className="btn-label p-3"><i className="icon-login"></i></span>
  57. <span className="btn-label-text p-3">{ t('Sign in') }</span>
  58. </button>
  59. </div>
  60. </form>
  61. );
  62. }
  63. renderExternalAuthInput(auth) {
  64. const { t } = this.props;
  65. return (
  66. <div className="input-group justify-content-center d-flex mt-5">
  67. <form role="form" action={`/passport/${auth}`} className="d-inline-flex flex-column">
  68. <input type="hidden" name="_csrf" value="{{ csrf() }}" />
  69. <button type="submit" className="btn btn-fill px-0 py-2" id={auth}>
  70. <div className="eff"></div>
  71. <span className="btn-label p-3"><i className={`fa fa-${auth}`}></i></span>
  72. <span className="btn-label-text p-3">{ t('Sign in') }</span>
  73. </button>
  74. <div className="small text-center">by {auth} Account</div>
  75. </form>
  76. </div>
  77. );
  78. }
  79. renderExternalAuthLoginForm() {
  80. const isExternalAuthCollapsible = this.isLocalStrategySetup || this.isLdapStrategySetup;
  81. const collapsibleClass = isExternalAuthCollapsible ? 'collapse collapse-external-auth collapse-anchor' : '';
  82. return (
  83. <>
  84. <div className="border-bottom"></div>
  85. <div id="external-auth" className={`external-auth ${collapsibleClass}`}>
  86. <div className="spacer"></div>
  87. <div className="d-flex flex-row justify-content-between flex-wrap">
  88. {Object.keys(this.objOfIsExternalAuthEnableds).map((auth) => {
  89. if (!this.objOfIsExternalAuthEnableds[auth]) {
  90. return;
  91. }
  92. return this.renderExternalAuthInput(auth);
  93. })}
  94. </div>
  95. <div className="spacer"></div>
  96. </div>
  97. <div className="border-bottom"></div>
  98. <div className="text-center">
  99. <button
  100. type="button"
  101. className="collapse-anchor btn btn-xs btn-collapse-external-auth mb-3"
  102. data-toggle={isExternalAuthCollapsible ? 'collapse' : ''}
  103. data-target="#external-auth"
  104. aria-expanded="false"
  105. aria-controls="external-auth"
  106. >
  107. External Auth
  108. </button>
  109. </div>
  110. </>
  111. );
  112. }
  113. render() {
  114. const { t } = this.props;
  115. const isLocalOrLdapStrategiesEnabled = this.isLocalStrategySetup || this.isLdapStrategySetup;
  116. const registerFormClass = this.isRegistrationEnabled ? 'to-flip' : '';
  117. const isSomeExternalAuthEnabled = Object.values(this.objOfIsExternalAuthEnableds).some(elem => elem);
  118. return (
  119. <div className={`login-dialog mx-auto flipper ${registerFormClass}`} id="login-dialog">
  120. <div className="row">
  121. <div className="col-12">
  122. <div className="front">
  123. { isLocalOrLdapStrategiesEnabled && this.renderLocalOrLdapLoginForm() }
  124. { isSomeExternalAuthEnabled && this.renderExternalAuthLoginForm() }
  125. </div>
  126. {/* [TODO][GW-1863] render register form here */}
  127. </div>
  128. </div>
  129. {this.isRegistrationEnabled && (
  130. <div className="row">
  131. <div className="col-12 text-right py-2">
  132. <a href="#register" id="register" className="link-switch">
  133. <i className="ti-check-box"></i> { t('Sign up is here') }
  134. </a>
  135. </div>
  136. </div>
  137. )}
  138. </div>
  139. );
  140. }
  141. }
  142. LoginForm.propTypes = {
  143. // i18next
  144. t: PropTypes.func.isRequired,
  145. };
  146. export default withTranslation()(LoginForm);