mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
refactor: login method (#1676)
This commit is contained in:
@@ -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<{
|
||||
|
||||
26
apps/web/src/hooks/affine/use-affine-log-in.ts
Normal file
26
apps/web/src/hooks/affine/use-affine-log-in.ts
Normal 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]);
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
36
apps/web/src/hooks/affine/use-affine-refresh-auth-token.ts
Normal file
36
apps/web/src/hooks/affine/use-affine-refresh-auth-token.ts
Normal 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,
|
||||
});
|
||||
}
|
||||
@@ -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 */}
|
||||
|
||||
@@ -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="AFFiNE:There 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="AFFiNE:There 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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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="AFFiNE:There 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="AFFiNE:There 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>
|
||||
|
||||
@@ -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])}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user