mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-05 08:10:14 +00:00
Merge pull request #2 from RooCodeInc/jr/extension-auth
This commit is contained in:
commit
938418fc3f
5 changed files with 119 additions and 0 deletions
2
.env
2
.env
|
|
@ -1,5 +1,7 @@
|
|||
BILLING_PLAN_ENV=dev
|
||||
|
||||
VSCODE_EXTENSION_BASE_URL=vscode://RooVeterinaryInc.roo-cline
|
||||
|
||||
# Clerk
|
||||
# https://clerk.com/docs/deployments/clerk-environment-variables#sign-in-and-sign-up-redirects
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
||||
|
|
|
|||
25
src/app/(authenticated)/extension/sign-in/route.ts
Normal file
25
src/app/(authenticated)/extension/sign-in/route.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { getSignInToken } from '@/lib/server/clerk';
|
||||
import { Env } from '@/lib/server/env';
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { type NextRequest } from 'next/server';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const authObj = await auth();
|
||||
const userId = authObj.userId;
|
||||
const state = request.nextUrl.searchParams.get('state') || '';
|
||||
|
||||
if (!userId) {
|
||||
return new Response('Unauthorized', { status: 401 });
|
||||
}
|
||||
|
||||
const signInToken = await getSignInToken(authObj.userId);
|
||||
if (!signInToken) {
|
||||
throw new Error("couldn't sign in");
|
||||
}
|
||||
|
||||
const url = new URL(`${Env.VSCODE_EXTENSION_BASE_URL}/auth/clerk/callback`);
|
||||
url.searchParams.append('state', state);
|
||||
url.searchParams.append('code', signInToken);
|
||||
redirect(url.href);
|
||||
}
|
||||
52
src/app/api/ping/route.ts
Normal file
52
src/app/api/ping/route.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { auth } from '@clerk/nextjs/server';
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
import { logger } from '@/lib/server/logger';
|
||||
|
||||
/**
|
||||
* API endpoint for testing Clerk authentication
|
||||
* Verifies/parses JWT and logs authenticated user information
|
||||
*/
|
||||
export async function GET() {
|
||||
const authObj = await auth();
|
||||
|
||||
// If not authenticated
|
||||
if (!authObj.userId) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Unauthorized request' },
|
||||
{ status: 401 },
|
||||
);
|
||||
}
|
||||
|
||||
// Get the JWT token
|
||||
const token = await authObj.getToken();
|
||||
|
||||
// Extract user information from the auth object
|
||||
// Only include properties that exist on the auth object
|
||||
const userInfo = {
|
||||
userId: authObj.userId,
|
||||
sessionId: authObj.sessionId,
|
||||
orgId: authObj.orgId,
|
||||
orgRole: authObj.orgRole,
|
||||
// Note: To get additional user data like email, firstName, lastName,
|
||||
// you would need to use Clerk's methods like clerkClient.users.getUser()
|
||||
};
|
||||
|
||||
// Log the user information
|
||||
logger.info({
|
||||
event: 'ping_endpoint_accessed',
|
||||
userInfo: {
|
||||
userId: authObj.userId,
|
||||
sessionId: authObj.sessionId,
|
||||
orgId: authObj.orgId,
|
||||
orgRole: authObj.orgRole,
|
||||
},
|
||||
hasToken: !!token, // Just log if token exists, not the actual token for security
|
||||
});
|
||||
|
||||
// Return the user information
|
||||
return NextResponse.json({
|
||||
authenticated: true,
|
||||
userInfo,
|
||||
});
|
||||
}
|
||||
38
src/lib/server/clerk.ts
Normal file
38
src/lib/server/clerk.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { Env } from './env';
|
||||
import { logger } from './logger';
|
||||
|
||||
export async function getSignInToken(
|
||||
userId: string,
|
||||
): Promise<string | undefined> {
|
||||
const response = await fetch('https://api.clerk.com/v1/sign_in_tokens', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${Env.CLERK_SECRET_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
user_id: userId,
|
||||
// Default expiration is 30 days (2592000 seconds)
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
logger.error({
|
||||
event: 'sign_in_token_creation_failed',
|
||||
error: errorData,
|
||||
userId,
|
||||
});
|
||||
|
||||
throw new Error("Failed to create sign-in token");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
logger.info({
|
||||
event: 'sign_in_token_created',
|
||||
userId,
|
||||
});
|
||||
|
||||
return data.token;
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ export const Env = createEnv({
|
|||
STRIPE_SECRET_KEY: z.string().min(1),
|
||||
STRIPE_WEBHOOK_SECRET: z.string().min(1),
|
||||
BILLING_PLAN_ENV: z.enum(['dev', 'test', 'prod']),
|
||||
VSCODE_EXTENSION_BASE_URL: z.string().min(1),
|
||||
},
|
||||
client: {
|
||||
NEXT_PUBLIC_APP_URL: z.string().optional(),
|
||||
|
|
@ -32,6 +33,7 @@ export const Env = createEnv({
|
|||
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
|
||||
STRIPE_WEBHOOK_SECRET: process.env.STRIPE_WEBHOOK_SECRET,
|
||||
BILLING_PLAN_ENV: process.env.BILLING_PLAN_ENV,
|
||||
VSCODE_EXTENSION_BASE_URL: process.env.VSCODE_EXTENSION_BASE_URL,
|
||||
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
|
||||
process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue