refactor: login method (#1676)

This commit is contained in:
Himself65
2023-03-23 16:29:29 -05:00
committed by GitHub
parent a415e4aa5c
commit 56acb2bdeb
22 changed files with 626 additions and 61 deletions

View File

@@ -4,7 +4,7 @@ import { messages } from '@affine/datacenter';
import type React from 'react';
import { memo, useEffect, useState } from 'react';
import { useOnGoogleLogout } from '../../../hooks/use-on-google-logout';
import { useAffineLogOut } from '../../../hooks/affine/use-affine-log-out';
import { apis } from '../../../shared/apis';
declare global {
@@ -17,7 +17,7 @@ declare global {
export const MessageCenter: React.FC = memo(function MessageCenter() {
const [popup, setPopup] = useState(false);
const onLogout = useOnGoogleLogout();
const onLogout = useAffineLogOut();
useEffect(() => {
const listener = (
event: CustomEvent<{

View File

@@ -0,0 +1,26 @@
import { toast } from '@affine/component';
import {
createAffineAuth,
setLoginStorage,
SignMethod,
} from '@affine/workspace/affine/login';
import { useRouter } from 'next/router';
import { useCallback } from 'react';
import { apis } from '../../shared/apis';
export const affineAuth = createAffineAuth();
export function useAffineLogIn() {
const router = useRouter();
return useCallback(async () => {
const response = await affineAuth.generateToken(SignMethod.Google);
if (response) {
setLoginStorage(response);
apis.auth.setLogin(response);
router.reload();
} else {
toast('Login failed');
}
}, [router]);
}

View File

@@ -1,13 +1,14 @@
import { clearLoginStorage } from '@affine/workspace/affine/login';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { useSetAtom } from 'jotai';
import { useRouter } from 'next/router';
import { useCallback } from 'react';
import { jotaiWorkspacesAtom } from '../atoms';
import { WorkspacePlugins } from '../plugins';
import { apis } from '../shared/apis';
import { jotaiWorkspacesAtom } from '../../atoms';
import { WorkspacePlugins } from '../../plugins';
import { apis } from '../../shared/apis';
export function useOnGoogleLogout() {
export function useAffineLogOut() {
const set = useSetAtom(jotaiWorkspacesAtom);
const router = useRouter();
return useCallback(() => {
@@ -18,6 +19,7 @@ export function useOnGoogleLogout() {
)
);
WorkspacePlugins[WorkspaceFlavour.AFFINE].cleanup?.();
clearLoginStorage();
router.reload();
}, [router, set]);
}

View File

@@ -0,0 +1,36 @@
import { DebugLogger } from '@affine/debug';
import {
getLoginStorage,
isExpired,
parseIdToken,
setLoginStorage,
} from '@affine/workspace/affine/login';
import useSWR from 'swr';
import { apis } from '../../shared/apis';
import { affineAuth } from './use-affine-log-in';
const logger = new DebugLogger('auth-token');
const revalidate = async () => {
const storage = getLoginStorage();
if (storage) {
const tokenMessage = parseIdToken(storage.token);
logger.debug('revalidate affine user');
if (isExpired(tokenMessage)) {
logger.debug('need to refresh token');
const response = await affineAuth.refreshToken(storage);
if (response) {
setLoginStorage(response);
apis.auth.setLogin(response);
}
}
}
return true;
};
export function useAffineRefreshAuthToken() {
useSWR('autoRefreshToken', {
fetcher: revalidate,
});
}

View File

@@ -19,6 +19,7 @@ import {
import { HelpIsland } from '../components/pure/help-island';
import { PageLoading } from '../components/pure/loading';
import WorkSpaceSliderBar from '../components/pure/workspace-slider-bar';
import { useAffineRefreshAuthToken } from '../hooks/affine/use-affine-refresh-auth-token';
import { useCurrentPageId } from '../hooks/current/use-current-page-id';
import { useCurrentWorkspace } from '../hooks/current/use-current-workspace';
import { useBlockSuiteWorkspaceHelper } from '../hooks/use-blocksuite-workspace-helper';
@@ -92,6 +93,11 @@ export const WorkspaceLayout: React.FC<React.PropsWithChildren> =
);
};
function AffineWorkspaceEffect() {
useAffineRefreshAuthToken();
return null;
}
export const WorkspaceLayoutInner: React.FC<React.PropsWithChildren> = ({
children,
}) => {
@@ -196,6 +202,7 @@ export const WorkspaceLayoutInner: React.FC<React.PropsWithChildren> = ({
paths={isPublicWorkspace ? publicPathGenerator : pathGenerator}
/>
<StyledWrapper>
<AffineWorkspaceEffect />
{children}
<StyledToolWrapper>
{/* fixme(himself65): remove this */}

View File

@@ -67,39 +67,6 @@ const App = function App({
>
<Head>
<title>AFFiNE</title>
<meta
name="viewport"
content="initial-scale=1, width=device-width"
/>
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:url" content="https://app.affine.pro/" />
<meta
name="twitter:title"
content="AFFiNEThere can be more than Notion and Miro."
/>
<meta
name="twitter:description"
content="There can be more than Notion and Miro. AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together."
/>
<meta name="twitter:site" content="@AffineOfficial" />
<meta
name="twitter:image"
content="https://affine.pro/og.jpeg"
/>
<meta
property="og:title"
content="AFFiNEThere can be more than Notion and Miro."
/>
<meta property="og:type" content="website" />
<meta
property="og:description"
content="There can be more than Notion and Miro. AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together."
/>
<meta property="og:url" content="https://app.affine.pro/" />
<meta
property="og:image"
content="https://affine.pro/og.jpeg"
/>
</Head>
{getLayout(<Component {...pageProps} />)}
</ProviderComposer>

View File

@@ -11,8 +11,16 @@ import {
} from '@affine/workspace/affine/login';
import { useAtom } from 'jotai';
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import { useMemo } from 'react';
const Viewer = dynamic(
() => import('@rich-data/viewer').then(m => ({ default: m.JsonViewer })),
{ ssr: false }
);
import { useTheme } from 'next-themes';
import { StyledPage, StyledWrapper } from '../../layouts/styles';
const LoginDevPage: NextPage = () => {
@@ -69,7 +77,24 @@ const LoginDevPage: NextPage = () => {
>
Reset Storage
</Button>
{user && JSON.stringify(user)}
<Button
onClick={async () => {
const status = await fetch('/api/workspace', {
method: 'GET',
headers: {
'Cache-Control': 'no-cache',
Authorization: getLoginStorage()?.token ?? '',
},
}).then(r => r.status);
toast(`Response Status: ${status}`);
}}
>
Check Permission
</Button>
<Viewer
theme={useTheme().resolvedTheme === 'light' ? 'light' : 'dark'}
value={user}
/>
</StyledWrapper>
</StyledPage>
);

View File

@@ -51,6 +51,30 @@ export default class AppDocument extends Document<{
/>
<link rel="icon" sizes="192x192" href="/chrome-192x192.png" />
<meta name="emotion-insertion-point" content="" />
<meta name="viewport" content="initial-scale=1, width=device-width" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:url" content="https://app.affine.pro/" />
<meta
name="twitter:title"
content="AFFiNEThere can be more than Notion and Miro."
/>
<meta
name="twitter:description"
content="There can be more than Notion and Miro. AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together."
/>
<meta name="twitter:site" content="@AffineOfficial" />
<meta name="twitter:image" content="https://affine.pro/og.jpeg" />
<meta
property="og:title"
content="AFFiNEThere can be more than Notion and Miro."
/>
<meta property="og:type" content="website" />
<meta
property="og:description"
content="There can be more than Notion and Miro. AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together."
/>
<meta property="og:url" content="https://app.affine.pro/" />
<meta property="og:image" content="https://affine.pro/og.jpeg" />
{this.props.emotionStyleTags}
</Head>
<body>

View File

@@ -9,13 +9,13 @@ import {
openCreateWorkspaceModalAtom,
openWorkspacesModalAtom,
} from '../atoms';
import { useAffineLogIn } from '../hooks/affine/use-affine-log-in';
import { useAffineLogOut } from '../hooks/affine/use-affine-log-out';
import { useCurrentUser } from '../hooks/current/use-current-user';
import { useCurrentWorkspace } from '../hooks/current/use-current-workspace';
import { useOnGoogleLogout } from '../hooks/use-on-google-logout';
import { useRouterHelper } from '../hooks/use-router-helper';
import { useWorkspaces, useWorkspacesHelper } from '../hooks/use-workspaces';
import { WorkspaceSubPath } from '../shared';
import { apis } from '../shared/apis';
const WorkspaceListModal = dynamic(
async () =>
@@ -69,12 +69,8 @@ export function Modals() {
},
[jumpToSubPath, setCurrentWorkspace, setOpenWorkspacesModal]
)}
onClickLogin={useCallback(() => {
apis.signInWithGoogle().then(() => {
router.reload();
});
}, [router])}
onClickLogout={useOnGoogleLogout()}
onClickLogin={useAffineLogIn()}
onClickLogout={useAffineLogOut()}
onCreateWorkspace={useCallback(() => {
setOpenCreateWorkspaceModal(true);
}, [setOpenCreateWorkspaceModal])}

View File

@@ -5,6 +5,10 @@ import {
GoogleAuth,
} from '@affine/datacenter';
import { config } from '@affine/env';
import {
createUserApis,
createWorkspaceApis,
} from '@affine/workspace/affine/api';
import { isValidIPAddress } from '../utils/is-valid-ip-address';
@@ -27,6 +31,22 @@ if (typeof window === 'undefined') {
params.get('prefixUrl') && (prefixUrl = params.get('prefixUrl') as string);
}
declare global {
// eslint-disable-next-line no-var
var affineApis:
| undefined
| (ReturnType<typeof createUserApis> &
ReturnType<typeof createWorkspaceApis>);
}
const affineApis = {} as ReturnType<typeof createUserApis> &
ReturnType<typeof createWorkspaceApis>;
Object.assign(affineApis, createUserApis(prefixUrl));
Object.assign(affineApis, createWorkspaceApis(prefixUrl));
if (!globalThis.affineApis) {
globalThis.affineApis = affineApis;
}
const bareAuth = createBareClient(prefixUrl);
const googleAuth = new GoogleAuth(bareAuth);
export const clientAuth = createAuthClient(bareAuth, googleAuth);