feat(backend-git-gateway): handle identity disabled error message (#3002)

This commit is contained in:
Erez Rokah 2020-01-06 21:10:37 +02:00 committed by Shawn Erquhart
parent b54d42fcfe
commit b5ffccdac5
5 changed files with 428 additions and 11 deletions

View File

@ -60,6 +60,9 @@ if (window.netlifyIdentity) {
window.netlifyIdentity.on('logout', () => {
component && component.handleIdentityLogout();
});
window.netlifyIdentity.on('error', err => {
component && component.handleIdentityError(err);
});
}
export default class GitGatewayAuthenticationPage extends React.Component {
@ -88,6 +91,15 @@ export default class GitGatewayAuthenticationPage extends React.Component {
window.netlifyIdentity.open();
};
handleIdentityError = err => {
if (err?.message?.match(/^Failed to load settings from.+\.netlify\/identity$/)) {
window.netlifyIdentity.close();
this.setState({
errors: { identity: this.props.t('auth.errors.identitySettings') },
});
}
};
handleIdentity = () => {
const user = window.netlifyIdentity.currentUser();
if (user) {
@ -102,6 +114,7 @@ export default class GitGatewayAuthenticationPage extends React.Component {
inProgress: PropTypes.bool.isRequired,
error: PropTypes.node,
config: ImmutablePropTypes.map,
t: PropTypes.func.isRequired,
};
state = { email: '', password: '', errors: {} };
@ -114,12 +127,13 @@ export default class GitGatewayAuthenticationPage extends React.Component {
e.preventDefault();
const { email, password } = this.state;
const { t } = this.props;
const errors = {};
if (!email) {
errors.email = 'Make sure to enter your email.';
errors.email = t('auth.errors.email');
}
if (!password) {
errors.password = 'Please enter your password.';
errors.password = t('auth.errors.password');
}
if (Object.keys(errors).length > 0) {
@ -142,16 +156,34 @@ export default class GitGatewayAuthenticationPage extends React.Component {
render() {
const { errors } = this.state;
const { error, inProgress, config } = this.props;
const { error, inProgress, config, t } = this.props;
if (window.netlifyIdentity) {
return (
<AuthenticationPage
logoUrl={config.get('logo_url')}
onLogin={this.handleIdentity}
renderButtonContent={() => 'Login with Netlify Identity'}
/>
);
if (errors.identity) {
return (
<AuthenticationPage
logoUrl={config.get('logo_url')}
onLogin={this.handleIdentity}
renderPageContent={() => (
<a
href="https://docs.netlify.com/visitor-access/git-gateway/#setup-and-settings"
target="_blank"
rel="noopener noreferrer"
>
{errors.identity}
</a>
)}
/>
);
} else {
return (
<AuthenticationPage
logoUrl={config.get('logo_url')}
onLogin={this.handleIdentity}
renderButtonContent={() => t('auth.loginWithNetlifyIdentity')}
/>
);
}
}
return (
@ -179,7 +211,7 @@ export default class GitGatewayAuthenticationPage extends React.Component {
onChange={partial(this.handleChange, 'password')}
/>
<LoginButton disabled={inProgress}>
{inProgress ? 'Logging in...' : 'Login'}
{inProgress ? t('auth.loggingIn') : t('auth.login')}
</LoginButton>
</AuthForm>
)}

View File

@ -0,0 +1,42 @@
import React from 'react';
import { Map } from 'immutable';
import { render } from '@testing-library/react';
window.netlifyIdentity = {
currentUser: jest.fn(),
on: jest.fn(),
close: jest.fn(),
};
describe('GitGatewayAuthenticationPage', () => {
const props = {
config: Map({ logo_url: 'logo_url' }),
t: jest.fn(key => key),
onLogin: jest.fn(),
inProgress: false,
};
beforeEach(() => {
jest.clearAllMocks();
jest.resetModules();
});
it('should render with identity error', () => {
const { default: GitGatewayAuthenticationPage } = require('../AuthenticationPage');
const { asFragment } = render(<GitGatewayAuthenticationPage {...props} />);
const errorCallback = window.netlifyIdentity.on.mock.calls.find(call => call[0] === 'error')[1];
errorCallback(
new Error('Failed to load settings from https://site.netlify.com/.netlify/identity'),
);
expect(asFragment()).toMatchSnapshot();
});
it('should render with no identity error', () => {
const { default: GitGatewayAuthenticationPage } = require('../AuthenticationPage');
const { asFragment } = render(<GitGatewayAuthenticationPage {...props} />);
expect(asFragment()).toMatchSnapshot();
});
});

File diff suppressed because one or more lines are too long

View File

@ -132,6 +132,7 @@ class App extends React.Component {
authEndpoint: this.props.config.getIn(['backend', 'auth_endpoint']),
config: this.props.config,
clearHash: () => history.replace('/'),
t,
})}
</div>
);

View File

@ -1,4 +1,15 @@
const en = {
auth: {
login: 'Login',
loggingIn: 'Logging in...',
loginWithNetlifyIdentity: 'Login with Netlify Identity',
errors: {
email: 'Make sure to enter your email.',
password: 'Please enter your password.',
identitySettings:
'Unable to access identity settings. When using git-gateway backend make sure to enable Identity service and Git Gateway.',
},
},
app: {
header: {
content: 'Contents',