+3
-13
app/api/categories/[categoryId]/route.ts
+3
-13
app/api/categories/[categoryId]/route.ts
···
9
9
import { getOrganizationRole } from '@/lib/repositories/user-repository';
10
10
import { Category } from '@/lib/types';
11
11
import { z } from 'zod';
12
-
import { verifyBotId } from '@/lib/botid-verification';
12
+
13
13
14
14
export const runtime = 'nodejs';
15
15
···
24
24
{ params }: { params: Promise<{ categoryId: string }> }
25
25
) {
26
26
try {
27
-
// Check for bot before proceeding
28
-
const botVerification = await verifyBotId();
29
-
if (botVerification) {
30
-
return botVerification;
31
-
}
32
-
27
+
33
28
const { categoryId } = await params;
34
29
const session = await auth();
35
30
if (!session?.user?.id) {
···
130
125
{ params }: { params: Promise<{ categoryId: string }> }
131
126
) {
132
127
try {
133
-
// Check for bot before proceeding
134
-
const botVerification = await verifyBotId();
135
-
if (botVerification) {
136
-
return botVerification;
137
-
}
138
-
128
+
139
129
const { categoryId } = await params;
140
130
const session = await auth();
141
131
if (!session?.user?.id) {
+2
-7
app/api/dashboard/data/route.ts
+2
-7
app/api/dashboard/data/route.ts
···
1
1
import { NextRequest, NextResponse } from 'next/server';
2
2
import { getUserWithOrganizations } from '@/lib/auth-context';
3
-
import { verifyBotId } from '@/lib/botid-verification';
3
+
4
4
5
5
export const runtime = 'nodejs';
6
6
7
7
export async function GET(request: NextRequest) {
8
8
try {
9
-
// Check for bot before proceeding
10
-
const botVerification = await verifyBotId();
11
-
if (botVerification) {
12
-
return botVerification;
13
-
}
14
-
9
+
15
10
const { searchParams } = new URL(request.url);
16
11
const include = searchParams.get('include')?.split(',') || [];
17
12
+4
-16
app/api/github-app/installations/[installationId]/route.ts
+4
-16
app/api/github-app/installations/[installationId]/route.ts
···
7
7
import { auth } from '@/auth'
8
8
import { getService } from '@/lib/core/container/di-container'
9
9
import { IGitHubAppService } from '@/lib/core/ports'
10
-
import { verifyBotId } from '@/lib/botid-verification'
10
+
11
11
12
12
export const runtime = 'nodejs'
13
13
···
20
20
{ params }: { params: Promise<{ installationId: string }> }
21
21
) {
22
22
try {
23
-
// Check for bot before proceeding
24
-
const botVerification = await verifyBotId();
25
-
if (botVerification) {
26
-
return botVerification;
27
-
}
23
+
28
24
29
25
const { installationId } = await params
30
26
const session = await auth()
···
91
87
{ params }: { params: Promise<{ installationId: string }> }
92
88
) {
93
89
try {
94
-
// Check for bot before proceeding
95
-
const botVerification = await verifyBotId();
96
-
if (botVerification) {
97
-
return botVerification;
98
-
}
90
+
99
91
100
92
const { installationId } = await params
101
93
const session = await auth()
···
163
155
{ params }: { params: Promise<{ installationId: string }> }
164
156
) {
165
157
try {
166
-
// Check for bot before proceeding
167
-
const botVerification = await verifyBotId();
168
-
if (botVerification) {
169
-
return botVerification;
170
-
}
158
+
171
159
172
160
const { installationId } = await params
173
161
const session = await auth()
+3
-11
app/api/github-app/installations/route.ts
+3
-11
app/api/github-app/installations/route.ts
···
7
7
import { auth } from '@/auth'
8
8
import { getService } from '@/lib/core/container/di-container'
9
9
import { IGitHubAppService } from '@/lib/core/ports'
10
-
import { verifyBotId } from '@/lib/botid-verification'
10
+
11
11
12
12
export const runtime = 'nodejs'
13
13
···
17
17
*/
18
18
export async function GET() {
19
19
try {
20
-
// Check for bot before proceeding
21
-
const botVerification = await verifyBotId();
22
-
if (botVerification) {
23
-
return botVerification;
24
-
}
20
+
25
21
26
22
const session = await auth()
27
23
···
78
74
*/
79
75
export async function POST() {
80
76
try {
81
-
// Check for bot before proceeding
82
-
const botVerification = await verifyBotId();
83
-
if (botVerification) {
84
-
return botVerification;
85
-
}
77
+
86
78
87
79
const session = await auth()
88
80
+1
-7
app/api/github/organizations/[orgName]/repositories/route.ts
+1
-7
app/api/github/organizations/[orgName]/repositories/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getService } from '@/lib/core/container/di-container';
4
4
import { IGitHubService } from '@/lib/core/ports';
5
-
import { verifyBotId } from '@/lib/botid-verification';
5
+
6
6
7
7
// Use the context object directly with proper typing for Next.js route handler
8
8
export async function GET(
9
9
request: NextRequest,
10
10
{ params }: { params: Promise<{ orgName: string }> }
11
11
) {
12
-
// Check for bot before proceeding
13
-
const botVerification = await verifyBotId();
14
-
if (botVerification) {
15
-
return botVerification;
16
-
}
17
-
18
12
const { orgName } = await params;
19
13
20
14
const session = await auth();
+1
-7
app/api/github/organizations/route.ts
+1
-7
app/api/github/organizations/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getService } from '@/lib/core/container/di-container';
4
4
import { IGitHubService } from '@/lib/core/ports';
5
-
import { verifyBotId } from '@/lib/botid-verification';
6
5
7
-
export async function GET() {
8
-
// Check for bot before proceeding
9
-
const botVerification = await verifyBotId();
10
-
if (botVerification) {
11
-
return botVerification;
12
-
}
13
6
7
+
export async function GET() {
14
8
const session = await auth();
15
9
16
10
if (!session || !session.user) {
+1
-7
app/api/github/repositories/sync/route.ts
+1
-7
app/api/github/repositories/sync/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { GitHubService } from '@/lib/services';
4
4
import { findUserById, findUserByEmail } from '@/lib/repositories';
5
-
import { verifyBotId } from '@/lib/botid-verification';
5
+
6
6
7
7
export const runtime = 'nodejs';
8
8
9
9
export async function POST() {
10
-
// Check for bot before proceeding
11
-
const botVerification = await verifyBotId();
12
-
if (botVerification) {
13
-
return botVerification;
14
-
}
15
-
16
10
const session = await auth();
17
11
18
12
if (!session || !session.user) {
-8
app/api/github/user/route.ts
-8
app/api/github/user/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getService } from '@/lib/core/container/di-container';
4
4
import { IGitHubService } from '@/lib/core/ports';
5
-
import { verifyBotId } from '@/lib/botid-verification';
6
-
7
5
export async function GET() {
8
-
// Check for bot before proceeding
9
-
const botVerification = await verifyBotId();
10
-
if (botVerification) {
11
-
return botVerification;
12
-
}
13
-
14
6
const session = await auth();
15
7
16
8
if (!session || !session.user) {
+1
-11
app/api/organizations/[orgId]/ai-settings/route.ts
+1
-11
app/api/organizations/[orgId]/ai-settings/route.ts
···
3
3
import { AiSettingsService } from '@/lib/services/ai-settings-service';
4
4
import { z } from 'zod';
5
5
import { unauthorized, badRequest, errorResponse } from '@/lib/api-errors';
6
-
import { verifyBotId } from '@/lib/botid-verification';
6
+
7
7
8
8
const updateAiSettingsSchema = z.object({
9
9
provider: z.enum(['openai', 'google', 'anthropic']).nullable().optional(),
···
20
20
{ params }: { params: Promise<{ orgId: string }> }
21
21
) {
22
22
try {
23
-
// Check for bot before proceeding
24
-
const botVerification = await verifyBotId();
25
-
if (botVerification) {
26
-
return botVerification;
27
-
}
28
23
29
24
const { orgId } = await params;
30
25
const session = await auth();
···
46
41
{ params }: { params: Promise<{ orgId: string }> }
47
42
) {
48
43
try {
49
-
// Check for bot before proceeding
50
-
const botVerification = await verifyBotId();
51
-
if (botVerification) {
52
-
return botVerification;
53
-
}
54
44
55
45
const { orgId } = await params;
56
46
const session = await auth();
+2
-8
app/api/organizations/[orgId]/members/route.ts
+2
-8
app/api/organizations/[orgId]/members/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getOrganizationMembers, searchUsers } from '@/lib/repositories/team-repository';
4
4
import { getOrganizationRole } from '@/lib/repositories/user-repository';
5
-
import { verifyBotId } from '@/lib/botid-verification';
5
+
6
6
7
7
export const runtime = 'nodejs';
8
8
···
12
12
{ params }: { params: Promise<{ orgId: string }> }
13
13
) {
14
14
try {
15
-
// Check for bot before proceeding
16
-
const botVerification = await verifyBotId();
17
-
if (botVerification) {
18
-
return botVerification;
19
-
}
20
-
21
-
const { orgId } = await params;
15
+
const { orgId } = await params;
22
16
const session = await auth();
23
17
if (!session?.user?.id) {
24
18
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
-71
instrumentation-client.ts
-71
instrumentation-client.ts
···
1
-
import { initBotId } from 'botid/client/core';
2
-
3
-
initBotId({
4
-
protect: [
5
-
// Only protect actual mutations (POST, PUT, DELETE) - not GET requests
6
-
// Team management mutations
7
-
{
8
-
path: '/api/organizations/*/teams',
9
-
method: 'POST',
10
-
},
11
-
{
12
-
path: '/api/organizations/*/teams/*',
13
-
method: 'PUT',
14
-
},
15
-
{
16
-
path: '/api/organizations/*/teams/*',
17
-
method: 'DELETE',
18
-
},
19
-
{
20
-
path: '/api/organizations/*/teams/*/members',
21
-
method: 'POST',
22
-
},
23
-
{
24
-
path: '/api/organizations/*/teams/*/members',
25
-
method: 'PUT',
26
-
},
27
-
{
28
-
path: '/api/organizations/*/teams/*/members',
29
-
method: 'DELETE',
30
-
},
31
-
// Settings mutations
32
-
{
33
-
path: '/api/organizations/*/ai-settings',
34
-
method: 'PUT',
35
-
},
36
-
{
37
-
path: '/api/organizations/*/categories',
38
-
method: 'POST',
39
-
},
40
-
{
41
-
path: '/api/categories/*',
42
-
method: 'PUT',
43
-
},
44
-
{
45
-
path: '/api/categories/*',
46
-
method: 'DELETE',
47
-
},
48
-
// GitHub sync mutations
49
-
{
50
-
path: '/api/github/repositories/sync',
51
-
method: 'POST',
52
-
},
53
-
{
54
-
path: '/api/github-app/installations',
55
-
method: 'POST',
56
-
},
57
-
{
58
-
path: '/api/github-app/installations/*',
59
-
method: 'POST',
60
-
},
61
-
// Webhook management
62
-
{
63
-
path: '/api/github/repositories/*/webhook',
64
-
method: 'POST',
65
-
},
66
-
{
67
-
path: '/api/github/repositories/*/webhook',
68
-
method: 'DELETE',
69
-
},
70
-
],
71
-
});
-41
lib/botid-verification.ts
-41
lib/botid-verification.ts
···
1
-
import { checkBotId } from 'botid/server';
2
-
import { NextRequest, NextResponse } from 'next/server';
3
-
4
-
/**
5
-
* Utility function to verify botid and return 403 if request is from a bot
6
-
* @returns Promise<NextResponse | null> - Returns 403 response if bot detected, null if verification passes
7
-
*/
8
-
export async function verifyBotId(): Promise<NextResponse | null> {
9
-
try {
10
-
// Check if the request is from a bot
11
-
const verification = await checkBotId();
12
-
13
-
if (verification.isBot) {
14
-
return NextResponse.json({ error: 'Access denied' }, { status: 403 });
15
-
}
16
-
17
-
return null; // Verification passed
18
-
} catch (error) {
19
-
console.error('BotId verification error:', error);
20
-
// In case of verification error, allow request to proceed to avoid blocking legitimate users
21
-
return null;
22
-
}
23
-
}
24
-
25
-
/**
26
-
* Higher-order function to wrap API route handlers with botid verification
27
-
*/
28
-
export function withBotIdVerification<T extends (...args: any[]) => Promise<NextResponse>>(
29
-
handler: T
30
-
): T {
31
-
return (async (...args: any[]) => {
32
-
// Check for bot before executing the handler
33
-
const botVerification = await verifyBotId();
34
-
if (botVerification) {
35
-
return botVerification;
36
-
}
37
-
38
-
// If verification passes, execute the original handler
39
-
return await handler(...args);
40
-
}) as T;
41
-
}
+1
-13
lib/core/application/auth-middleware.ts
+1
-13
lib/core/application/auth-middleware.ts
···
13
13
createAnonymousContext,
14
14
UserPermissions
15
15
} from './context'
16
-
import { verifyBotId } from '../../botid-verification'
16
+
17
17
18
18
export type AuthenticatedHandler<TRequest = NextRequest, TResponse = NextResponse> =
19
19
(context: ApplicationContext, request: TRequest) => Promise<TResponse>
···
29
29
): (request: TRequest) => Promise<TResponse | NextResponse> {
30
30
return async (request: TRequest) => {
31
31
try {
32
-
// Check for bot before proceeding
33
-
const botVerification = await verifyBotId();
34
-
if (botVerification) {
35
-
return botVerification;
36
-
}
37
-
38
32
const context = await createAuthenticatedContext(request)
39
33
40
34
if (!context) {
···
57
51
): (request: TRequest) => Promise<TResponse> {
58
52
return async (request: TRequest) => {
59
53
try {
60
-
// Check for bot before proceeding
61
-
const botVerification = await verifyBotId();
62
-
if (botVerification) {
63
-
return botVerification as TResponse;
64
-
}
65
-
66
54
const context = await createRequestContext(request)
67
55
return await handler(context, request)
68
56
} catch (error) {