From db3f73ae496f900a9974a1198bf1c202f6b29d9e Mon Sep 17 00:00:00 2001 From: "Ryan J. Shaw" <610578+ryanjshaw@users.noreply.github.com> Date: Mon, 14 Oct 2024 08:19:33 +0200 Subject: [PATCH] Cleanup and wait spiny thing --- .env.example | 1 + app/api/auth/figma/callback/route.ts | 11 ++++++++++- app/api/auth/figma/signin/route.ts | 10 ++++++++++ templates/figma/Config.ts | 1 - templates/figma/components/FigmaConnector.tsx | 16 +++++++++++++--- templates/figma/components/PropertiesTab.tsx | 2 -- templates/figma/utils/FigmaApi.ts | 6 +++--- templates/figma/utils/FigmaFrameBuilder.ts | 2 +- 8 files changed, 38 insertions(+), 11 deletions(-) diff --git a/.env.example b/.env.example index 1d55fb89..1b98182b 100644 --- a/.env.example +++ b/.env.example @@ -37,5 +37,6 @@ POLYGONSCAN_API_KEY= BSCSCAN_API_KEY= # Figma App for OAuth +# Create these here: https://www.figma.com/developers/apps FIGMA_CLIENT_ID= FIGMA_CLIENT_SECRET= \ No newline at end of file diff --git a/app/api/auth/figma/callback/route.ts b/app/api/auth/figma/callback/route.ts index 79088c1d..6ee2a0f9 100644 --- a/app/api/auth/figma/callback/route.ts +++ b/app/api/auth/figma/callback/route.ts @@ -8,11 +8,20 @@ export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url); const { FIGMA_CLIENT_ID, FIGMA_CLIENT_SECRET, NEXT_PUBLIC_HOST } = process.env; + // biome-ignore lint/complexity/useSimplifiedLogicExpression: + if (!FIGMA_CLIENT_ID || !FIGMA_CLIENT_SECRET || !NEXT_PUBLIC_HOST) { + return NextResponse.json({ error: 'Missing environment variables' }, { status: 500 }); + } + // Retrieve the stored state from the cookie and verify the CSRF token const stateParam = searchParams.get('state'); const storedState = request.cookies.get('oauth_state')?.value; + // biome-ignore lint/complexity/useSimplifiedLogicExpression: + if (!stateParam || !storedState) { + return NextResponse.json({ error: 'Missing state parameter' }, { status: 500 }); + } if (storedState !== stateParam) { - return NextResponse.json({ error: 'State mismatch. Possible CSRF attack.' }, { status: 400 }); + return NextResponse.json({ error: 'State mismatch. Possible CSRF attack.' }, { status: 500 }); } // Get the original page URL from the state diff --git a/app/api/auth/figma/signin/route.ts b/app/api/auth/figma/signin/route.ts index 66f62530..83c6a598 100644 --- a/app/api/auth/figma/signin/route.ts +++ b/app/api/auth/figma/signin/route.ts @@ -7,9 +7,19 @@ import { type NextRequest, NextResponse } from 'next/server'; export async function GET(request: NextRequest) { const { FIGMA_CLIENT_ID, NEXT_PUBLIC_HOST } = process.env; + // biome-ignore lint/complexity/useSimplifiedLogicExpression: + if (!FIGMA_CLIENT_ID || !NEXT_PUBLIC_HOST) { + return NextResponse.json({ error: 'Missing environment variables' }, { status: 500 }); + } + // Get the original page URL from query params or referrer header const originalUrl = request.nextUrl.searchParams.get('original_url'); + // URL redirection attacks + if (!originalUrl?.startsWith(NEXT_PUBLIC_HOST)) { + return NextResponse.json({ error: 'Invalid redirect URL' }, { status: 400 }); + } + const redirectUri = `${NEXT_PUBLIC_HOST}/api/auth/figma/callback`; const state = JSON.stringify({ csrfToken: Math.random().toString(36).substring(2), diff --git a/templates/figma/Config.ts b/templates/figma/Config.ts index 2a79fa15..b8da8bc3 100644 --- a/templates/figma/Config.ts +++ b/templates/figma/Config.ts @@ -1,7 +1,6 @@ import type { FigmaTextLayer } from './utils/FigmaApi' export interface FramePressConfig { - figmaPAT: string slides: SlideConfig[] nextSlideId: number } diff --git a/templates/figma/components/FigmaConnector.tsx b/templates/figma/components/FigmaConnector.tsx index 70b730d8..19717335 100644 --- a/templates/figma/components/FigmaConnector.tsx +++ b/templates/figma/components/FigmaConnector.tsx @@ -2,29 +2,39 @@ import { Button } from '@/sdk/components'; import { useFigmaToken } from './FigmaTokenContext'; import { useRouter } from 'next/navigation'; +import { useState } from 'react'; -export default function FigmaTokenEditor() { +export default function FigmaConnector() { const router = useRouter(); const { figmaAccessToken, loading } = useFigmaToken(); + const [isConnecting, setIsConnecting] = useState(false); // To track connection state const handleConnectFigma = () => { + setIsConnecting(true); // Set connecting state + + // Change cursor to 'wait' + document.body.style.cursor = 'wait'; + const currentPage = window.location.href; router.push(`/api/auth/figma/signin?original_url=${encodeURIComponent(currentPage)}`); }; const handleSignout = async () => { + // Change cursor to 'wait' + document.body.style.cursor = 'wait'; + await fetch('/api/auth/figma/signout', { method: 'POST' }); // Refresh the page - // biome-ignore lint/correctness/noSelfAssign: + // biome-ignore lint/correctness/noSelfAssign: this is legit window.location.href = window.location.href; }; return (
- {loading ? ( + {loading || isConnecting ? (

Loading...

) : !figmaAccessToken ? (