mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-11-12 20:23:45 +08:00
去掉sdk的引入,客户端也能直连
This commit is contained in:
@@ -4,7 +4,6 @@ import {
|
||||
StoreKey,
|
||||
ApiPath,
|
||||
OPENAI_BASE_URL,
|
||||
BEDROCK_BASE_URL,
|
||||
ANTHROPIC_BASE_URL,
|
||||
GEMINI_BASE_URL,
|
||||
BAIDU_BASE_URL,
|
||||
@@ -23,14 +22,12 @@ import { createPersistStore } from "../utils/store";
|
||||
import { ensure } from "../utils/clone";
|
||||
import { DEFAULT_CONFIG } from "./config";
|
||||
import { getModelProvider } from "../utils/model";
|
||||
import { encrypt, decrypt } from "../utils/encryption";
|
||||
|
||||
let fetchState = 0; // 0 not fetch, 1 fetching, 2 done
|
||||
|
||||
const isApp = getClientConfig()?.buildMode === "export";
|
||||
|
||||
const DEFAULT_OPENAI_URL = isApp ? OPENAI_BASE_URL : ApiPath.OpenAI;
|
||||
const DEFAULT_BEDROCK_URL = isApp ? BEDROCK_BASE_URL : ApiPath.Bedrock;
|
||||
|
||||
const DEFAULT_GOOGLE_URL = isApp ? GEMINI_BASE_URL : ApiPath.Google;
|
||||
|
||||
@@ -64,13 +61,6 @@ const DEFAULT_ACCESS_STATE = {
|
||||
openaiUrl: DEFAULT_OPENAI_URL,
|
||||
openaiApiKey: "",
|
||||
|
||||
// bedrock
|
||||
awsRegion: "",
|
||||
awsAccessKey: "",
|
||||
awsSecretKey: "",
|
||||
awsSessionToken: "",
|
||||
awsCognitoUser: false,
|
||||
|
||||
// azure
|
||||
azureUrl: "",
|
||||
azureApiKey: "",
|
||||
@@ -126,6 +116,12 @@ const DEFAULT_ACCESS_STATE = {
|
||||
chatglmUrl: DEFAULT_CHATGLM_URL,
|
||||
chatglmApiKey: "",
|
||||
|
||||
// aws bedrock
|
||||
awsRegion: "",
|
||||
awsAccessKey: "",
|
||||
awsSecretKey: "",
|
||||
awsSessionToken: "",
|
||||
|
||||
// server config
|
||||
needCode: true,
|
||||
hideUserApiKey: false,
|
||||
@@ -139,9 +135,6 @@ const DEFAULT_ACCESS_STATE = {
|
||||
edgeTTSVoiceName: "zh-CN-YunxiNeural",
|
||||
};
|
||||
|
||||
type AccessState = typeof DEFAULT_ACCESS_STATE;
|
||||
type BedrockCredentialKey = "awsAccessKey" | "awsSecretKey" | "awsSessionToken";
|
||||
|
||||
export const useAccessStore = createPersistStore(
|
||||
{ ...DEFAULT_ACCESS_STATE },
|
||||
|
||||
@@ -162,46 +155,6 @@ export const useAccessStore = createPersistStore(
|
||||
return ensure(get(), ["openaiApiKey"]);
|
||||
},
|
||||
|
||||
isValidBedrock() {
|
||||
const state = get();
|
||||
return (
|
||||
ensure(state, ["awsAccessKey", "awsSecretKey", "awsRegion"]) &&
|
||||
this.validateAwsCredentials(
|
||||
this.getDecryptedAwsCredential("awsAccessKey"),
|
||||
this.getDecryptedAwsCredential("awsSecretKey"),
|
||||
state.awsRegion,
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
validateAwsCredentials(
|
||||
accessKey: string,
|
||||
secretKey: string,
|
||||
region: string,
|
||||
) {
|
||||
// Comprehensive AWS credential validation
|
||||
const accessKeyRegex = /^(AKIA|A3T|ASIA)[A-Z0-9]{16}$/;
|
||||
const regionRegex = /^[a-z]{2}-[a-z]+-\d+$/;
|
||||
|
||||
return (
|
||||
accessKeyRegex.test(accessKey) && // Validate access key format
|
||||
secretKey.length === 40 && // Validate secret key length
|
||||
regionRegex.test(region) && // Validate region format
|
||||
accessKey !== "" &&
|
||||
secretKey !== "" &&
|
||||
region !== ""
|
||||
);
|
||||
},
|
||||
|
||||
setEncryptedAwsCredential(key: BedrockCredentialKey, value: string) {
|
||||
set({ [key]: encrypt(value) });
|
||||
},
|
||||
|
||||
getDecryptedAwsCredential(key: BedrockCredentialKey): string {
|
||||
const encryptedValue = get()[key];
|
||||
return encryptedValue ? decrypt(encryptedValue) : "";
|
||||
},
|
||||
|
||||
isValidAzure() {
|
||||
return ensure(get(), ["azureUrl", "azureApiKey", "azureApiVersion"]);
|
||||
},
|
||||
@@ -233,6 +186,7 @@ export const useAccessStore = createPersistStore(
|
||||
isValidMoonshot() {
|
||||
return ensure(get(), ["moonshotApiKey"]);
|
||||
},
|
||||
|
||||
isValidIflytek() {
|
||||
return ensure(get(), ["iflytekApiKey"]);
|
||||
},
|
||||
@@ -245,13 +199,16 @@ export const useAccessStore = createPersistStore(
|
||||
return ensure(get(), ["chatglmApiKey"]);
|
||||
},
|
||||
|
||||
isValidBedrock() {
|
||||
return ensure(get(), ["awsRegion", "awsAccessKey", "awsSecretKey"]);
|
||||
},
|
||||
|
||||
isAuthorized() {
|
||||
this.fetch();
|
||||
|
||||
// has token or has code or disabled access control
|
||||
return (
|
||||
this.isValidOpenAI() ||
|
||||
this.isValidBedrock() ||
|
||||
this.isValidAzure() ||
|
||||
this.isValidGoogle() ||
|
||||
this.isValidAnthropic() ||
|
||||
@@ -263,6 +220,7 @@ export const useAccessStore = createPersistStore(
|
||||
this.isValidIflytek() ||
|
||||
this.isValidXAI() ||
|
||||
this.isValidChatGLM() ||
|
||||
this.isValidBedrock() ||
|
||||
!this.enabledAccessControl() ||
|
||||
(this.enabledAccessControl() && ensure(get(), ["accessCode"]))
|
||||
);
|
||||
@@ -290,28 +248,8 @@ export const useAccessStore = createPersistStore(
|
||||
return res;
|
||||
})
|
||||
.then((res: DangerConfig) => {
|
||||
console.log("[Config] received DangerConfig server configuration");
|
||||
console.log("[Config] got config from server", res);
|
||||
set(() => ({ ...res }));
|
||||
return res;
|
||||
})
|
||||
.then((res: Partial<AccessState>) => {
|
||||
console.log("[Config] received AccessState server configuration");
|
||||
// Encrypt Bedrock-related sensitive data before storing
|
||||
const encryptedRes = { ...res };
|
||||
const keysToEncrypt: BedrockCredentialKey[] = [
|
||||
"awsAccessKey",
|
||||
"awsSecretKey",
|
||||
"awsSessionToken",
|
||||
];
|
||||
|
||||
keysToEncrypt.forEach((key) => {
|
||||
const value = encryptedRes[key];
|
||||
if (value) {
|
||||
(encryptedRes[key] as string) = encrypt(value as string);
|
||||
}
|
||||
});
|
||||
|
||||
set(() => ({ ...encryptedRes }));
|
||||
})
|
||||
.catch(() => {
|
||||
console.error("[Config] failed to fetch config");
|
||||
|
||||
Reference in New Issue
Block a user