Skip to content

Commit

Permalink
Update files: modified files
Browse files Browse the repository at this point in the history
  • Loading branch information
storminstakk committed Apr 14, 2024
1 parent 69e7913 commit 823ef5c
Show file tree
Hide file tree
Showing 14 changed files with 770 additions and 470 deletions.
59 changes: 30 additions & 29 deletions app/api/auth.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { NextRequest } from "next/server";
import { getServerSideConfig } from "../config/server";
import { NextRequest, NextResponse } from "next/server";
import md5 from "spark-md5";
import { getServerSideConfig } from "../config/server";
import { ACCESS_CODE_PREFIX } from "../constant";
import { OPENAI_URL } from "./common";

function getIP(req: NextRequest) {
let ip = req.ip ?? req.headers.get("x-real-ip");
Expand All @@ -15,8 +14,8 @@ function getIP(req: NextRequest) {
return ip;
}

function parseApiKey(bearToken: string) {
const token = bearToken.trim().replaceAll("Bearer ", "").trim();
function parseAuthToken(authToken: string) {
const token = authToken.trim().replaceAll("Bearer ", "").trim();
const isOpenAiKey = !token.startsWith(ACCESS_CODE_PREFIX);

return {
Expand All @@ -25,42 +24,44 @@ function parseApiKey(bearToken: string) {
};
}

export function auth(req: NextRequest) {
const authToken = req.headers.get("Authorization") ?? "";
export function handleAuthRequest(
req: NextRequest,
params: { path: string[] }
): NextResponse {
const { path } = params;
console.log(`[Auth] Handling request for path: ${path}`);

// check if it is openai api key or user token
const { accessCode, apiKey: token } = parseApiKey(authToken);
const authToken = req.headers.get("Authorization") ?? "";
const { accessCode, apiKey } = parseAuthToken(authToken);

const hashedCode = md5.hash(accessCode ?? "").trim();

const serverConfig = getServerSideConfig();
console.log("[Auth] allowed hashed codes: ", [...serverConfig.codes]);
console.log("[Auth] got access code:", accessCode);
console.log("[Auth] hashed access code:", hashedCode);

console.log("[Auth] Allowed hashed codes: ", [...serverConfig.codes]);
console.log("[Auth] Received access code:", accessCode);
console.log("[Auth] Hashed access code:", hashedCode);
console.log("[User IP] ", getIP(req));
console.log("[Time] ", new Date().toLocaleString());

if (serverConfig.needCode && !serverConfig.codes.has(hashedCode) && !token) {
return {
error: true,
msg: !accessCode ? "empty access code" : "wrong access code",
};
if (serverConfig.needCode && !serverConfig.codes.has(hashedCode) && !apiKey) {
return new NextResponse(
JSON.stringify({ error: true, msg: !accessCode ? "Empty access code" : "Wrong access code" }),
{ status: 401 }
);
}

// if user does not provide an api key, inject system api key
if (!token) {
const apiKey = serverConfig.apiKey;
if (apiKey) {
console.log("[Auth] use system api key");
req.headers.set("Authorization", `Bearer ${apiKey}`);
// Inject system API key if user does not provide one
if (!apiKey) {
const systemApiKey = serverConfig.apiKey;
if (systemApiKey) {
console.log("[Auth] Using system API key");
req.headers.set("Authorization", `Bearer ${systemApiKey}`);
} else {
console.log("[Auth] admin did not provide an api key");
console.log("[Auth] Admin did not provide an API key");
}
} else {
console.log("[Auth] use user api key");
console.log("[Auth] Using user API key");
}

return {
error: false,
};
return new NextResponse(JSON.stringify({ error: false }));
}
32 changes: 10 additions & 22 deletions app/api/common.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,43 @@
import { NextRequest } from "next/server";
import { NextRequest, NextResponse } from "next/server";

export const OPENAI_URL = "api.openai.com";
export const HUGGINGFACE_URL = "api.huggingface.co";
const DEFAULT_PROTOCOL = "https";
const PROTOCOL = process.env.PROTOCOL ?? DEFAULT_PROTOCOL;
const BASE_URL = process.env.BASE_URL ?? OPENAI_URL;
const BASE_URL = process.env.BASE_URL ?? HUGGINGFACE_URL;

export async function requestOpenai(req: NextRequest) {
export async function handleHuggingFaceRequest(req: NextRequest): Promise<NextResponse> {
const controller = new AbortController();
const authValue = req.headers.get("Authorization") ?? "";
const openaiPath = `${req.nextUrl.pathname}${req.nextUrl.search}`.replaceAll(
"/api/openai/",
"",
);
const huggingFacePath = req.nextUrl.pathname.replace("/api/huggingface/", "");

let baseUrl = BASE_URL;

if (!baseUrl.startsWith("http")) {
baseUrl = `${PROTOCOL}://${baseUrl}`;
}

console.log("[Proxy] ", openaiPath);
console.log("[Base Url]", baseUrl);

if (process.env.OPENAI_ORG_ID) {
console.log("[Org ID]", process.env.OPENAI_ORG_ID);
}
console.log("[Proxy] ", huggingFacePath);
console.log("[Base URL]", baseUrl);

const timeoutId = setTimeout(() => {
controller.abort();
}, 10 * 60 * 1000);

const fetchUrl = `${baseUrl}/${openaiPath}`;
const fetchUrl = `${baseUrl}/${huggingFacePath}`;
const fetchOptions: RequestInit = {
method: req.method,
headers: {
"Content-Type": "application/json",
Authorization: authValue,
...(process.env.OPENAI_ORG_ID && {
"OpenAI-Organization": process.env.OPENAI_ORG_ID,
}),
},
cache: "no-store",
method: req.method,
body: req.body,
signal: controller.signal,
};

try {
const res = await fetch(fetchUrl, fetchOptions);

// Handle 401 Unauthorized to prevent browser prompt for credentials
if (res.status === 401) {
// to prevent browser prompt for credentials
const newHeaders = new Headers(res.headers);
newHeaders.delete("www-authenticate");
return new Response(res.body, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { prettyObject } from "@/app/utils/format";
import { NextRequest, NextResponse } from "next/server";
import { auth } from "../../auth";
import { requestOpenai } from "../../common";
import { requestHuggingface } from "../../common"; // Update import to use Hugging Face

async function handle(
req: NextRequest,
{ params }: { params: { path: string[] } },
) {
console.log("[OpenAI Route] params ", params);
console.log("[Hugging Face Route] params ", params);

const authResult = auth(req);
if (authResult.error) {
Expand All @@ -17,9 +17,9 @@ async function handle(
}

try {
return await requestOpenai(req);
return await requestHuggingface(req); // Use Hugging Face request function
} catch (e) {
console.error("[OpenAI] ", e);
console.error("[Hugging Face] ", e);
return NextResponse.json(prettyObject(e));
}
}
Expand Down
6 changes: 3 additions & 3 deletions app/client/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ACCESS_CODE_PREFIX } from "../constant";
import { ChatMessage, ModelConfig, ModelType, useAccessStore } from "../store";
import { ChatGPTApi } from "./platforms/openai";
import { ChatGPTApi } from "./platforms/huggingface";

export const ROLES = ["system", "user", "assistant"] as const;
export type MessageRole = (typeof ROLES)[number];
Expand Down Expand Up @@ -87,7 +87,7 @@ export class ClientApi {
public llm: LLMApi;

constructor() {
this.llm = new ChatGPTApi();
this.llm = new HuggingfaceApi();
}

config() {}
Expand Down Expand Up @@ -167,7 +167,7 @@ export function getHeaders() {
* This module exports several classes and interfaces that are used to interact with OpenAI's GPT API.
* The `ClientApi` class is the main entry point for using the API, and it provides methods for interacting with the GPT API.
* The `LLMApi` class is an abstract class that defines the interface for interacting with the GPT API.
* The `ChatGPTApi` class is a concrete implementation of the `LLMApi` class that provides methods for chatting with the GPT API.
* The `HuggingfaceApi` class is a concrete implementation of the `LLMApi` class that provides methods for chatting with the GPT API.
* The `RequestMessage` interface defines the structure of a message that can be sent to the GPT API.
* The `LLMConfig` interface defines the configuration options that can be passed to the GPT API.
* The `ChatOptions` interface defines the options that can be passed to the `chat` method of the `LLMApi` class.
Expand Down
14 changes: 7 additions & 7 deletions app/constant.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export const OWNER = "Yidadaa";
export const REPO = "ChatGPT-Next-Web";
export const REPO_URL = `/~https://github.com/${OWNER}/${REPO}`;
export const ISSUE_URL = `/~https://github.com/${OWNER}/${REPO}/issues`;
export const OWNER = "storminstakk";
export const REPO = "Justice-Juggernaut";
export const REPO_URL = `/~https://github.com/storminstakk/Justice_Juggernaut`;
export const ISSUE_URL = `/~https://github.com/storminstakk/Justice_Juggernaut/issues`;
export const UPDATE_URL = `${REPO_URL}#keep-updated`;
export const FETCH_COMMIT_URL = `https://api.github.com/repos/${OWNER}/${REPO}/commits?per_page=1`;
export const FETCH_TAG_URL = `https://api.github.com/repos/${OWNER}/${REPO}/tags?per_page=1`;
export const FETCH_COMMIT_URL = `https://api.github.com/repos/storminstakk/Justice_Juggernaut/commits?per_page=1`;
export const FETCH_TAG_URL = `https://api.github.com/repos/storminstakk/Justice_Juggernaut/tags?per_page=1`;
export const RUNTIME_CONFIG_DOM = "danger-runtime-config";

export enum Path {
Expand All @@ -25,7 +25,7 @@ export enum FileName {
}

export enum StoreKey {
Chat = "chat-next-web-store",
Chat = "Justice-Juggernaut-store",
Access = "access-control",
Config = "app-config",
Mask = "mask-store",
Expand Down
132 changes: 99 additions & 33 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,108 @@
/* eslint-disable @next/next/no-page-custom-font */
import "./styles/globals.scss";
import "./styles/markdown.scss";
import "./styles/highlight.scss";
// layout.tsx

import React from "react";
import Head from "next/head";
import ErrorBoundary from "./ErrorBoundary";
import { getBuildConfig } from "./config/build";

const buildConfig = getBuildConfig();

export const metadata = {
title: "Justice Juggernaut",
description: "Your personal Law Chat Bot.",
viewport: {
width: "device-width",
initialScale: 1,
maximumScale: 1,
},
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "#fafafa" },
{ media: "(prefers-color-scheme: dark)", color: "#151515" },
],
appleWebApp: {
title: "Justice Juggernaut",
statusBarStyle: "default",
},
};

export default function RootLayout({
const RootLayout: React.FC<{ pageTitle: string; children: React.ReactNode }> = ({
pageTitle,
children,
}: {
children: React.ReactNode;
}) {
}) => {
// Dynamically determine theme color based on user's color scheme preference
const getThemeColor = () => {
return window.matchMedia("(prefers-color-scheme: dark)").matches
? "#151515"
: "#fafafa";
};

// Handle network errors and display fallback UI
const handleNetworkError = (error: Error, componentStack: string) => {
console.error("Network Error:", error);
// Implement custom error handling and reporting (e.g., notify error tracking service)
// Display fallback UI to the user
return (
<div style={{ padding: "20px", color: "red", fontWeight: "bold" }}>
Something went wrong. Please try again later.
</div>
);
};

return (
<html lang="en">
<head>
<>
<Head>
<meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{pageTitle}</title>
<meta
name="description"
content="Empowering parents' rights and fighting against CPS corruption. Your personal Law Chat Bot."
/>
<meta name="version" content={buildConfig.commitId} />
<link rel="manifest" href="/site.webmanifest"></link>
<meta name="theme-color" content={getThemeColor()} />
{/* Include anti-CYFD and parents' rights advocacy tags */}
<meta
name="keywords"
content="parents rights, civil rights, fight CPS, anti-CYFD, CPS corruption"
/>
<link rel="manifest" href="/site.webmanifest" />
<link rel="icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap"
/>
</Head>
<body>
{/* Wrap children with ErrorBoundary to catch and handle errors */}
<ErrorBoundary onError={handleNetworkError}>
{children}
</ErrorBoundary>
{/* Include service worker registration script for offline support */}
<script src="/serviceWorkerRegister.js" defer></script>
</head>
<body>{children}</body>
</html>
{/* Display powerful messages promoting parents' rights and anti-CYFD sentiments */}
<div style={{ backgroundColor: "#f8c0c0", padding: "20px", textAlign: "center" }}>
<h1>Empowering Parents' Rights</h1>
<p>
Stand up against CPS corruption and fight for justice and fairness in family matters.
</p>
{/* Resource links for more information */}
<p>
Explore resources:
<br />
<a href="https://www.parentalrights.org/" target="_blank" rel="noopener noreferrer">
ParentalRights.org
</a>{" "}
|{" "}
<a href="https://www.aclu.org/issues/parental-rights" target="_blank" rel="noopener noreferrer">
ACLU - Parental Rights
</a>
</p>
</div>
{/* Include additional dynamic elements and enhancements */}
<div style={{ backgroundColor: "#c0f8e4", padding: "20px", textAlign: "center" }}>
<h1>Join the Civil Rights Movement</h1>
<p>
Advocate for civil rights and equality, ensuring every family is treated with respect and dignity.
</p>
{/* Resource links for civil rights advocacy */}
<p>
Explore resources:
<br />
<a href="https://www.naacp.org/" target="_blank" rel="noopener noreferrer">
NAACP
</a>{" "}
|{" "}
<a href="https://www.hrc.org/" target="_blank" rel="noopener noreferrer">
Human Rights Campaign
</a>
</p>
</div>
</body>
</>
);
}
};

export default RootLayout;
Loading

0 comments on commit 823ef5c

Please sign in to comment.