diff --git a/src/components/TokenForm/GitTokenForm.tsx b/src/components/TokenForm/GitTokenForm.tsx
index dffc360b..3d81641c 100644
--- a/src/components/TokenForm/GitTokenForm.tsx
+++ b/src/components/TokenForm/GitTokenForm.tsx
@@ -10,6 +10,7 @@ import { useUserInfoObservable } from '@services/auth/hooks';
import { usePromiseValueAndSetter } from '@/helpers/useServiceValue';
import { APP_ID, APP_DOMAIN } from '@/constants/auth';
import { ServiceEmailTypes, ServiceTokenTypes, ServiceUserNameTypes } from '@services/auth/interface';
+import { useAuthing } from './gitTokenHooks';
const AuthingLoginButton = styled(Button)`
white-space: nowrap;
@@ -28,80 +29,12 @@ export function GitTokenForm(props: {
const { children, storageService } = props;
const { t } = useTranslation();
- /**
- * 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 authing = useMemo(
- () =>
- new AuthingSSO({
- appId: APP_ID,
- appDomain: APP_DOMAIN,
- redirectUrl: 'http://localhost:3000',
- }),
- [],
- );
+ const authing = useAuthing();
const onFailure = useCallback((error: Error) => {
console.error(error);
}, []);
- const onLoginSuccessResponse = useCallback(
- async (response: ITrackSessionResult) => {
- // DEBUG: console
- console.log(`response`, response);
- if ('userInfo' in response && response.userInfo?.thirdPartyIdentity?.accessToken !== undefined) {
- const accessTokenToSet = response?.userInfo?.thirdPartyIdentity?.accessToken;
- 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,
- };
- void window.service.auth.set(`${storageService}-token` as ServiceTokenTypes, accessTokenToSet);
- void window.service.auth.set(`${storageService}-userName` as ServiceUserNameTypes, nextUserInfo.username);
- void window.service.auth.set(`${storageService}-email` as ServiceEmailTypes, nextUserInfo.email);
- if (userName === undefined || (userName === '' && nextUserInfo.username !== userName)) {
- userNameSetter(nextUserInfo.username);
- }
- }
- }
- },
- [storageService, 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 {
- onFailure(new Error(message));
- }
- }, [authing, onFailure]);
-
- // 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]);
-
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();
@@ -114,8 +47,6 @@ export function GitTokenForm(props: {
}, [authing, onFailure]);
const userInfo = useUserInfoObservable();
- // DEBUG: console
- console.log(`userInfo`, JSON.stringify(userInfo));
if (userInfo === undefined) {
return
Loading...
;
}
diff --git a/src/components/TokenForm/gitTokenHooks.ts b/src/components/TokenForm/gitTokenHooks.ts
new file mode 100644
index 00000000..1831bb0b
--- /dev/null
+++ b/src/components/TokenForm/gitTokenHooks.ts
@@ -0,0 +1,92 @@
+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;
+}
diff --git a/src/pages/AddWorkspace/index.tsx b/src/pages/AddWorkspace/index.tsx
index 55e7c11d..384629fc 100644
--- a/src/pages/AddWorkspace/index.tsx
+++ b/src/pages/AddWorkspace/index.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useCallback } from 'react';
import styled from 'styled-components';
import { useTranslation } from 'react-i18next';
import { AppBar, Paper, Tab } from '@material-ui/core';
@@ -16,6 +16,7 @@ import { CloneWikiForm } from './CloneWikiForm';
import { CloneWikiDoneButton } from './CloneWikiDoneButton';
import { useIsCreateMainWorkspace, useIsCreateSyncedWorkspace, useWikiWorkspaceForm } from './useForm';
+import { useAuthing, useTokenFromAuthingRedirect } from '@/components/TokenForm/gitTokenHooks';
enum CreateWorkspaceTabs {
CloneOnlineWiki = 'CloneOnlineWiki',
@@ -50,6 +51,12 @@ export default function AddWorkspace(): JSX.Element {
const [isCreateSyncedWorkspace, isCreateSyncedWorkspaceSetter] = useIsCreateSyncedWorkspace();
const [isCreateMainWorkspace, isCreateMainWorkspaceSetter] = useIsCreateMainWorkspace();
+ const authing = useAuthing();
+ useTokenFromAuthingRedirect(
+ authing,
+ useCallback(() => isCreateSyncedWorkspaceSetter(true), []),
+ );
+
const form = useWikiWorkspaceForm();
return (
diff --git a/src/preload/common/authing-postmessage.ts b/src/preload/common/authing-postmessage.ts
index 741f021d..20f48380 100644
--- a/src/preload/common/authing-postmessage.ts
+++ b/src/preload/common/authing-postmessage.ts
@@ -44,6 +44,8 @@ interface IAuthingPostMessageEvent {
window.addEventListener(
'message',
(event: MessageEvent) => {
+ // DEBUG: console
+ console.log(`event`, event);
if (typeof event?.data?.code === 'number' && typeof event?.data?.data?.token === 'string' && event?.data.from !== 'preload') {
// This message will be catch by this handler again, so we add a 'from' to indicate that it is re-send by ourself
// we re-send this, so authing in this window can catch it
diff --git a/src/type.d.ts b/src/type.d.ts
index 80256e7c..8bbd123c 100644
--- a/src/type.d.ts
+++ b/src/type.d.ts
@@ -41,6 +41,7 @@ declare module '@authing/sso' {
oauth?: string;
thirdPartyIdentity?: {
accessToken?: string;
+ provider?: string;
};
}