fix(git-gateway): wait for identity widget to initialize (#3660)
This commit is contained in:
parent
213ae86b54
commit
6c229c5149
@ -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() {
|
||||
|
@ -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!();
|
||||
|
Loading…
x
Reference in New Issue
Block a user