fix(git-gateway): wait for identity widget to initialize (#3660)

This commit is contained in:
Erez Rokah 2020-04-30 17:46:07 +03:00 committed by GitHub
parent 213ae86b54
commit 6c229c5149
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 27 deletions

View File

@ -125,7 +125,7 @@ export default class GitGatewayAuthenticationPage extends React.Component {
this.setState({ ...this.state, [name]: e.target.value });
};
handleLogin = e => {
handleLogin = async e => {
e.preventDefault();
const { email, password } = this.state;
@ -143,17 +143,16 @@ export default class GitGatewayAuthenticationPage extends React.Component {
return;
}
GitGatewayAuthenticationPage.authClient
.login(this.state.email, this.state.password, true)
.then(user => {
this.props.onLogin(user);
})
.catch(error => {
this.setState({
errors: { server: error.description || error.msg || error },
loggingIn: false,
});
try {
const client = await GitGatewayAuthenticationPage.authClient();
const user = await client.login(this.state.email, this.state.password, true);
this.props.onLogin(user);
} catch (error) {
this.setState({
errors: { server: error.description || error.msg || error },
loggingIn: false,
});
}
};
render() {

View File

@ -33,9 +33,22 @@ import GitLabAPI from './GitLabAPI';
import AuthenticationPage from './AuthenticationPage';
import { getClient, Client } from './netlify-lfs-client';
type NetlifyIdentity = {
logout: () => void;
currentUser: () => User;
on: (event: string, args: unknown) => void;
init: () => void;
};
type AuthClient = {
logout: () => void;
currentUser: () => unknown;
login?(email: string, password: string, remember?: boolean): Promise<unknown>;
};
declare global {
interface Window {
netlifyIdentity?: { gotrue: GoTrue; logout: () => void };
netlifyIdentity?: NetlifyIdentity;
}
}
@ -69,6 +82,27 @@ function getEndpoint(endpoint: string, netlifySiteURL: string | null) {
return endpoint;
}
// wait for identity widget to initialize
// force init on timeout
let initPromise = Promise.resolve() as Promise<unknown>;
if (window.netlifyIdentity) {
let initialized = false;
initPromise = Promise.race([
new Promise(resolve => {
window.netlifyIdentity?.on('init', () => {
initialized = true;
resolve();
});
}),
new Promise(resolve => setTimeout(resolve, 2500)).then(() => {
if (!initialized) {
console.log('Manually initializing identity widget');
window.netlifyIdentity?.init();
}
}),
]);
}
interface NetlifyUser extends Credentials {
jwt: () => Promise<string>;
email: string;
@ -85,7 +119,8 @@ export default class GitGateway implements Implementation {
gatewayUrl: string;
netlifyLargeMediaURL: string;
backendType: string | null;
authClient: GoTrue;
apiUrl: string;
authClient?: AuthClient;
backend: GitHubBackend | GitLabBackend | BitbucketBackend | null;
acceptRoles?: string[];
tokenPromise?: () => Promise<string>;
@ -110,7 +145,7 @@ export default class GitGateway implements Implementation {
this.transformImages = config.backend.use_large_media_transforms_in_media_library || true;
const netlifySiteURL = localStorage.getItem('netlifySiteURL');
const APIUrl = getEndpoint(config.backend.identity_url || defaults.identity, netlifySiteURL);
this.apiUrl = getEndpoint(config.backend.identity_url || defaults.identity, netlifySiteURL);
this.gatewayUrl = getEndpoint(config.backend.gateway_url || defaults.gateway, netlifySiteURL);
this.netlifyLargeMediaURL = getEndpoint(
config.backend.large_media_url || defaults.largeMedia,
@ -125,18 +160,40 @@ export default class GitGateway implements Implementation {
this.backendType = null;
}
this.authClient = window.netlifyIdentity
? window.netlifyIdentity.gotrue
: new GoTrue({ APIUrl });
AuthenticationPage.authClient = this.authClient;
this.backend = null;
AuthenticationPage.authClient = () => this.getAuthClient();
}
isGitBackend() {
return true;
}
async getAuthClient() {
if (this.authClient) {
return this.authClient;
}
await initPromise;
if (window.netlifyIdentity) {
this.authClient = {
logout: () => window.netlifyIdentity?.logout(),
currentUser: () => window.netlifyIdentity?.currentUser(),
};
} else {
const goTrue = new GoTrue({ APIUrl: this.apiUrl });
this.authClient = {
logout: () => {
const user = goTrue.currentUser();
if (user) {
return user.logout();
}
},
currentUser: () => goTrue.currentUser(),
login: goTrue.login.bind(goTrue),
};
}
return this.authClient;
}
requestFunction = (req: ApiRequest) =>
this.tokenPromise!()
.then(
@ -233,8 +290,9 @@ export default class GitGateway implements Implementation {
return { name: userData.name, login: userData.email } as User;
});
}
restoreUser() {
const user = this.authClient && this.authClient.currentUser();
async restoreUser() {
const client = await this.getAuthClient();
const user = client.currentUser();
if (!user) return Promise.reject();
return this.authenticate(user as Credentials);
}
@ -242,12 +300,9 @@ export default class GitGateway implements Implementation {
return AuthenticationPage;
}
logout() {
if (window.netlifyIdentity) {
return window.netlifyIdentity.logout();
}
const user = this.authClient.currentUser();
return user && user.logout();
async logout() {
const client = await this.getAuthClient();
return client.logout();
}
getToken() {
return this.tokenPromise!();