fix(chat): handle inactive botid gracefully (#1437)
This commit is contained in:
parent
ad47aa0ee0
commit
314f8ced57
6 changed files with 30 additions and 9 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
import type { NextAuthConfig } from "next-auth";
|
import type { NextAuthConfig } from "next-auth";
|
||||||
|
|
||||||
export const authConfig = {
|
export const authConfig = {
|
||||||
|
basePath: "/api/auth",
|
||||||
pages: {
|
pages: {
|
||||||
signIn: "/login",
|
signIn: "/login",
|
||||||
newUser: "/",
|
newUser: "/",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { checkBotId } from "botid/server";
|
|
||||||
import { geolocation, ipAddress } from "@vercel/functions";
|
import { geolocation, ipAddress } from "@vercel/functions";
|
||||||
import {
|
import {
|
||||||
convertToModelMessages,
|
convertToModelMessages,
|
||||||
|
|
@ -8,6 +7,7 @@ import {
|
||||||
stepCountIs,
|
stepCountIs,
|
||||||
streamText,
|
streamText,
|
||||||
} from "ai";
|
} from "ai";
|
||||||
|
import { checkBotId } from "botid/server";
|
||||||
import { after } from "next/server";
|
import { after } from "next/server";
|
||||||
import { createResumableStreamContext } from "resumable-stream";
|
import { createResumableStreamContext } from "resumable-stream";
|
||||||
import { auth, type UserType } from "@/app/(auth)/auth";
|
import { auth, type UserType } from "@/app/(auth)/auth";
|
||||||
|
|
@ -64,9 +64,12 @@ export async function POST(request: Request) {
|
||||||
const { id, message, messages, selectedChatModel, selectedVisibilityType } =
|
const { id, message, messages, selectedChatModel, selectedVisibilityType } =
|
||||||
requestBody;
|
requestBody;
|
||||||
|
|
||||||
const [botResult, session] = await Promise.all([checkBotId(), auth()]);
|
const [botResult, session] = await Promise.all([
|
||||||
|
checkBotId().catch(() => null),
|
||||||
|
auth(),
|
||||||
|
]);
|
||||||
|
|
||||||
if (botResult.isBot) {
|
if (botResult?.isBot) {
|
||||||
return new ChatbotError("unauthorized:chat").toResponse();
|
return new ChatbotError("unauthorized:chat").toResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { initBotId } from "botid/client/core";
|
||||||
initBotId({
|
initBotId({
|
||||||
protect: [
|
protect: [
|
||||||
{
|
{
|
||||||
path: "/api/chat",
|
path: `${process.env.NEXT_PUBLIC_BASE_PATH ?? ""}/api/chat`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ let client: ReturnType<typeof createClient> | null = null;
|
||||||
function getClient() {
|
function getClient() {
|
||||||
if (!client && process.env.REDIS_URL) {
|
if (!client && process.env.REDIS_URL) {
|
||||||
client = createClient({ url: process.env.REDIS_URL });
|
client = createClient({ url: process.env.REDIS_URL });
|
||||||
client.on("error", () => {});
|
client.on("error", () => undefined);
|
||||||
client.connect().catch(() => {
|
client.connect().catch(() => {
|
||||||
client = null;
|
client = null;
|
||||||
});
|
});
|
||||||
|
|
@ -20,10 +20,14 @@ function getClient() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkIpRateLimit(ip: string | undefined) {
|
export async function checkIpRateLimit(ip: string | undefined) {
|
||||||
if (!isProductionEnvironment || !ip) return;
|
if (!isProductionEnvironment || !ip) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const redis = getClient();
|
const redis = getClient();
|
||||||
if (!redis?.isReady) return;
|
if (!redis?.isReady) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const key = `ip-rate-limit:${ip}`;
|
const key = `ip-rate-limit:${ip}`;
|
||||||
|
|
@ -37,6 +41,8 @@ export async function checkIpRateLimit(ip: string | undefined) {
|
||||||
throw new ChatbotError("rate_limit:chat");
|
throw new ChatbotError("rate_limit:chat");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof ChatbotError) throw error;
|
if (error instanceof ChatbotError) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { NextConfig } from "next";
|
|
||||||
import { withBotId } from "botid/next/config";
|
import { withBotId } from "botid/next/config";
|
||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
const basePath = "/demo";
|
const basePath = "/demo";
|
||||||
|
|
||||||
|
|
@ -8,6 +8,7 @@ const nextConfig: NextConfig = {
|
||||||
assetPrefix: "/demo-assets",
|
assetPrefix: "/demo-assets",
|
||||||
env: {
|
env: {
|
||||||
NEXT_PUBLIC_BASE_PATH: basePath,
|
NEXT_PUBLIC_BASE_PATH: basePath,
|
||||||
|
NEXTAUTH_URL: `http://localhost${basePath}/api/auth`,
|
||||||
},
|
},
|
||||||
cacheComponents: true,
|
cacheComponents: true,
|
||||||
images: {
|
images: {
|
||||||
|
|
|
||||||
10
vercel.json
10
vercel.json
|
|
@ -1,5 +1,15 @@
|
||||||
{
|
{
|
||||||
"framework": "nextjs",
|
"framework": "nextjs",
|
||||||
|
"rewrites": [
|
||||||
|
{
|
||||||
|
"source": "/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/a-4-a/c.js",
|
||||||
|
"destination": "https://api.vercel.com/bot-protection/v1/challenge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/:path*",
|
||||||
|
"destination": "https://api.vercel.com/bot-protection/v1/proxy/:path*"
|
||||||
|
}
|
||||||
|
],
|
||||||
"redirects": [
|
"redirects": [
|
||||||
{
|
{
|
||||||
"source": "/",
|
"source": "/",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue