*/
import { getJSON, post, RequestData } from '../helpers/request';
+export interface IdentityProvider {
+ backgroundColor: string;
+ iconPath: string;
+ key: string;
+ name: string;
+}
+
export function getCurrentUser(): Promise<any> {
return getJSON('/api/users/current');
}
return getJSON('/api/users/groups', data);
}
-export function getIdentityProviders(): Promise<any> {
+export function getIdentityProviders(): Promise<{ identityProviders: IdentityProvider[] }> {
return getJSON('/api/users/identity_providers');
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import GlobalFooterContainer from './GlobalFooterContainer';
-import NavBar from '../../components/nav/NavBar';
-
-/*::
-type Props = {
- children?: React.Element<*> | Array<React.Element<*>>,
- hideLoggedInInfo?: boolean
-};
-*/
-
-export default class SimpleContainer extends React.PureComponent {
- /*:: props: Props; */
-
- componentDidMount() {
- const html = document.querySelector('html');
- if (html) {
- html.classList.add('dashboard-page');
- }
- }
-
- componentWillUnmount() {
- const html = document.querySelector('html');
- if (html) {
- html.classList.remove('dashboard-page');
- }
- }
-
- render() {
- return (
- <div className="global-container">
- <div className="page-wrapper" id="container">
- <NavBar className="navbar-global" id="global-navigation" height={30} />
-
- <div id="bd" className="page-wrapper-simple">
- <div id="nonav" className="page-simple">
- {this.props.children}
- </div>
- </div>
- </div>
- <GlobalFooterContainer hideLoggedInInfo={this.props.hideLoggedInInfo} />
- </div>
- );
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import GlobalFooterContainer from './GlobalFooterContainer';
+import NavBar from '../../components/nav/NavBar';
+
+interface Props {
+ children?: React.ReactNode;
+ hideLoggedInInfo?: boolean;
+}
+
+export default class SimpleContainer extends React.PureComponent<Props> {
+ componentDidMount() {
+ const html = document.querySelector('html');
+ if (html) {
+ html.classList.add('dashboard-page');
+ }
+ }
+
+ componentWillUnmount() {
+ const html = document.querySelector('html');
+ if (html) {
+ html.classList.remove('dashboard-page');
+ }
+ }
+
+ render() {
+ return (
+ <div className="global-container">
+ <div className="page-wrapper" id="container">
+ <NavBar className="navbar-global" height={30} />
+
+ <div id="bd" className="page-wrapper-simple">
+ <div id="nonav" className="page-simple">
+ {this.props.children}
+ </div>
+ </div>
+ </div>
+ <GlobalFooterContainer hideLoggedInInfo={this.props.hideLoggedInInfo} />
+ </div>
+ );
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import OAuthProviders from './OAuthProviders';
-import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer';
-import { translate } from '../../../helpers/l10n';
-
-/*::
-type Props = {
- identityProviders: Array<{
- backgroundColor: string,
- iconPath: string,
- key: string,
- name: string
- }>,
- onSubmit: (string, string) => void
-};
-*/
-
-/*::
-type State = {
- collapsed: boolean,
- login: string,
- password: string
-};
-*/
-
-export default class LoginForm extends React.PureComponent {
- /*:: props: Props; */
- /*:: state: State; */
-
- constructor(props /*: Props */) {
- super(props);
- this.state = {
- collapsed: props.identityProviders.length > 0,
- login: '',
- password: ''
- };
- }
-
- handleSubmit = (event /*: Event */) => {
- event.preventDefault();
- this.props.onSubmit(this.state.login, this.state.password);
- };
-
- handleMoreOptionsClick = (event /*: Event */) => {
- event.preventDefault();
- this.setState({ collapsed: false });
- };
-
- render() {
- return (
- <div id="login_form">
- <h1 className="maintenance-title text-center">{translate('login.login_to_sonarqube')}</h1>
-
- {this.props.identityProviders.length > 0 && (
- <OAuthProviders identityProviders={this.props.identityProviders} />
- )}
-
- {this.state.collapsed ? (
- <div className="text-center">
- <a
- className="small text-muted js-more-options"
- href="#"
- onClick={this.handleMoreOptionsClick}>
- {translate('login.more_options')}
- </a>
- </div>
- ) : (
- <form onSubmit={this.handleSubmit}>
- <GlobalMessagesContainer />
-
- <div className="big-spacer-bottom">
- <label htmlFor="login" className="login-label">
- {translate('login')}
- </label>
- <input
- type="text"
- id="login"
- name="login"
- className="login-input"
- maxLength="255"
- required={true}
- autoFocus={true}
- placeholder={translate('login')}
- value={this.state.login}
- onChange={e => this.setState({ login: e.target.value })}
- />
- </div>
-
- <div className="big-spacer-bottom">
- <label htmlFor="password" className="login-label">
- {translate('password')}
- </label>
- <input
- type="password"
- id="password"
- name="password"
- className="login-input"
- required={true}
- placeholder={translate('password')}
- value={this.state.password}
- onChange={e => this.setState({ password: e.target.value })}
- />
- </div>
-
- <div>
- <div className="text-right overflow-hidden">
- <button name="commit" type="submit">
- {translate('sessions.log_in')}
- </button>
- <a className="spacer-left" href={window.baseUrl + '/'}>
- {translate('cancel')}
- </a>
- </div>
- </div>
- </form>
- )}
- </div>
- );
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { Link } from 'react-router';
+import OAuthProviders from './OAuthProviders';
+import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer';
+import { translate } from '../../../helpers/l10n';
+import { IdentityProvider } from '../../../api/users';
+
+interface Props {
+ identityProviders: IdentityProvider[];
+ onSubmit: (login: string, password: string) => void;
+}
+
+interface State {
+ collapsed: boolean;
+ login: string;
+ password: string;
+}
+
+export default class LoginForm extends React.PureComponent<Props, State> {
+ constructor(props: Props) {
+ super(props);
+ this.state = {
+ collapsed: props.identityProviders.length > 0,
+ login: '',
+ password: ''
+ };
+ }
+
+ handleSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
+ event.preventDefault();
+ this.props.onSubmit(this.state.login, this.state.password);
+ };
+
+ handleMoreOptionsClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ this.setState({ collapsed: false });
+ };
+
+ handleLoginChange = (event: React.SyntheticEvent<HTMLInputElement>) =>
+ this.setState({ login: event.currentTarget.value });
+
+ handlePwdChange = (event: React.SyntheticEvent<HTMLInputElement>) =>
+ this.setState({ password: event.currentTarget.value });
+
+ render() {
+ return (
+ <div id="login_form">
+ <h1 className="maintenance-title text-center">{translate('login.login_to_sonarqube')}</h1>
+
+ {this.props.identityProviders.length > 0 && (
+ <OAuthProviders identityProviders={this.props.identityProviders} />
+ )}
+
+ {this.state.collapsed ? (
+ <div className="text-center">
+ <a
+ className="small text-muted js-more-options"
+ href="#"
+ onClick={this.handleMoreOptionsClick}>
+ {translate('login.more_options')}
+ </a>
+ </div>
+ ) : (
+ <form onSubmit={this.handleSubmit}>
+ <GlobalMessagesContainer />
+
+ <div className="big-spacer-bottom">
+ <label htmlFor="login" className="login-label">
+ {translate('login')}
+ </label>
+ <input
+ type="text"
+ id="login"
+ name="login"
+ className="login-input"
+ maxLength={255}
+ required={true}
+ autoFocus={true}
+ placeholder={translate('login')}
+ value={this.state.login}
+ onChange={this.handleLoginChange}
+ />
+ </div>
+
+ <div className="big-spacer-bottom">
+ <label htmlFor="password" className="login-label">
+ {translate('password')}
+ </label>
+ <input
+ type="password"
+ id="password"
+ name="password"
+ className="login-input"
+ required={true}
+ placeholder={translate('password')}
+ value={this.state.password}
+ onChange={this.handlePwdChange}
+ />
+ </div>
+
+ <div>
+ <div className="text-right overflow-hidden">
+ <button name="commit" type="submit">
+ {translate('sessions.log_in')}
+ </button>
+ <Link className="spacer-left" to="/">
+ {translate('cancel')}
+ </Link>
+ </div>
+ </div>
+ </form>
+ )}
+ </div>
+ );
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import LoginForm from './LoginForm';
-import { doLogin } from '../../../store/rootActions';
-import { getAppState } from '../../../store/rootReducer';
-import { getIdentityProviders } from '../../../api/users';
-
-class LoginFormContainer extends React.PureComponent {
- /*:: mounted: boolean; */
-
- static propTypes = {
- location: PropTypes.object.isRequired
- };
-
- state = {};
-
- componentDidMount() {
- this.mounted = true;
- getIdentityProviders().then(r => {
- if (this.mounted) {
- this.setState({ identityProviders: r.identityProviders });
- }
- });
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- handleSuccessfulLogin = () => {
- const { location } = this.props;
- const queryReturnTo = location.query['return_to'];
- const returnTo = queryReturnTo ? `${queryReturnTo}${location.hash}` : `${window.baseUrl}/`;
- window.location = returnTo;
- };
-
- handleSubmit = (login /*: string */, password /*: string */) => {
- this.props.doLogin(login, password).then(this.handleSuccessfulLogin, () => {
- /* do nothing */
- });
- };
-
- render() {
- if (!this.state.identityProviders) {
- return null;
- }
-
- return (
- <LoginForm identityProviders={this.state.identityProviders} onSubmit={this.handleSubmit} />
- );
- }
-}
-
-const mapStateToProps = state => ({
- appState: getAppState(state)
-});
-
-const mapDispatchToProps = { doLogin };
-
-export default connect(mapStateToProps, mapDispatchToProps)(LoginFormContainer);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { connect } from 'react-redux';
+import LoginForm from './LoginForm';
+import { doLogin } from '../../../store/rootActions';
+import { getAppState } from '../../../store/rootReducer';
+import { IdentityProvider, getIdentityProviders } from '../../../api/users';
+import { getBaseUrl } from '../../../helpers/urls';
+
+interface Props {
+ doLogin: (login: string, password: string) => Promise<void>;
+ location: { hash?: string; pathName: string; query: { return_to?: string } };
+}
+
+interface State {
+ identityProviders?: IdentityProvider[];
+}
+
+class LoginFormContainer extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = {};
+
+ componentDidMount() {
+ this.mounted = true;
+ getIdentityProviders().then(r => {
+ if (this.mounted) {
+ this.setState({ identityProviders: r.identityProviders });
+ }
+ });
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ handleSuccessfulLogin = () => {
+ const { location } = this.props;
+ const queryReturnTo = location.query['return_to'];
+ const returnTo = queryReturnTo ? `${queryReturnTo}${location.hash}` : `${getBaseUrl()}/`;
+ window.location.href = returnTo;
+ };
+
+ handleSubmit = (login: string, password: string) => {
+ this.props.doLogin(login, password).then(this.handleSuccessfulLogin, () => {});
+ };
+
+ render() {
+ if (!this.state.identityProviders) {
+ return null;
+ }
+
+ return (
+ <LoginForm identityProviders={this.state.identityProviders} onSubmit={this.handleSubmit} />
+ );
+ }
+}
+
+const mapStateToProps = (state: any) => ({
+ appState: getAppState(state)
+});
+
+const mapDispatchToProps = { doLogin };
+
+export default connect(mapStateToProps, mapDispatchToProps)(LoginFormContainer as any);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import { connect } from 'react-redux';
-import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer';
-import { doLogout } from '../../../store/rootActions';
-import { translate } from '../../../helpers/l10n';
-import RecentHistory from '../../../app/components/RecentHistory';
-
-class Logout extends React.PureComponent {
- componentDidMount() {
- this.props
- .doLogout()
- .then(() => {
- RecentHistory.clear();
- window.location = window.baseUrl + '/';
- })
- .catch(() => {
- /* do nothing */
- });
- }
-
- render() {
- return (
- <div>
- <GlobalMessagesContainer />
- {translate('logging_out')}
- </div>
- );
- }
-}
-
-const mapStateToProps = () => ({});
-
-const mapDispatchToProps = { doLogout };
-
-export default connect(mapStateToProps, mapDispatchToProps)(Logout);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { connect } from 'react-redux';
+import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer';
+import RecentHistory from '../../../app/components/RecentHistory';
+import { doLogout } from '../../../store/rootActions';
+import { translate } from '../../../helpers/l10n';
+import { getBaseUrl } from '../../../helpers/urls';
+
+interface Props {
+ doLogout: () => Promise<void>;
+}
+
+class Logout extends React.PureComponent<Props> {
+ componentDidMount() {
+ this.props.doLogout().then(
+ () => {
+ RecentHistory.clear();
+ window.location.href = getBaseUrl() + '/';
+ },
+ () => {}
+ );
+ }
+
+ render() {
+ return (
+ <div>
+ <GlobalMessagesContainer />
+ {translate('logging_out')}
+ </div>
+ );
+ }
+}
+
+const mapStateToProps = () => ({});
+
+const mapDispatchToProps = { doLogout };
+
+export default connect(mapStateToProps, mapDispatchToProps)(Logout as any);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import { translateWithParameters } from '../../../helpers/l10n';
-
-/*::
-type Props = {
- formatLabel?: string => string,
- identityProviders: Array<{
- backgroundColor: string,
- iconPath: string,
- key: string,
- name: string
- }>
-};
-*/
-
-export default function OAuthProviders(props /*: Props */) {
- return (
- <section className="oauth-providers">
- <ul>
- {props.identityProviders.map(identityProvider => (
- <li key={identityProvider.key}>
- <a
- href={`${window.baseUrl}/sessions/init/${identityProvider.key}`}
- style={{ backgroundColor: identityProvider.backgroundColor }}
- // $FlowFixMe formatLabel is always defined through defaultProps
- title={props.formatLabel(identityProvider.name)}>
- <img
- alt={identityProvider.name}
- width="20"
- height="20"
- src={window.baseUrl + identityProvider.iconPath}
- />
- <span>
- {/* $FlowFixMe formatLabel is always defined through defaultProps */}
- {props.formatLabel(identityProvider.name)}
- </span>
- </a>
- </li>
- ))}
- </ul>
- </section>
- );
-}
-
-OAuthProviders.defaultProps = {
- formatLabel: (name /*: string */) => translateWithParameters('login.login_with_x', name)
-};
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { translateWithParameters } from '../../../helpers/l10n';
+import { IdentityProvider } from '../../../api/users';
+import { getBaseUrl } from '../../../helpers/urls';
+
+interface Props {
+ formatLabel?: (name: string) => string;
+ identityProviders: IdentityProvider[];
+}
+
+export default function OAuthProviders(props: Props) {
+ const formatLabel = props.formatLabel || defaultFormatLabel;
+ return (
+ <section className="oauth-providers">
+ <ul>
+ {props.identityProviders.map(identityProvider => (
+ <li key={identityProvider.key}>
+ <a
+ href={`${getBaseUrl()}/sessions/init/${identityProvider.key}`}
+ style={{ backgroundColor: identityProvider.backgroundColor }}
+ title={formatLabel(identityProvider.name)}>
+ <img
+ alt={identityProvider.name}
+ width="20"
+ height="20"
+ src={getBaseUrl() + identityProvider.iconPath}
+ />
+ <span>{formatLabel(identityProvider.name)}</span>
+ </a>
+ </li>
+ ))}
+ </ul>
+ </section>
+ );
+}
+
+function defaultFormatLabel(name: string) {
+ return translateWithParameters('login.login_with_x', name);
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import SimpleContainer from '../../../app/components/SimpleContainer';
-
-/*::
-type Props = {
- children?: React.Element<*> | Array<React.Element<*>>
-};
-*/
-
-export default function SimpleSessionsContainer({ children } /*: Props */) {
- return <SimpleContainer hideLoggedInInfo={true}>{children}</SimpleContainer>;
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import SimpleContainer from '../../../app/components/SimpleContainer';
+
+interface Props {
+ children?: React.ReactElement<any>;
+}
+
+export default function SimpleSessionsContainer({ children }: Props) {
+ return <SimpleContainer hideLoggedInInfo={true}>{children}</SimpleContainer>;
+}
*/
import * as React from 'react';
import { Link } from 'react-router';
+import { translate } from '../../../helpers/l10n';
interface Props {
location: {
return (
<div className="text-center">
- <p id="unauthorized">
- {"You're not authorized to access this page. Please contact the administrator."}
- </p>
+ <p id="unauthorized">{translate('unauthorized.message')}</p>
- {!!message && <p className="spacer-top">Reason : {message}</p>}
+ {!!message && (
+ <p className="spacer-top">
+ {translate('unauthorized.reason')} {message}
+ </p>
+ )}
<div className="big-spacer-top">
- <Link to="/">Home</Link>
+ <Link to="/">{translate('layout.home')}</Link>
</div>
</div>
);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import LoginForm from '../LoginForm';
-import { change, click, submit } from '../../../../helpers/testUtils';
-
-const identityProvider = {
- backgroundColor: '#000',
- iconPath: '/some/path',
- key: 'foo',
- name: 'foo'
-};
-
-it('logs in with simple credentials', () => {
- const onSubmit = jest.fn();
- const wrapper = shallow(<LoginForm identityProviders={[]} onSubmit={onSubmit} />);
- expect(wrapper).toMatchSnapshot();
-
- change(wrapper.find('#login'), 'admin');
- change(wrapper.find('#password'), 'admin');
- submit(wrapper.find('form'));
-
- expect(onSubmit).toBeCalledWith('admin', 'admin');
-});
-
-it('logs in with identity provider', () => {
- const wrapper = shallow(
- <LoginForm identityProviders={[identityProvider]} onSubmit={jest.fn()} />
- );
- expect(wrapper).toMatchSnapshot();
-});
-
-it('expands more options', () => {
- const wrapper = shallow(
- <LoginForm identityProviders={[identityProvider]} onSubmit={jest.fn()} />
- );
- expect(wrapper).toMatchSnapshot();
-
- click(wrapper.find('.js-more-options'));
- expect(wrapper).toMatchSnapshot();
-});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { shallow } from 'enzyme';
+import LoginForm from '../LoginForm';
+import { change, click, submit } from '../../../../helpers/testUtils';
+
+const identityProvider = {
+ backgroundColor: '#000',
+ iconPath: '/some/path',
+ key: 'foo',
+ name: 'foo'
+};
+
+it('logs in with simple credentials', () => {
+ const onSubmit = jest.fn();
+ const wrapper = shallow(<LoginForm identityProviders={[]} onSubmit={onSubmit} />);
+ expect(wrapper).toMatchSnapshot();
+
+ change(wrapper.find('#login'), 'admin');
+ change(wrapper.find('#password'), 'admin');
+ submit(wrapper.find('form'));
+
+ expect(onSubmit).toBeCalledWith('admin', 'admin');
+});
+
+it('logs in with identity provider', () => {
+ const wrapper = shallow(
+ <LoginForm identityProviders={[identityProvider]} onSubmit={jest.fn()} />
+ );
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('expands more options', () => {
+ const wrapper = shallow(
+ <LoginForm identityProviders={[identityProvider]} onSubmit={jest.fn()} />
+ );
+ expect(wrapper).toMatchSnapshot();
+
+ click(wrapper.find('.js-more-options'));
+ expect(wrapper).toMatchSnapshot();
+});
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`expands more options 1`] = `
-<div
- id="login_form"
->
- <h1
- className="maintenance-title text-center"
- >
- login.login_to_sonarqube
- </h1>
- <OAuthProviders
- formatLabel={[Function]}
- identityProviders={
- Array [
- Object {
- "backgroundColor": "#000",
- "iconPath": "/some/path",
- "key": "foo",
- "name": "foo",
- },
- ]
- }
- />
- <div
- className="text-center"
- >
- <a
- className="small text-muted js-more-options"
- href="#"
- onClick={[Function]}
- >
- login.more_options
- </a>
- </div>
-</div>
-`;
-
-exports[`expands more options 2`] = `
-<div
- id="login_form"
->
- <h1
- className="maintenance-title text-center"
- >
- login.login_to_sonarqube
- </h1>
- <OAuthProviders
- formatLabel={[Function]}
- identityProviders={
- Array [
- Object {
- "backgroundColor": "#000",
- "iconPath": "/some/path",
- "key": "foo",
- "name": "foo",
- },
- ]
- }
- />
- <form
- onSubmit={[Function]}
- >
- <Connect(GlobalMessages) />
- <div
- className="big-spacer-bottom"
- >
- <label
- className="login-label"
- htmlFor="login"
- >
- login
- </label>
- <input
- autoFocus={true}
- className="login-input"
- id="login"
- maxLength="255"
- name="login"
- onChange={[Function]}
- placeholder="login"
- required={true}
- type="text"
- value=""
- />
- </div>
- <div
- className="big-spacer-bottom"
- >
- <label
- className="login-label"
- htmlFor="password"
- >
- password
- </label>
- <input
- className="login-input"
- id="password"
- name="password"
- onChange={[Function]}
- placeholder="password"
- required={true}
- type="password"
- value=""
- />
- </div>
- <div>
- <div
- className="text-right overflow-hidden"
- >
- <button
- name="commit"
- type="submit"
- >
- sessions.log_in
- </button>
- <a
- className="spacer-left"
- href="/"
- >
- cancel
- </a>
- </div>
- </div>
- </form>
-</div>
-`;
-
-exports[`logs in with identity provider 1`] = `
-<div
- id="login_form"
->
- <h1
- className="maintenance-title text-center"
- >
- login.login_to_sonarqube
- </h1>
- <OAuthProviders
- formatLabel={[Function]}
- identityProviders={
- Array [
- Object {
- "backgroundColor": "#000",
- "iconPath": "/some/path",
- "key": "foo",
- "name": "foo",
- },
- ]
- }
- />
- <div
- className="text-center"
- >
- <a
- className="small text-muted js-more-options"
- href="#"
- onClick={[Function]}
- >
- login.more_options
- </a>
- </div>
-</div>
-`;
-
-exports[`logs in with simple credentials 1`] = `
-<div
- id="login_form"
->
- <h1
- className="maintenance-title text-center"
- >
- login.login_to_sonarqube
- </h1>
- <form
- onSubmit={[Function]}
- >
- <Connect(GlobalMessages) />
- <div
- className="big-spacer-bottom"
- >
- <label
- className="login-label"
- htmlFor="login"
- >
- login
- </label>
- <input
- autoFocus={true}
- className="login-input"
- id="login"
- maxLength="255"
- name="login"
- onChange={[Function]}
- placeholder="login"
- required={true}
- type="text"
- value=""
- />
- </div>
- <div
- className="big-spacer-bottom"
- >
- <label
- className="login-label"
- htmlFor="password"
- >
- password
- </label>
- <input
- className="login-input"
- id="password"
- name="password"
- onChange={[Function]}
- placeholder="password"
- required={true}
- type="password"
- value=""
- />
- </div>
- <div>
- <div
- className="text-right overflow-hidden"
- >
- <button
- name="commit"
- type="submit"
- >
- sessions.log_in
- </button>
- <a
- className="spacer-left"
- href="/"
- >
- cancel
- </a>
- </div>
- </div>
- </form>
-</div>
-`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`expands more options 1`] = `
+<div
+ id="login_form"
+>
+ <h1
+ className="maintenance-title text-center"
+ >
+ login.login_to_sonarqube
+ </h1>
+ <OAuthProviders
+ identityProviders={
+ Array [
+ Object {
+ "backgroundColor": "#000",
+ "iconPath": "/some/path",
+ "key": "foo",
+ "name": "foo",
+ },
+ ]
+ }
+ />
+ <div
+ className="text-center"
+ >
+ <a
+ className="small text-muted js-more-options"
+ href="#"
+ onClick={[Function]}
+ >
+ login.more_options
+ </a>
+ </div>
+</div>
+`;
+
+exports[`expands more options 2`] = `
+<div
+ id="login_form"
+>
+ <h1
+ className="maintenance-title text-center"
+ >
+ login.login_to_sonarqube
+ </h1>
+ <OAuthProviders
+ identityProviders={
+ Array [
+ Object {
+ "backgroundColor": "#000",
+ "iconPath": "/some/path",
+ "key": "foo",
+ "name": "foo",
+ },
+ ]
+ }
+ />
+ <form
+ onSubmit={[Function]}
+ >
+ <Connect(GlobalMessages) />
+ <div
+ className="big-spacer-bottom"
+ >
+ <label
+ className="login-label"
+ htmlFor="login"
+ >
+ login
+ </label>
+ <input
+ autoFocus={true}
+ className="login-input"
+ id="login"
+ maxLength={255}
+ name="login"
+ onChange={[Function]}
+ placeholder="login"
+ required={true}
+ type="text"
+ value=""
+ />
+ </div>
+ <div
+ className="big-spacer-bottom"
+ >
+ <label
+ className="login-label"
+ htmlFor="password"
+ >
+ password
+ </label>
+ <input
+ className="login-input"
+ id="password"
+ name="password"
+ onChange={[Function]}
+ placeholder="password"
+ required={true}
+ type="password"
+ value=""
+ />
+ </div>
+ <div>
+ <div
+ className="text-right overflow-hidden"
+ >
+ <button
+ name="commit"
+ type="submit"
+ >
+ sessions.log_in
+ </button>
+ <Link
+ className="spacer-left"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/"
+ >
+ cancel
+ </Link>
+ </div>
+ </div>
+ </form>
+</div>
+`;
+
+exports[`logs in with identity provider 1`] = `
+<div
+ id="login_form"
+>
+ <h1
+ className="maintenance-title text-center"
+ >
+ login.login_to_sonarqube
+ </h1>
+ <OAuthProviders
+ identityProviders={
+ Array [
+ Object {
+ "backgroundColor": "#000",
+ "iconPath": "/some/path",
+ "key": "foo",
+ "name": "foo",
+ },
+ ]
+ }
+ />
+ <div
+ className="text-center"
+ >
+ <a
+ className="small text-muted js-more-options"
+ href="#"
+ onClick={[Function]}
+ >
+ login.more_options
+ </a>
+ </div>
+</div>
+`;
+
+exports[`logs in with simple credentials 1`] = `
+<div
+ id="login_form"
+>
+ <h1
+ className="maintenance-title text-center"
+ >
+ login.login_to_sonarqube
+ </h1>
+ <form
+ onSubmit={[Function]}
+ >
+ <Connect(GlobalMessages) />
+ <div
+ className="big-spacer-bottom"
+ >
+ <label
+ className="login-label"
+ htmlFor="login"
+ >
+ login
+ </label>
+ <input
+ autoFocus={true}
+ className="login-input"
+ id="login"
+ maxLength={255}
+ name="login"
+ onChange={[Function]}
+ placeholder="login"
+ required={true}
+ type="text"
+ value=""
+ />
+ </div>
+ <div
+ className="big-spacer-bottom"
+ >
+ <label
+ className="login-label"
+ htmlFor="password"
+ >
+ password
+ </label>
+ <input
+ className="login-input"
+ id="password"
+ name="password"
+ onChange={[Function]}
+ placeholder="password"
+ required={true}
+ type="password"
+ value=""
+ />
+ </div>
+ <div>
+ <div
+ className="text-right overflow-hidden"
+ >
+ <button
+ name="commit"
+ type="submit"
+ >
+ sessions.log_in
+ </button>
+ <Link
+ className="spacer-left"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/"
+ >
+ cancel
+ </Link>
+ </div>
+ </div>
+ </form>
+</div>
+`;
login.more_options=More options
login.login_with_x=Log in with {0}
+unauthorized.message=You're not authorized to access this page. Please contact the administrator.
+unauthorized.reason=Reason:
+
#------------------------------------------------------------------------------
#
# USERS & GROUPS PAGE
<tr>
<td>assertText</td>
<td>bd</td>
- <td>*Reason : A functional error has happened*</td>
+ <td>*Reason: A functional error has happened*</td>
</tr>
</tbody>
</table>
<tr>
<td>waitForText</td>
<td>bd</td>
- <td>*You're not authorized to access this page. Please contact the administrator.*Reason : 'fake-base-id-provider' users are not allowed to sign up*</td>
+ <td>*You're not authorized to access this page. Please contact the administrator.*Reason: 'fake-base-id-provider' users are not allowed to sign up*</td>
</tr>
</tbody>
</table>
<tr>
<td>assertText</td>
<td>bd</td>
- <td>*Reason : A functional error has happened*</td>
+ <td>*Reason: A functional error has happened*</td>
</tr>
</tbody>
</table>
<tr>
<td>waitForText</td>
<td>bd</td>
- <td>*You're not authorized to access this page. Please contact the administrator.*Reason : 'fake-oauth2-id-provider' users are not allowed to sign up*</td>
+ <td>*You're not authorized to access this page. Please contact the administrator.*Reason: 'fake-oauth2-id-provider' users are not allowed to sign up*</td>
</tr>
</tbody>
</table>