mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 16:23:41 +08:00 
			
		
		
		
	Merge pull request #1844 from Yidadaa/bugfix-0607
feat: close #741 add auth page
This commit is contained in:
		@@ -42,15 +42,19 @@ export async function requestOpenai(req: NextRequest) {
 | 
			
		||||
    },
 | 
			
		||||
    cache: "no-store",
 | 
			
		||||
    method: req.method,
 | 
			
		||||
    body: req.clone().body,
 | 
			
		||||
    body: req.body,
 | 
			
		||||
    signal: controller.signal,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // #1815 try to refuse gpt4 request
 | 
			
		||||
  if (DISABLE_GPT4) {
 | 
			
		||||
  if (DISABLE_GPT4 && req.body) {
 | 
			
		||||
    try {
 | 
			
		||||
      const clonedBody = await req.clone().json();
 | 
			
		||||
      if ((clonedBody?.model ?? "").includes("gpt-4")) {
 | 
			
		||||
      const clonedBody = await req.text();
 | 
			
		||||
      fetchOptions.body = clonedBody;
 | 
			
		||||
 | 
			
		||||
      const jsonBody = JSON.parse(clonedBody);
 | 
			
		||||
 | 
			
		||||
      if ((jsonBody?.model ?? "").includes("gpt-4")) {
 | 
			
		||||
        return NextResponse.json(
 | 
			
		||||
          {
 | 
			
		||||
            error: true,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								app/components/auth.module.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/components/auth.module.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
.auth-page {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
 | 
			
		||||
  .auth-logo {
 | 
			
		||||
    transform: scale(1.4);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .auth-title {
 | 
			
		||||
    font-size: 24px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    line-height: 2;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .auth-tips {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .auth-input {
 | 
			
		||||
    margin: 3vh 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .auth-actions {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
 | 
			
		||||
    button:not(:last-child) {
 | 
			
		||||
      margin-bottom: 10px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								app/components/auth.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								app/components/auth.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
import styles from "./auth.module.scss";
 | 
			
		||||
import { IconButton } from "./button";
 | 
			
		||||
 | 
			
		||||
import { useNavigate } from "react-router-dom";
 | 
			
		||||
import { Path } from "../constant";
 | 
			
		||||
import { useAccessStore } from "../store";
 | 
			
		||||
import Locale from "../locales";
 | 
			
		||||
 | 
			
		||||
import BotIcon from "../icons/bot.svg";
 | 
			
		||||
 | 
			
		||||
export function AuthPage() {
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
  const access = useAccessStore();
 | 
			
		||||
 | 
			
		||||
  const goHome = () => navigate(Path.Home);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={styles["auth-page"]}>
 | 
			
		||||
      <div className={`no-dark ${styles["auth-logo"]}`}>
 | 
			
		||||
        <BotIcon />
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div className={styles["auth-title"]}>{Locale.Auth.Title}</div>
 | 
			
		||||
      <div className={styles["auth-tips"]}>{Locale.Auth.Tips}</div>
 | 
			
		||||
 | 
			
		||||
      <input
 | 
			
		||||
        className={styles["auth-input"]}
 | 
			
		||||
        type="text"
 | 
			
		||||
        placeholder={Locale.Auth.Input}
 | 
			
		||||
        value={access.accessCode}
 | 
			
		||||
        onChange={(e) => {
 | 
			
		||||
          access.updateCode(e.currentTarget.value);
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      <div className={styles["auth-actions"]}>
 | 
			
		||||
        <IconButton
 | 
			
		||||
          text={Locale.Auth.Confirm}
 | 
			
		||||
          type="primary"
 | 
			
		||||
          onClick={goHome}
 | 
			
		||||
        />
 | 
			
		||||
        <IconButton text={Locale.Auth.Later} onClick={goHome} />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@@ -23,6 +23,7 @@ import {
 | 
			
		||||
} from "react-router-dom";
 | 
			
		||||
import { SideBar } from "./sidebar";
 | 
			
		||||
import { useAppConfig } from "../store/config";
 | 
			
		||||
import { AuthPage } from "./auth";
 | 
			
		||||
 | 
			
		||||
export function Loading(props: { noLogo?: boolean }) {
 | 
			
		||||
  return (
 | 
			
		||||
@@ -102,6 +103,7 @@ function Screen() {
 | 
			
		||||
  const config = useAppConfig();
 | 
			
		||||
  const location = useLocation();
 | 
			
		||||
  const isHome = location.pathname === Path.Home;
 | 
			
		||||
  const isAuth = location.pathname === Path.Auth;
 | 
			
		||||
  const isMobileScreen = useMobileScreen();
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
@@ -119,17 +121,25 @@ function Screen() {
 | 
			
		||||
        }`
 | 
			
		||||
      }
 | 
			
		||||
    >
 | 
			
		||||
      <SideBar className={isHome ? styles["sidebar-show"] : ""} />
 | 
			
		||||
      {isAuth ? (
 | 
			
		||||
        <>
 | 
			
		||||
          <AuthPage />
 | 
			
		||||
        </>
 | 
			
		||||
      ) : (
 | 
			
		||||
        <>
 | 
			
		||||
          <SideBar className={isHome ? styles["sidebar-show"] : ""} />
 | 
			
		||||
 | 
			
		||||
      <div className={styles["window-content"]} id={SlotID.AppBody}>
 | 
			
		||||
        <Routes>
 | 
			
		||||
          <Route path={Path.Home} element={<Chat />} />
 | 
			
		||||
          <Route path={Path.NewChat} element={<NewChat />} />
 | 
			
		||||
          <Route path={Path.Masks} element={<MaskPage />} />
 | 
			
		||||
          <Route path={Path.Chat} element={<Chat />} />
 | 
			
		||||
          <Route path={Path.Settings} element={<Settings />} />
 | 
			
		||||
        </Routes>
 | 
			
		||||
      </div>
 | 
			
		||||
          <div className={styles["window-content"]} id={SlotID.AppBody}>
 | 
			
		||||
            <Routes>
 | 
			
		||||
              <Route path={Path.Home} element={<Chat />} />
 | 
			
		||||
              <Route path={Path.NewChat} element={<NewChat />} />
 | 
			
		||||
              <Route path={Path.Masks} element={<MaskPage />} />
 | 
			
		||||
              <Route path={Path.Chat} element={<Chat />} />
 | 
			
		||||
              <Route path={Path.Settings} element={<Settings />} />
 | 
			
		||||
            </Routes>
 | 
			
		||||
          </div>
 | 
			
		||||
        </>
 | 
			
		||||
      )}
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ export enum Path {
 | 
			
		||||
  Settings = "/settings",
 | 
			
		||||
  NewChat = "/new-chat",
 | 
			
		||||
  Masks = "/masks",
 | 
			
		||||
  Auth = "/auth",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum SlotID {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,14 @@ const cn = {
 | 
			
		||||
  WIP: "该功能仍在开发中……",
 | 
			
		||||
  Error: {
 | 
			
		||||
    Unauthorized:
 | 
			
		||||
      "访问密码不正确或为空,请前往[设置](/#/settings)页输入正确的访问密码,或者填入你自己的 OpenAI API Key。",
 | 
			
		||||
      "访问密码不正确或为空,请前往[登录](/#/auth)页输入正确的访问密码,或者在[设置](/#/settings)页填入你自己的 OpenAI API Key。",
 | 
			
		||||
  },
 | 
			
		||||
  Auth: {
 | 
			
		||||
    Title: "需要密码",
 | 
			
		||||
    Tips: "管理员开启了密码验证,请在下方填入访问码",
 | 
			
		||||
    Input: "在此处填写访问码",
 | 
			
		||||
    Confirm: "确认",
 | 
			
		||||
    Later: "稍后再说",
 | 
			
		||||
  },
 | 
			
		||||
  ChatItem: {
 | 
			
		||||
    ChatItemCount: (count: number) => `${count} 条对话`,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,14 @@ const en: RequiredLocaleType = {
 | 
			
		||||
  WIP: "Coming Soon...",
 | 
			
		||||
  Error: {
 | 
			
		||||
    Unauthorized:
 | 
			
		||||
      "Unauthorized access, please enter access code in settings page.",
 | 
			
		||||
      "Unauthorized access, please enter access code in [auth](/#/auth) page.",
 | 
			
		||||
  },
 | 
			
		||||
  Auth: {
 | 
			
		||||
    Title: "Need Access Code",
 | 
			
		||||
    Tips: "Please enter access code below",
 | 
			
		||||
    Input: "access code",
 | 
			
		||||
    Confirm: "Confirm",
 | 
			
		||||
    Later: "Later",
 | 
			
		||||
  },
 | 
			
		||||
  ChatItem: {
 | 
			
		||||
    ChatItemCount: (count: number) => `${count} messages`,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user