mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-09 19:46:37 +08:00
Amplify
This commit is contained in:
parent
f021826220
commit
d44bb47efd
@ -1,4 +1,9 @@
|
||||
|
||||
USER_POOL_ID=
|
||||
|
||||
USER_POOL_CLIENT_ID=
|
||||
|
||||
|
||||
# Your openai api key. (required)
|
||||
OPENAI_API_KEY=sk-xxxx
|
||||
|
||||
|
4
app/auth/layout.module.scss
Normal file
4
app/auth/layout.module.scss
Normal file
@ -0,0 +1,4 @@
|
||||
.container {
|
||||
background-color: white;
|
||||
/* 其他样式 */
|
||||
}
|
23
app/auth/layout.tsx
Normal file
23
app/auth/layout.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
// app\auth\layout.tsx
|
||||
|
||||
import styles from "./layout.module.scss";
|
||||
|
||||
export default function AuthLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link rel="manifest" href="/site.webmanifest"></link>
|
||||
<script src="/serviceWorkerRegister.js" defer></script>
|
||||
</head>
|
||||
<body className={styles.container}>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
89
app/auth/login.module.scss
Normal file
89
app/auth/login.module.scss
Normal file
@ -0,0 +1,89 @@
|
||||
.loginContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.authenticator {
|
||||
// /* 覆盖全局样式 */
|
||||
input[type="number"],
|
||||
input[type="text"],
|
||||
input[type="password"] {
|
||||
-webkit-appearance: none !important;
|
||||
-moz-appearance: none !important;
|
||||
appearance: none !important;
|
||||
border-radius: var(
|
||||
--amplify-components-fieldcontrol-border-radius
|
||||
) !important;
|
||||
border: var(--amplify-components-fieldcontrol-border) !important;
|
||||
min-height: 36px !important;
|
||||
box-sizing: border-box !important;
|
||||
background: var(--amplify-components-fieldcontrol-background) !important;
|
||||
color: var(--amplify-components-fieldcontrol-color) !important;
|
||||
padding: var(--amplify-components-fieldcontrol-padding) !important;
|
||||
max-width: 100% !important;
|
||||
font-family: inherit !important;
|
||||
font-size: var(--amplify-components-fieldcontrol-font-size) !important;
|
||||
line-height: var(--amplify-components-fieldcontrol-line-height) !important;
|
||||
-webkit-padding-before: var(
|
||||
--amplify-components-fieldcontrol-padding-block-start
|
||||
) !important;
|
||||
padding-block-start: var(
|
||||
--amplify-components-fieldcontrol-padding-block-start
|
||||
) !important;
|
||||
-webkit-padding-after: var(
|
||||
--amplify-components-fieldcontrol-padding-block-end
|
||||
) !important;
|
||||
padding-block-end: var(
|
||||
--amplify-components-fieldcontrol-padding-block-end
|
||||
) !important;
|
||||
-webkit-padding-start: var(
|
||||
--amplify-components-fieldcontrol-padding-inline-start
|
||||
) !important;
|
||||
padding-inline-start: var(
|
||||
--amplify-components-fieldcontrol-padding-inline-start
|
||||
) !important;
|
||||
-webkit-padding-end: var(
|
||||
--amplify-components-fieldcontrol-padding-inline-end
|
||||
) !important;
|
||||
padding-inline-end: var(
|
||||
--amplify-components-fieldcontrol-padding-inline-end
|
||||
) !important;
|
||||
transition: all var(--amplify-components-fieldcontrol-transition-duration) !important;
|
||||
width: 100% !important;
|
||||
border-color: var(
|
||||
--amplify-components-fieldcontrol-border-color
|
||||
) !important;
|
||||
border-style: var(
|
||||
--amplify-components-fieldcontrol-border-style
|
||||
) !important;
|
||||
border-width: var(
|
||||
--amplify-components-fieldcontrol-border-width
|
||||
) !important;
|
||||
outline-color: var(
|
||||
--amplify-components-fieldcontrol-outline-color
|
||||
) !important;
|
||||
outline-style: var(
|
||||
--amplify-components-fieldcontrol-outline-style
|
||||
) !important;
|
||||
outline-width: var(
|
||||
--amplify-components-fieldcontrol-outline-width
|
||||
) !important;
|
||||
outline-offset: var(
|
||||
--amplify-components-fieldcontrol-outline-offset
|
||||
) !important;
|
||||
-webkit-user-select: text !important;
|
||||
-moz-user-select: text !important;
|
||||
user-select: text !important;
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
input[type="password"]::-ms-reveal,
|
||||
input[type="password"]::-ms-clear,
|
||||
input[type="password"]::-webkit-search-cancel-button,
|
||||
input[type="password"]::-webkit-search-decoration {
|
||||
display: none;
|
||||
}
|
||||
}
|
89
app/auth/login.tsx
Normal file
89
app/auth/login.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
"use client";
|
||||
// app\auth\login.tsx
|
||||
import { Authenticator, useAuthenticator } from "@aws-amplify/ui-react";
|
||||
import { Amplify, type ResourcesConfig } from "aws-amplify";
|
||||
import { Hub } from "aws-amplify/utils";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Path } from "../constant";
|
||||
import styles from "./login.module.scss";
|
||||
import "@aws-amplify/ui-react/styles.css";
|
||||
import {
|
||||
confirmSignIn,
|
||||
type ConfirmSignInInput,
|
||||
type ConfirmSignInOutput,
|
||||
} from "aws-amplify/auth";
|
||||
|
||||
// Hub.listen("auth", ({ payload }) => {
|
||||
// switch (payload.event) {
|
||||
// case "signedIn":
|
||||
// console.log("user have been signedIn successfully.");
|
||||
// const router = useRouter();
|
||||
// router.push(Path.Home);
|
||||
// break;
|
||||
// case "signedOut":
|
||||
// console.log("user have been signedOut successfully.");
|
||||
// break;
|
||||
// case "tokenRefresh":
|
||||
// console.log("auth tokens have been refreshed.");
|
||||
// break;
|
||||
// case "tokenRefresh_failure":
|
||||
// console.log("failure while refreshing auth tokens.");
|
||||
// break;
|
||||
// case "signInWithRedirect":
|
||||
// console.log("signInWithRedirect API has successfully been resolved.");
|
||||
// break;
|
||||
// case "signInWithRedirect_failure":
|
||||
// console.log("failure while trying to resolve signInWithRedirect API.");
|
||||
// break;
|
||||
// case "customOAuthState":
|
||||
// console.info("custom state returned from CognitoHosted UI");
|
||||
// break;
|
||||
// }
|
||||
// });
|
||||
|
||||
const authConfig: ResourcesConfig["Auth"] = {
|
||||
Cognito: {
|
||||
userPoolId: "eu-central-1_vu74Tv7SY",
|
||||
userPoolClientId: "6f4c2hie09ms17uvmo2qn1kmkh",
|
||||
//identityPoolId: "eu-central-1:d988e88f-5c19-4c89-841b-63c7a8d50b27",
|
||||
},
|
||||
};
|
||||
|
||||
Amplify.configure({
|
||||
Auth: authConfig,
|
||||
});
|
||||
|
||||
export function Login() {
|
||||
// const services = {
|
||||
// async handleConfirmSignIn(
|
||||
// input: ConfirmSignInInput,
|
||||
// ): Promise<ConfirmSignInOutput> {
|
||||
// try {
|
||||
// console.log("Confirming sign in", input);
|
||||
// const result = await confirmSignIn(input);
|
||||
// console.log("Sign in confirmed", result);
|
||||
// router.push(Path.Home);
|
||||
// return result;
|
||||
// } catch (error) {
|
||||
// console.error("Error confirming sign in", error);
|
||||
// throw error; // Ensure to throw the error to match the expected return type
|
||||
// }
|
||||
// },
|
||||
// };
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<div className={styles.loginContainer}>
|
||||
<Authenticator
|
||||
loginMechanisms={["email"]}
|
||||
socialProviders={["apple", "google"]}
|
||||
signUpAttributes={["name"]}
|
||||
//services={services}
|
||||
//variation="modal"
|
||||
className={styles.authenticator}
|
||||
></Authenticator>
|
||||
</div>
|
||||
);
|
||||
}
|
10
app/auth/page.tsx
Normal file
10
app/auth/page.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
//app\auth\page.tsx
|
||||
import { Login } from "./login";
|
||||
import { Authenticator } from "@aws-amplify/ui-react";
|
||||
export default function AuthPage() {
|
||||
return (
|
||||
<>
|
||||
<Login />
|
||||
</>
|
||||
);
|
||||
}
|
@ -231,10 +231,12 @@
|
||||
|
||||
animation: slide-in ease 0.3s;
|
||||
|
||||
$linear: linear-gradient(to right,
|
||||
rgba(0, 0, 0, 0),
|
||||
rgba(0, 0, 0, 1),
|
||||
rgba(0, 0, 0, 0));
|
||||
$linear: linear-gradient(
|
||||
to right,
|
||||
rgba(0, 0, 0, 0),
|
||||
rgba(0, 0, 0, 1),
|
||||
rgba(0, 0, 0, 0)
|
||||
);
|
||||
mask-image: $linear;
|
||||
|
||||
@mixin show {
|
||||
@ -367,7 +369,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.chat-message-user>.chat-message-container {
|
||||
.chat-message-user > .chat-message-container {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
@ -450,9 +452,8 @@
|
||||
border: rgba($color: #888, $alpha: 0.2) 1px solid;
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
$calc-image-width: calc(100vw/3*2/var(--image-count));
|
||||
$calc-image-width: calc(100vw / 3 * 2 / var(--image-count));
|
||||
|
||||
.chat-message-item-image-multi {
|
||||
width: $calc-image-width;
|
||||
@ -460,13 +461,18 @@
|
||||
}
|
||||
|
||||
.chat-message-item-image {
|
||||
max-width: calc(100vw/3*2);
|
||||
max-width: calc(100vw / 3 * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
$max-image-width: calc(calc(1200px - var(--sidebar-width))/3*2/var(--image-count));
|
||||
$image-width: calc(calc(var(--window-width) - var(--sidebar-width))/3*2/var(--image-count));
|
||||
$max-image-width: calc(
|
||||
calc(1200px - var(--sidebar-width)) / 3 * 2 / var(--image-count)
|
||||
);
|
||||
$image-width: calc(
|
||||
calc(var(--window-width) - var(--sidebar-width)) / 3 * 2 /
|
||||
var(--image-count)
|
||||
);
|
||||
|
||||
.chat-message-item-image-multi {
|
||||
width: $image-width;
|
||||
@ -476,7 +482,7 @@
|
||||
}
|
||||
|
||||
.chat-message-item-image {
|
||||
max-width: calc(calc(1200px - var(--sidebar-width))/3*2);
|
||||
max-width: calc(calc(1200px - var(--sidebar-width)) / 3 * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,7 +500,7 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.chat-message-user>.chat-message-container>.chat-message-item {
|
||||
.chat-message-user > .chat-message-container > .chat-message-item {
|
||||
background-color: var(--second);
|
||||
|
||||
&:hover {
|
||||
@ -605,7 +611,8 @@
|
||||
min-height: 68px;
|
||||
}
|
||||
|
||||
.chat-input:focus {}
|
||||
.chat-input:focus {
|
||||
}
|
||||
|
||||
.chat-input-send {
|
||||
background-color: var(--primary);
|
||||
|
@ -128,6 +128,7 @@ function Screen() {
|
||||
const location = useLocation();
|
||||
const isHome = location.pathname === Path.Home;
|
||||
const isAuth = location.pathname === Path.Auth;
|
||||
//const isLogin = location.pathname === Path.Login;
|
||||
const isMobileScreen = useMobileScreen();
|
||||
const shouldTightBorder =
|
||||
getClientConfig()?.isApp || (config.tightBorder && !isMobileScreen);
|
||||
|
@ -15,12 +15,13 @@ export const ANTHROPIC_BASE_URL = "https://api.anthropic.com";
|
||||
export const GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/";
|
||||
|
||||
export enum Path {
|
||||
Login = "/login",
|
||||
Home = "/",
|
||||
Chat = "/chat",
|
||||
Settings = "/settings",
|
||||
NewChat = "/new-chat",
|
||||
Masks = "/masks",
|
||||
Auth = "/auth",
|
||||
Auth = "/b-auth", //暂时修改
|
||||
}
|
||||
|
||||
export enum ApiPath {
|
||||
@ -182,6 +183,7 @@ const bedrockModels = [
|
||||
"claude-3-haiku",
|
||||
"claude-3-sonnet",
|
||||
"claude-3-opus",
|
||||
"knowledge-base-regulations",
|
||||
];
|
||||
|
||||
export const DEFAULT_MODELS = [
|
||||
|
2
app/global.d.ts
vendored
2
app/global.d.ts
vendored
@ -21,7 +21,7 @@ declare interface Window {
|
||||
writeBinaryFile(path: string, data: Uint8Array): Promise<void>;
|
||||
writeTextFile(path: string, data: string): Promise<void>;
|
||||
};
|
||||
notification:{
|
||||
notification: {
|
||||
requestPermission(): Promise<Permission>;
|
||||
isPermissionGranted(): Promise<boolean>;
|
||||
sendNotification(options: string | Options): void;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* eslint-disable @next/next/no-page-custom-font */
|
||||
// app\layout.tsx
|
||||
import "./styles/globals.scss";
|
||||
import "./styles/markdown.scss";
|
||||
import "./styles/highlight.scss";
|
||||
@ -7,6 +8,7 @@ import { type Metadata } from "next";
|
||||
import { SpeedInsights } from "@vercel/speed-insights/next";
|
||||
import { getServerSideConfig } from "./config/server";
|
||||
import { GoogleTagManager } from "@next/third-parties/google";
|
||||
import { Authenticator } from "@aws-amplify/ui-react";
|
||||
const serverConfig = getServerSideConfig();
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@ -36,7 +38,10 @@ export default function RootLayout({
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="config" content={JSON.stringify(getClientConfig())} />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link rel="manifest" href="/site.webmanifest"></link>
|
||||
<script src="/serviceWorkerRegister.js" defer></script>
|
||||
</head>
|
||||
|
@ -1,7 +1,6 @@
|
||||
// app\page.tsx
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
|
||||
import { Home } from "./components/home";
|
||||
|
||||
import { getServerSideConfig } from "./config/server";
|
||||
|
||||
const serverConfig = getServerSideConfig();
|
||||
|
@ -366,7 +366,10 @@ export const useChatStore = createPersistStore(
|
||||
var api: ClientApi;
|
||||
if (modelConfig.model.startsWith("gemini")) {
|
||||
api = new ClientApi(ModelProvider.GeminiPro);
|
||||
} else if (modelConfig.model.startsWith("claude")) {
|
||||
} else if (
|
||||
modelConfig.model.startsWith("claude") ||
|
||||
modelConfig.model.startsWith("knowledge-base")
|
||||
) {
|
||||
api = new ClientApi(ModelProvider.Bedrock);
|
||||
//api = new ClientApi(ModelProvider.Claude);
|
||||
} else {
|
||||
|
26
middleware.ts
Normal file
26
middleware.ts
Normal file
@ -0,0 +1,26 @@
|
||||
//Next.js请求中间件
|
||||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { fetchAuthSession } from "aws-amplify/auth";
|
||||
|
||||
// 如果在该函数中使用 "await",则可将其标记为 "async"。
|
||||
export async function middleware(request: NextRequest) {
|
||||
try {
|
||||
const session = await fetchAuthSession();
|
||||
console.log("session", session);
|
||||
if (session) {
|
||||
//return NextResponse.redirect(new URL("/auth", request.url));
|
||||
return NextResponse.next();
|
||||
} else {
|
||||
return NextResponse.redirect(new URL("/auth", request.url));
|
||||
}
|
||||
} catch (error) {
|
||||
return NextResponse.redirect(new URL("/auth", request.url));
|
||||
}
|
||||
// return NextResponse.redirect(new URL("/", request.url));
|
||||
}
|
||||
|
||||
// See "Matching Paths" below to learn more
|
||||
export const config = {
|
||||
matcher: ["/((?!auth).*)"], // Apply middleware to all paths except /auth
|
||||
};
|
@ -16,12 +16,14 @@
|
||||
"proxy-dev": "sh ./scripts/init-proxy.sh && proxychains -f ./scripts/proxychains.conf yarn dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-amplify/ui-react": "^6.1.12",
|
||||
"@fortaine/fetch-event-source": "^3.0.6",
|
||||
"@hello-pangea/dnd": "^16.5.0",
|
||||
"@next/third-parties": "^14.1.0",
|
||||
"@svgr/webpack": "^6.5.1",
|
||||
"@vercel/analytics": "^0.1.11",
|
||||
"@vercel/speed-insights": "^1.0.2",
|
||||
"aws-amplify": "^6.3.6",
|
||||
"emoji-picker-react": "^4.9.2",
|
||||
"fuse.js": "^7.0.0",
|
||||
"heic2any": "^0.0.4",
|
||||
@ -45,6 +47,8 @@
|
||||
"zustand": "^4.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aws-amplify/backend": "^1.0.3",
|
||||
"@aws-amplify/backend-cli": "^1.0.4",
|
||||
"@tauri-apps/cli": "1.5.11",
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/react": "^18.2.70",
|
||||
|
Loading…
Reference in New Issue
Block a user