feat: allow user use Authing to get token

This commit is contained in:
tiddlygit-test 2021-04-13 01:06:19 +08:00
parent af32534288
commit 79847adbb3
5 changed files with 118 additions and 192 deletions

View file

@ -1,77 +0,0 @@
import React from 'react';
import styled from 'styled-components';
import { useTranslation } from 'react-i18next';
import TextField from '@material-ui/core/TextField';
import GitHubLogin from './github-login';
import type { IAuthingUserInfo } from '@services/types';
import { useUserInfoObservable } from '@services/auth/hooks';
const GitTokenInput = styled(TextField)``;
export const setGithubToken = async (token: string | undefined): Promise<void> => await window.service.auth.set('github-token', token);
export const getGithubToken = async (): Promise<string | undefined> => await window.service.auth.get('github-token');
export function GithubTokenForm(props: { children?: JSX.Element | Array<JSX.Element | undefined | string> }): JSX.Element {
const { children } = props;
const { t } = useTranslation();
useEffect(() => {
// on startup, loading the cachedGithubToken
if (accessToken === undefined && cachedGithubToken !== undefined) {
graphqlClient.setHeader('Authorization', `bearer ${cachedGithubToken}`);
accessTokenSetter(cachedGithubToken);
} else if (accessToken !== undefined && accessToken !== cachedGithubToken) {
// if user or login button changed the token, we use latest token
Object.keys(graphqlClient.headers).map((key) => graphqlClient.removeHeader(key));
accessTokenSetter(accessToken);
void setGithubToken(accessToken);
}
}, [cachedGithubToken, accessToken]);
const userInfo = useUserInfoObservable();
if (userInfo === undefined) {
return <div>Loading...</div>;
}
return (
<>
<GitHubLogin
onSuccess={(response) => {
const accessTokenToSet = response?.userInfo?.thirdPartyIdentity?.accessToken;
const authDataString = response?.userInfo?.oauth;
if (accessTokenToSet !== undefined) {
void window.service.auth.set('github-token', accessTokenToSet);
}
// all data we need
if (accessTokenToSet !== undefined && authDataString !== undefined) {
const authData = JSON.parse(authDataString);
const nextUserInfo = {
...response.userInfo,
...authData,
...response.userInfo?.thirdPartyIdentity,
};
delete nextUserInfo.oauth;
delete nextUserInfo.thirdPartyIdentity;
void window.service.auth.set('github-userName', (nextUserInfo as IAuthingUserInfo).username);
}
}}
onLogout={() => {
void window.service.auth.set('github-token', '');
void window.service.auth.set('github-userName', '');
}}
onFailure={() => {
void window.service.auth.set('github-token', '');
void window.service.auth.set('github-userName', '');
}}
/>
<GitTokenInput
helperText={t('AddWorkspace.GitTokenDescription')}
fullWidth
onChange={(event) => {
void window.service.auth.set('github-token', event.target.value);
}}
value={userInfo['github-token']}
/>
{children}
</>
);
}

View file

@ -1,114 +0,0 @@
/* eslint-disable promise/no-nesting */
import React, { Component } from 'react';
import styled from 'styled-components';
import Button from '@material-ui/core/Button';
import GithubIcon from '@material-ui/icons/GitHub';
import AuthingSSO, { ILoginInfo } from '@authing/sso';
import { withTranslation } from 'react-i18next';
import { APP_DOMAIN, APP_ID } from '../../constants/auth';
const SyncToGithubButton = styled(Button)`
white-space: nowrap;
width: 100%;
`;
interface Props {
t: (x: string) => string;
onRequest: () => unknown;
onSuccess: (info: Partial<ILoginInfo>) => unknown;
onLogout: () => unknown;
onFailure: (error: Error) => unknown;
}
interface State {
isLogin: boolean;
}
class GitHubLogin extends Component<Props, State> {
static defaultProps: Partial<Props> = {
onRequest: () => {},
onSuccess: () => {},
onLogout: () => {},
onFailure: () => {},
};
auth: AuthingSSO;
intervalHandel?: NodeJS.Timeout;
constructor(props: Props) {
super(props);
this.state = {
isLogin: false,
};
this.auth = new AuthingSSO({
appId: APP_ID,
appDomain: APP_DOMAIN,
redirectUrl: 'http://localhost:3000',
});
this.updateLoginState();
}
async isLogin(): Promise<boolean> {
const { onSuccess, onLogout } = this.props;
const { session, ...rest } = await this.auth.trackSession();
const isLogin = session !== null && session !== undefined;
if (isLogin) {
onSuccess(rest);
} else {
onLogout();
}
return isLogin;
}
updateLoginState(): void {
this.intervalHandel = setInterval(() => {
void this.isLogin().then((isLogin) => {
this.setState({ isLogin });
if (this.intervalHandel !== undefined) {
clearInterval(this.intervalHandel);
}
});
}, 500);
}
render(): JSX.Element {
const { onRequest, onLogout, onFailure, t } = this.props;
const { isLogin } = this.state;
return isLogin ? (
<SyncToGithubButton
onClick={async () => {
const { code, message } = await this.auth.logout();
await window.service.window.clearStorageData();
if (code === 200) {
this.setState({ isLogin: false });
this.updateLoginState();
onLogout();
} else {
console.error(message);
}
}}
color="secondary"
endIcon={<GithubIcon />}>
{t('AddWorkspace.LogoutGithubAccount')}
</SyncToGithubButton>
) : (
<SyncToGithubButton
onClick={async () => {
// clear token first, otherwise github login window won't give us a chance to see the form
// void this.auth.logout();
// window.remote.clearStorageData();
try {
onRequest();
await this.auth.login();
} catch (error) {
onFailure(error);
}
}}
color="secondary"
endIcon={<GithubIcon />}>
{t('AddWorkspace.LoginGithubAccount')}
</SyncToGithubButton>
);
}
}
export default withTranslation()(GitHubLogin);