mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-07 16:16:37 +08:00
[修复] 修复github登录问题
This commit is contained in:
@@ -165,7 +165,7 @@ curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/unin
|
|||||||
卸载脚本会先停止并移除 `openflare-agent.service`、删除整个 `/opt/openflare-agent` 目录,然后根据卸载前保存的 `agent.json` 判断 OpenResty 安装方式:
|
卸载脚本会先停止并移除 `openflare-agent.service`、删除整个 `/opt/openflare-agent` 目录,然后根据卸载前保存的 `agent.json` 判断 OpenResty 安装方式:
|
||||||
|
|
||||||
* Docker 模式:删除对应 OpenResty 容器,并尝试移除镜像
|
* Docker 模式:删除对应 OpenResty 容器,并尝试移除镜像
|
||||||
* 本机 `openresty_path` 模式:不改动本机 OpenResty
|
* 本机 `openresty_path` 模式:不改动本机 OpenResty,只提示用户手动卸载
|
||||||
|
|
||||||
### 3. 发布第一份配置
|
### 3. 发布第一份配置
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { InlineMessage } from '@/components/feedback/inline-message';
|
import { InlineMessage } from '@/components/feedback/inline-message';
|
||||||
import { LoadingState } from '@/components/feedback/loading-state';
|
import { LoadingState } from '@/components/feedback/loading-state';
|
||||||
@@ -14,8 +14,10 @@ export function GitHubOAuthCallback() {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const { setUser } = useAuth();
|
const { setUser } = useAuth();
|
||||||
|
const handledCodeRef = useRef<string | null>(null);
|
||||||
const [prompt, setPrompt] = useState('正在处理 GitHub 授权结果...');
|
const [prompt, setPrompt] = useState('正在处理 GitHub 授权结果...');
|
||||||
const [message, setMessage] = useState<{ tone: 'danger' | 'success'; text: string } | null>(null);
|
const [message, setMessage] = useState<{ tone: 'danger' | 'success'; text: string } | null>(null);
|
||||||
|
const code = searchParams?.get('code')?.trim() ?? '';
|
||||||
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: exchangeGitHubCode,
|
mutationFn: exchangeGitHubCode,
|
||||||
@@ -31,15 +33,19 @@ export function GitHubOAuthCallback() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const code = searchParams?.get('code');
|
|
||||||
if (!code) {
|
if (!code) {
|
||||||
setPrompt('缺少授权 code');
|
setPrompt('缺少授权 code');
|
||||||
setMessage({ tone: 'danger', text: '未收到 GitHub 授权参数,请返回登录页重试。' });
|
setMessage({ tone: 'danger', text: '未收到 GitHub 授权参数,请返回登录页重试。' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (handledCodeRef.current === code) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handledCodeRef.current = code;
|
||||||
mutation.mutate(code);
|
mutation.mutate(code);
|
||||||
}, [mutation, searchParams]);
|
}, [code, mutation]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppCard title='GitHub OAuth 回调' description={prompt}>
|
<AppCard title='GitHub OAuth 回调' description={prompt}>
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
|
import { render, waitFor } from '@testing-library/react';
|
||||||
|
import { StrictMode, type ReactNode } from 'react';
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
|
import { GitHubOAuthCallback } from '@/features/auth/components/github-oauth-callback';
|
||||||
|
|
||||||
|
const replaceMock = vi.fn();
|
||||||
|
const setUserMock = vi.fn();
|
||||||
|
const exchangeGitHubCodeMock = vi.fn();
|
||||||
|
|
||||||
|
vi.mock('next/navigation', () => ({
|
||||||
|
useRouter: () => ({
|
||||||
|
replace: replaceMock,
|
||||||
|
}),
|
||||||
|
useSearchParams: () => new URLSearchParams('code=github-code-123'),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@/components/providers/auth-provider', () => ({
|
||||||
|
useAuth: () => ({
|
||||||
|
setUser: setUserMock,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@/features/auth/api/auth', () => ({
|
||||||
|
exchangeGitHubCode: (code: string) => exchangeGitHubCodeMock(code),
|
||||||
|
}));
|
||||||
|
|
||||||
|
function createQueryClient() {
|
||||||
|
return new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
retry: false,
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
retry: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderWithProviders(ui: ReactNode) {
|
||||||
|
const queryClient = createQueryClient();
|
||||||
|
|
||||||
|
return render(
|
||||||
|
<StrictMode>
|
||||||
|
<QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>
|
||||||
|
</StrictMode>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('GitHubOAuthCallback', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
replaceMock.mockReset();
|
||||||
|
setUserMock.mockReset();
|
||||||
|
exchangeGitHubCodeMock.mockReset();
|
||||||
|
exchangeGitHubCodeMock.mockResolvedValue({
|
||||||
|
id: 1,
|
||||||
|
username: 'github-user',
|
||||||
|
role: 1,
|
||||||
|
status: 1,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exchanges the same GitHub code only once', async () => {
|
||||||
|
const view = renderWithProviders(<GitHubOAuthCallback />);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(exchangeGitHubCodeMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
view.rerender(
|
||||||
|
<StrictMode>
|
||||||
|
<QueryClientProvider client={createQueryClient()}>
|
||||||
|
<GitHubOAuthCallback />
|
||||||
|
</QueryClientProvider>
|
||||||
|
</StrictMode>,
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(replaceMock).toHaveBeenCalledWith('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exchangeGitHubCodeMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(exchangeGitHubCodeMock).toHaveBeenCalledWith('github-code-123');
|
||||||
|
expect(setUserMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user