Implements more robust anti-zoomer functionality (khanon/oai-reverse-proxy!24)
This commit is contained in:
parent
c0ac69df27
commit
43359779e7
|
@ -156,7 +156,7 @@ export const config: Config = {
|
|||
undefined
|
||||
),
|
||||
queueMode: getEnvWithDefault("QUEUE_MODE", "fair"),
|
||||
blockedOrigins: getEnvWithDefault("BLOCKED_ORIGINS", "janitorai"),
|
||||
blockedOrigins: getEnvWithDefault("BLOCKED_ORIGINS", undefined),
|
||||
blockMessage: getEnvWithDefault(
|
||||
"BLOCK_MESSAGE",
|
||||
"You must be over the age of majority in your country to use this service."
|
||||
|
|
|
@ -9,6 +9,7 @@ import { handleProxyError } from "./middleware/common";
|
|||
import {
|
||||
addKey,
|
||||
addAnthropicPreamble,
|
||||
blockZoomers,
|
||||
createPreprocessorMiddleware,
|
||||
finalizeBody,
|
||||
languageFilter,
|
||||
|
@ -71,6 +72,7 @@ const rewriteAnthropicRequest = (
|
|||
const rewriterPipeline = [
|
||||
addKey,
|
||||
addAnthropicPreamble,
|
||||
blockZoomers,
|
||||
languageFilter,
|
||||
limitOutputTokens,
|
||||
finalizeBody,
|
||||
|
|
|
@ -2,7 +2,6 @@ import { Request, Response } from "express";
|
|||
import httpProxy from "http-proxy";
|
||||
import { ZodError } from "zod";
|
||||
|
||||
|
||||
const OPENAI_CHAT_COMPLETION_ENDPOINT = "/v1/chat/completions";
|
||||
const ANTHROPIC_COMPLETION_ENDPOINT = "/v1/complete";
|
||||
|
||||
|
@ -32,9 +31,14 @@ export function writeErrorResponse(
|
|||
res.headersSent ||
|
||||
res.getHeader("content-type") === "text/event-stream"
|
||||
) {
|
||||
const errorContent =
|
||||
statusCode === 403
|
||||
? JSON.stringify(errorPayload)
|
||||
: JSON.stringify(errorPayload, null, 2);
|
||||
|
||||
const msg = buildFakeSseMessage(
|
||||
`${errorSource} error (${statusCode})`,
|
||||
JSON.stringify(errorPayload, null, 2),
|
||||
errorContent,
|
||||
req
|
||||
);
|
||||
res.write(msg);
|
||||
|
@ -57,6 +61,7 @@ export const handleInternalError = (
|
|||
) => {
|
||||
try {
|
||||
const isZod = err instanceof ZodError;
|
||||
const isForbidden = err.name === "ForbiddenError";
|
||||
if (isZod) {
|
||||
writeErrorResponse(req, res, 400, {
|
||||
error: {
|
||||
|
@ -67,6 +72,17 @@ export const handleInternalError = (
|
|||
message: err.message,
|
||||
},
|
||||
});
|
||||
} else if (isForbidden) {
|
||||
// Spoofs a vaguely threatening OpenAI error message. Only invoked by the
|
||||
// block-zoomers rewriter to scare off tiktokers.
|
||||
writeErrorResponse(req, res, 403, {
|
||||
error: {
|
||||
type: "organization_account_disabled",
|
||||
code: "policy_violation",
|
||||
param: null,
|
||||
message: err.message,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
writeErrorResponse(req, res, 500, {
|
||||
error: {
|
||||
|
@ -91,10 +107,14 @@ export function buildFakeSseMessage(
|
|||
req: Request
|
||||
) {
|
||||
let fakeEvent;
|
||||
const useBackticks = !type.includes("403");
|
||||
const msgContent = useBackticks
|
||||
? `\`\`\`\n[${type}: ${string}]\n\`\`\`\n`
|
||||
: `[${type}: ${string}]`;
|
||||
|
||||
if (req.inboundApi === "anthropic") {
|
||||
fakeEvent = {
|
||||
completion: `\`\`\`\n[${type}: ${string}]\n\`\`\`\n`,
|
||||
completion: msgContent,
|
||||
stop_reason: type,
|
||||
truncated: false, // I've never seen this be true
|
||||
stop: null,
|
||||
|
@ -109,7 +129,7 @@ export function buildFakeSseMessage(
|
|||
model: req.body?.model,
|
||||
choices: [
|
||||
{
|
||||
delta: { content: `\`\`\`\n[${type}: ${string}]\n\`\`\`\n` },
|
||||
delta: { content: msgContent },
|
||||
index: 0,
|
||||
finish_reason: type,
|
||||
},
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { isCompletionRequest } from "../common";
|
||||
import { ProxyRequestMiddleware } from ".";
|
||||
|
||||
const DISALLOWED_ORIGIN_SUBSTRINGS = "janitorai.com,janitor.ai".split(",");
|
||||
|
||||
class ForbiddenError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "ForbiddenError";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks requests from Janitor AI users with a fake, scary error message so I
|
||||
* stop getting emails asking for tech support.
|
||||
*/
|
||||
export const blockZoomers: ProxyRequestMiddleware = (_proxyReq, req) => {
|
||||
if (!isCompletionRequest(req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const origin = req.headers.origin || req.headers.referer;
|
||||
if (origin && DISALLOWED_ORIGIN_SUBSTRINGS.some((s) => origin.includes(s))) {
|
||||
// Venus-derivatives send a test prompt to check if the proxy is working.
|
||||
// We don't want to block that just yet.
|
||||
if (req.body.messages[0]?.content === "Just say TEST") {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ForbiddenError(
|
||||
`This OpenAI account has been disabled due to fraud and potential CSAM violations. Your IP address, user agent, and request details have been logged and will be shared with the National Center for Missing and Exploited Children and local law enforcement's cybercrime division to assist in their investigation.`
|
||||
);
|
||||
}
|
||||
};
|
|
@ -10,6 +10,7 @@ export { transformOutboundPayload } from "./transform-outbound-payload";
|
|||
// HPM middleware (runs on onProxyReq, cannot be async)
|
||||
export { addKey } from "./add-key";
|
||||
export { addAnthropicPreamble } from "./add-anthropic-preamble";
|
||||
export { blockZoomers } from "./block-zoomers";
|
||||
export { finalizeBody } from "./finalize-body";
|
||||
export { languageFilter } from "./language-filter";
|
||||
export { limitCompletions } from "./limit-completions";
|
||||
|
|
|
@ -9,6 +9,7 @@ import { ipLimiter } from "./rate-limit";
|
|||
import { handleProxyError } from "./middleware/common";
|
||||
import {
|
||||
addKey,
|
||||
blockZoomers,
|
||||
createPreprocessorMiddleware,
|
||||
finalizeBody,
|
||||
languageFilter,
|
||||
|
@ -28,15 +29,16 @@ function getModelsResponse() {
|
|||
return modelsCache;
|
||||
}
|
||||
|
||||
// https://platform.openai.com/docs/models/overview
|
||||
const gptVariants = [
|
||||
"gpt-4",
|
||||
"gpt-4-0613",
|
||||
"gpt-4-0314",
|
||||
"gpt-4-0314", // EOL 2023-09-13
|
||||
"gpt-4-32k",
|
||||
"gpt-4-32k-0613",
|
||||
"gpt-4-32k-0314",
|
||||
"gpt-4-32k-0314", // EOL 2023-09-13
|
||||
"gpt-3.5-turbo",
|
||||
"gpt-3.5-turbo-0301",
|
||||
"gpt-3.5-turbo-0301", // EOL 2023-09-13
|
||||
"gpt-3.5-turbo-0613",
|
||||
"gpt-3.5-turbo-16k",
|
||||
"gpt-3.5-turbo-16k-0613",
|
||||
|
@ -89,6 +91,7 @@ const rewriteRequest = (
|
|||
) => {
|
||||
const rewriterPipeline = [
|
||||
addKey,
|
||||
blockZoomers,
|
||||
languageFilter,
|
||||
limitOutputTokens,
|
||||
limitCompletions,
|
||||
|
|
Loading…
Reference in New Issue