Skip to content

Commit

Permalink
Merge pull request #29 from Yidadaa/bugfix-0325
Browse files Browse the repository at this point in the history
v1.2 bug fix, ui improvement and access control by code
  • Loading branch information
Yidadaa committed Mar 26, 2023
2 parents 15e49e8 + d0d1673 commit 5cdcaac
Show file tree
Hide file tree
Showing 17 changed files with 227 additions and 84 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ If you would like to contribute your API key, you can email it to the author and

如果你按照上述步骤一键部署了自己的项目,可能会发现总是提示“存在更新”的问题,这是由于 Vercel 会默认为你创建一个新项目而不是 fork 本项目,这会导致无法正确地检测更新。
推荐你按照下列步骤重新部署:

- 删除掉原先的 repo;
- fork 本项目;
- 前往 vercel 控制台,删除掉原先的 project,然后新建 project,选择你刚刚 fork 出来的项目重新进行部署即可;
Expand All @@ -74,6 +75,7 @@ If you would like to contribute your API key, you can email it to the author and
If you have deployed your own project with just one click following the steps above, you may encounter the issue of "Updates Available" constantly showing up. This is because Vercel will create a new project for you by default instead of forking this project, resulting in the inability to detect updates correctly.

We recommend that you follow the steps below to re-deploy:

- Delete the original repo;
- Fork this project;
- Go to the Vercel dashboard, delete the original project, then create a new project and select the project you just forked to redeploy;
Expand All @@ -83,6 +85,24 @@ This project will be continuously maintained. If you want to keep the code repos

You can star or watch this project or follow author to get release notifictions in time.

## 访问控制 Access Control

本项目提供有限的权限控制功能,请在环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义控制码:

```
code1,code2,code3
```

增加或修改该环境变量后,请重新部署项目使改动生效。

This project provides limited access control. Please add an environment variable named `CODE` on the environment variables page. The value should be a custom control code separated by comma like this:

```
code1,code2,code3
```

After adding or modifying this environment variable, please redeploy the project for the changes to take effect.

## 开发 Development

点击下方按钮,开始二次开发:
Expand Down
16 changes: 16 additions & 0 deletions app/api/access.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import md5 from "spark-md5";

export function getAccessCodes(): Set<string> {
const code = process.env.CODE;

try {
const codes = (code?.split(",") ?? [])
.filter((v) => !!v)
.map((v) => md5.hash(v.trim()));
return new Set(codes);
} catch (e) {
return new Set();
}
}

export const ACCESS_CODES = getAccessCodes();
29 changes: 27 additions & 2 deletions app/components/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useRef, useMemo } from "react";

import EmojiPicker, { Theme as EmojiTheme } from "emoji-picker-react";

Expand All @@ -17,6 +17,7 @@ import {
Theme,
ALL_MODELS,
useUpdateStore,
useAccessStore,
} from "../store";
import { Avatar } from "./home";

Expand All @@ -38,7 +39,7 @@ function SettingItem(props: {
<div className={styles["settings-sub-title"]}>{props.subTitle}</div>
)}
</div>
<div>{props.children}</div>
{props.children}
</ListItem>
);
}
Expand Down Expand Up @@ -71,6 +72,12 @@ export function Settings(props: { closeSettings: () => void }) {
checkUpdate();
}, []);

const accessStore = useAccessStore();
const enabledAccessControl = useMemo(
() => accessStore.enabledAccessControl(),
[]
);

return (
<>
<div className={styles["window-header"]}>
Expand Down Expand Up @@ -232,6 +239,24 @@ export function Settings(props: { closeSettings: () => void }) {
</div>
</List>
<List>
{enabledAccessControl ? (
<SettingItem
title={Locale.Settings.AccessCode.Title}
subTitle={Locale.Settings.AccessCode.SubTitle}
>
<input
value={accessStore.accessCode}
type="text"
placeholder={Locale.Settings.AccessCode.Placeholder}
onChange={(e) => {
accessStore.updateCode(e.currentTarget.value);
}}
></input>
</SettingItem>
) : (
<></>
)}

<SettingItem
title={Locale.Settings.HistoryCount.Title}
subTitle={Locale.Settings.HistoryCount.SubTitle}
Expand Down
25 changes: 1 addition & 24 deletions app/icons/export.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 24 additions & 3 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
/* eslint-disable @next/next/no-page-custom-font */
import "./styles/globals.scss";
import "./styles/markdown.scss";
import "./styles/prism.scss";
import process from "child_process";
import { ACCESS_CODES } from "./api/access";

const COMMIT_ID = process
.execSync("git rev-parse --short HEAD")
.toString()
.trim();

export const metadata = {
title: "ChatGPT Next Web",
description: "Your personal ChatGPT Chat Bot."
description: "Your personal ChatGPT Chat Bot.",
};

const COMMIT_ID = process.env.COMMIT_ID
function Meta() {
const metas = {
version: COMMIT_ID,
access: ACCESS_CODES.size > 0 ? "enabled" : "disabled",
};

return (
<>
{Object.entries(metas).map(([k, v]) => (
<meta name={k} content={v} key={k} />
))}
</>
);
}

export default function RootLayout({
children,
Expand All @@ -21,7 +42,7 @@ export default function RootLayout({
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta name="version" content={COMMIT_ID} />
<Meta />
<link rel="manifest" href="/site.webmanifest"></link>
<link rel="preconnect" href="https://fonts.googleapis.com"></link>
<link rel="preconnect" href="https://fonts.gstatic.com"></link>
Expand Down
8 changes: 8 additions & 0 deletions app/locales/cn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const cn = {
WIP: "该功能仍在开发中……",
Error: {
Unauthorized: "现在是未授权状态,请在设置页填写授权码。",
},
ChatItem: {
ChatItemCount: (count: number) => `${count} 条对话`,
},
Expand Down Expand Up @@ -65,6 +68,11 @@ const cn = {
Title: "历史消息长度压缩阈值",
SubTitle: "当未压缩的历史消息超过该值时,将进行压缩",
},
AccessCode: {
Title: "访问码",
SubTitle: "现在是受控访问状态",
Placeholder: "请输入访问码",
},
Model: "模型 (model)",
Temperature: {
Title: "随机性 (temperature)",
Expand Down
9 changes: 9 additions & 0 deletions app/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import type { LocaleType } from "./index";

const en: LocaleType = {
WIP: "WIP...",
Error: {
Unauthorized:
"Unauthorized access, please enter access code in settings page.",
},
ChatItem: {
ChatItemCount: (count: number) => `${count} messages`,
},
Expand Down Expand Up @@ -69,6 +73,11 @@ const en: LocaleType = {
SubTitle:
"Will compress if uncompressed messages length exceeds the value",
},
AccessCode: {
Title: "Access Code",
SubTitle: "Access control enabled",
Placeholder: "Need Access Code",
},
Model: "Model",
Temperature: {
Title: "Temperature",
Expand Down
26 changes: 23 additions & 3 deletions app/requests.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ChatRequest, ChatReponse } from "./api/chat/typing";
import { filterConfig, Message, ModelConfig } from "./store";
import { filterConfig, Message, ModelConfig, useAccessStore } from "./store";
import Locale from "./locales";

const TIME_OUT_MS = 30000;

Expand All @@ -26,13 +27,25 @@ const makeRequestParam = (
};
};

function getHeaders() {
const accessStore = useAccessStore.getState();
let headers: Record<string, string> = {};

if (accessStore.enabledAccessControl()) {
headers["access-code"] = accessStore.accessCode;
}

return headers;
}

export async function requestChat(messages: Message[]) {
const req: ChatRequest = makeRequestParam(messages, { filterBot: true });

const res = await fetch("/api/chat", {
method: "POST",
headers: {
"Content-Type": "application/json",
...getHeaders(),
},
body: JSON.stringify(req),
});
Expand Down Expand Up @@ -69,6 +82,7 @@ export async function requestChatStream(
method: "POST",
headers: {
"Content-Type": "application/json",
...getHeaders(),
},
body: JSON.stringify(req),
signal: controller.signal,
Expand All @@ -82,6 +96,8 @@ export async function requestChatStream(
controller.abort();
};

console.log(res);

if (res.ok) {
const reader = res.body?.getReader();
const decoder = new TextDecoder();
Expand All @@ -102,14 +118,18 @@ export async function requestChatStream(
}
}

finish();
} else if (res.status === 401) {
console.error("Anauthorized");
responseText = Locale.Error.Unauthorized;
finish();
} else {
console.error("Stream Error");
options?.onError(new Error("Stream Error"));
}
} catch (err) {
console.error("NetWork Error");
options?.onError(new Error("NetWork Error"));
console.error("NetWork Error", err);
options?.onError(err as Error);
}
}

Expand Down
30 changes: 30 additions & 0 deletions app/store/access.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { queryMeta } from "../utils";

export interface AccessControlStore {
accessCode: string;

updateCode: (_: string) => void;
enabledAccessControl: () => boolean;
}

export const ACCESS_KEY = "access-control";

export const useAccessStore = create<AccessControlStore>()(
persist(
(set, get) => ({
accessCode: "",
enabledAccessControl() {
return queryMeta("access") === "enabled";
},
updateCode(code: string) {
set((state) => ({ accessCode: code }));
},
}),
{
name: ACCESS_KEY,
version: 1,
}
)
);
1 change: 1 addition & 0 deletions app/store/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ export const useChatStore = create<ChatStore>()(
onMessage(content, done) {
if (done) {
botMessage.streaming = false;
botMessage.content = content;
get().onNewMessage(botMessage);
} else {
botMessage.content = content;
Expand Down
1 change: 1 addition & 0 deletions app/store/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./app";
export * from "./update";
export * from "./access";
4 changes: 3 additions & 1 deletion app/styles/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ input[type="range"]::-webkit-slider-thumb:hover {
width: 24px;
}

input[type="number"] {
input[type="number"],
input[type="text"] {
appearance: none;
border-radius: 10px;
border: var(--border-in-light);
Expand All @@ -176,6 +177,7 @@ input[type="number"] {
background: var(--white);
color: var(--black);
padding: 0 10px;
max-width: 50%;
}

div.math {
Expand Down

1 comment on commit 5cdcaac

@vercel
Copy link

@vercel vercel bot commented on 5cdcaac Mar 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.