TidGi-Desktop/src/components/TokenForm/gitTokenHooks.ts
2021-04-14 01:19:47 +08:00

92 lines
3.6 KiB
TypeScript

import { useCallback, useEffect, useMemo } from 'react';
import AuthingSSO, { ITrackSessionResult } from '@authing/sso';
import { ServiceTokenTypes, ServiceUserNameTypes, ServiceEmailTypes } from '@services/auth/interface';
import { SupportedStorageServices, IAuthingUserInfo } from '@services/types';
import { APP_ID, APP_DOMAIN } from '@/constants/auth';
import { usePromiseValueAndSetter } from '@/helpers/useServiceValue';
export function useTokenFromAuthingRedirect(authing: AuthingSSO, callback?: () => void): void {
/**
* Update tiddlywiki's editor user name when first time creating new workspace
*/
const [userName, userNameSetter] = usePromiseValueAndSetter(
async () => await window.service.auth.get('userName'),
async (newUserName) => await window.service.auth.set('userName', newUserName),
);
const onLoginSuccessResponse = useCallback(
async (response: ITrackSessionResult) => {
// DEBUG: console
console.log(`response`, response);
if (!('userInfo' in response)) return;
const accessTokenToSet = response?.userInfo?.thirdPartyIdentity?.accessToken;
const provider = response?.userInfo?.thirdPartyIdentity?.provider as SupportedStorageServices;
if (accessTokenToSet !== undefined && provider !== undefined) {
if (!Object.values(SupportedStorageServices).includes(provider)) {
throw new Error(`${provider} not in SupportedStorageServices`);
}
// DEBUG: console
console.log(`provider`, provider);
const authDataString = response?.userInfo?.oauth;
// all data we need
if (accessTokenToSet !== undefined && authDataString !== undefined) {
const authData = JSON.parse(authDataString);
// DEBUG: console
console.log(`authData`, authData);
const nextUserInfo: IAuthingUserInfo = {
...response.userInfo,
...authData,
...response.userInfo?.thirdPartyIdentity,
};
await Promise.all([
window.service.auth.set(`${provider}-token` as ServiceTokenTypes, accessTokenToSet),
window.service.auth.set(`${provider}-userName` as ServiceUserNameTypes, nextUserInfo.username),
window.service.auth.set(`${provider}-email` as ServiceEmailTypes, nextUserInfo.email),
]);
callback();
if (userName === undefined || (userName === '' && nextUserInfo.username !== userName)) {
userNameSetter(nextUserInfo.username);
}
}
}
},
[userName, userNameSetter],
);
const onClickLogout = useCallback(async () => {
const { code, message } = await authing.logout();
await window.service.window.clearStorageData();
if (code === 200) {
// TODO: clear the input
} else {
throw new Error(message);
}
}, [authing]);
// after authing redirect to 3rd party page and success, it will redirect back, we then check if login is success on component mount
useEffect(() => {
void (async () => {
const response = await authing.trackSession();
// we logout so login into github won't block use from login into gitlab
await onClickLogout();
const isLogin = response?.session !== undefined && response?.session !== null;
if (isLogin) {
await onLoginSuccessResponse(response);
}
})();
}, [authing, onLoginSuccessResponse, onClickLogout]);
}
export function useAuthing(): AuthingSSO {
const authing = useMemo(
() =>
new AuthingSSO({
appId: APP_ID,
appDomain: APP_DOMAIN,
redirectUrl: 'http://localhost:3000',
}),
[],
);
return authing;
}