refactor: use latest authing sdk

This commit is contained in:
tiddlygit-test 2021-05-15 20:03:26 +08:00
parent f9c12a8225
commit 3fa4f1e8f5
7 changed files with 135 additions and 94 deletions

57
package-lock.json generated
View file

@ -4738,6 +4738,48 @@
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"dev": true
},
"authing-js-sdk": {
"version": "4.19.5",
"resolved": "https://registry.npmjs.org/authing-js-sdk/-/authing-js-sdk-4.19.5.tgz",
"integrity": "sha512-rV1l1w/Xw1nf5Zh3E8QzuTR2N4N+oOTA2YlDvv50beetpbutyD74bf6fgDvL0WP2Tbi1ek7ZNICiNVSmipkuqw==",
"requires": {
"axios": "^0.19.2",
"crypto-js": "^4.0.0",
"jsencrypt": "^3.1.0",
"jwt-decode": "^2.2.0"
},
"dependencies": {
"axios": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
"requires": {
"follow-redirects": "1.5.10"
}
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"author-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz",
@ -7569,6 +7611,11 @@
"randomfill": "^1.0.3"
}
},
"crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"csp-html-webpack-plugin": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/csp-html-webpack-plugin/-/csp-html-webpack-plugin-5.1.0.tgz",
@ -14878,6 +14925,11 @@
}
}
},
"jsencrypt": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.2.0.tgz",
"integrity": "sha512-Y/WBrCYRP1A2I1OEXxqurO+W3AC5uXhiArprpYQ0Y8/1Dc3NaiINAyCLx7HzXGwN7xvW3s5xpeOTdwD7lD1SQQ=="
},
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@ -15075,6 +15127,11 @@
"integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
"dev": true
},
"jwt-decode": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
},
"keyv": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",

View file

@ -94,6 +94,7 @@
"@dnd-kit/sortable": "1.0.2",
"@dnd-kit/utilities": "1.0.2",
"@tiddlygit/tiddlywiki": "5.1.24-prerelease.20210331",
"authing-js-sdk": "4.19.5",
"beautiful-react-hooks": "0.31.1",
"bluebird": "3.7.2",
"chokidar": "3.5.1",

View file

@ -7,7 +7,7 @@ import { TextField, Button } from '@material-ui/core';
import { SupportedStorageServices } from '@services/types';
import { useUserInfoObservable } from '@services/auth/hooks';
import { ServiceEmailTypes, ServiceTokenTypes, ServiceUserNameTypes } from '@services/auth/interface';
import { useAuthing } from './gitTokenHooks';
import { useAuth } from './gitTokenHooks';
const AuthingLoginButton = styled(Button)`
width: 100%;
@ -25,22 +25,7 @@ export function GitTokenForm(props: {
const { children, storageService } = props;
const { t } = useTranslation();
const authing = useAuthing();
const onFailure = useCallback((error: Error) => {
console.error(error);
}, []);
const onClickLogin = useCallback(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 {
await authing.login();
} catch (error) {
onFailure(error);
}
}, [authing, onFailure]);
const [onClickLogin] = useAuth(storageService);
const userInfo = useUserInfoObservable();
if (userInfo === undefined) {

View file

@ -1,84 +1,51 @@
import { useCallback, useEffect, useMemo } from 'react';
import AuthingSSO, { ITrackSessionResult } from '@authing/sso';
import { AuthenticationClient } from 'authing-js-sdk';
import { ServiceTokenTypes, ServiceUserNameTypes, ServiceEmailTypes } from '@services/auth/interface';
import { SupportedStorageServices, IAuthingUserInfo } from '@services/types';
import { APP_ID, APP_DOMAIN } from '@/constants/auth';
export function useTokenFromAuthingRedirect(authing: AuthingSSO, callback?: () => void): void {
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,
};
// DEBUG: console
console.log(`nextUserInfo`, nextUserInfo);
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?.();
}
}
},
[callback],
);
const onClickLogout = useCallback(async () => {
const { code, message } = await authing.logout();
await window.service.window.clearStorageData();
// DEBUG: console
console.log(`{ code, message }`, { code, message });
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 {
export function useAuth(storageService: SupportedStorageServices): [() => Promise<void>, () => Promise<void>] {
const authing = useMemo(
() =>
new AuthingSSO({
new AuthenticationClient({
appId: APP_ID,
appDomain: APP_DOMAIN,
redirectUrl: 'http://localhost:3000',
appHost: APP_DOMAIN,
}),
[],
);
return authing;
const onFailure = useCallback((error: Error) => {
console.error(error);
}, []);
const onClickLogout = useCallback(async () => {
await authing.logout();
await window.service.window.clearStorageData();
}, [authing]);
const onClickLogin = useCallback(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 {
await authing.social.authorize(storageService, {
onSuccess: async (user) => {
// DEBUG: console
console.log('user', user);
const thirdPartyIdentity = user.identities?.find((identity) => identity?.provider === storageService);
await Promise.all([
thirdPartyIdentity?.accessToken !== undefined &&
window.service.auth.set(`${storageService}-token` as ServiceTokenTypes, thirdPartyIdentity.accessToken),
window.service.auth.set(`${storageService}-userName` as ServiceUserNameTypes, user.username),
window.service.auth.set(`${storageService}-email` as ServiceEmailTypes, user.email),
]);
},
onError: (code, message) => onFailure(new Error(message + String(code))),
});
} catch (error) {
onFailure(error);
}
}, [authing.social, onFailure, storageService]);
return [onClickLogin, onClickLogout];
}

View file

@ -1,3 +1,3 @@
export const APP_ID = '5efdd30e56a87fb76b52809d';
export const APP_DOMAIN = 'tiddlygit-desktop.authing.cn';
export const APP_DOMAIN = 'https://tiddlygit-desktop.authing.cn';
export const GITHUB_GRAPHQL_API = 'https://api.github.com/graphql';

View file

@ -18,7 +18,7 @@ import { CloneWikiDoneButton } from './CloneWikiDoneButton';
import { IErrorInWhichComponent, useIsCreateMainWorkspace, useIsCreateSyncedWorkspace, useWikiWorkspaceForm } from './useForm';
import { TokenForm } from '@/components/TokenForm';
import { useAuthing, useTokenFromAuthingRedirect } from '@/components/TokenForm/gitTokenHooks';
// import { useAuthing, useTokenFromAuthingRedirect } from '@/components/TokenForm/gitTokenHooks';
import { GitRepoUrlForm } from './GitRepoUrlForm';
enum CreateWorkspaceTabs {
@ -64,11 +64,7 @@ export default function AddWorkspace(): JSX.Element {
}
}, [isCreateSyncedWorkspace, storageProvider, storageProviderSetter]);
const authing = useAuthing();
useTokenFromAuthingRedirect(
authing,
useCallback(() => isCreateSyncedWorkspaceSetter(true), [isCreateSyncedWorkspaceSetter]),
);
// const [onClickLogin] = useAuth(storageService);
const formProps = {
form: form,

View file

@ -51,3 +51,38 @@ export const AuthenticationServiceIPCDescriptor = {
reset: ProxyPropertyType.Function,
},
};
export interface IGithubOAuthResult {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: string;
site_admin: boolean;
name: any;
company: any;
blog: string;
location: any;
email: any;
hireable: any;
bio: any;
twitter_username: any;
public_repos: number;
public_gists: number;
followers: number;
following: number;
created_at: string;
updated_at: string;
}