diff --git a/package.json b/package.json index 531f10e0..5a1615f6 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "@unkey/nextjs": "^0.15.0", "@vercel/analytics": "^1.0.1", "ai": "^3.1.12", + "async-retry": "^1.3.3", "autoprefixer": "^10.4.13", "axios": "^1.2.1", "checkbox": "^0.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f008181b..32eff637 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -275,6 +275,9 @@ importers: ai: specifier: ^3.1.12 version: 3.2.24(react@18.3.1)(svelte@4.2.18)(vue@3.4.31(typescript@5.5.3))(zod@3.23.8) + async-retry: + specifier: ^1.3.3 + version: 1.3.3 autoprefixer: specifier: ^10.4.13 version: 10.4.19(postcss@8.4.39) @@ -4290,6 +4293,9 @@ packages: async-limiter@1.0.1: resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -8248,6 +8254,10 @@ packages: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -13742,6 +13752,10 @@ snapshots: async-limiter@1.0.1: {} + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + asynckit@0.4.0: {} atob@2.1.2: {} @@ -18833,6 +18847,8 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + retry@0.13.1: {} + reusify@1.0.4: {} rgb-regex@1.0.1: {} diff --git a/src/app/(dynamic-pages)/(authenticated-pages)/github_app/error/page.tsx b/src/app/(dynamic-pages)/(authenticated-pages)/github_app/error/page.tsx new file mode 100644 index 00000000..063c3a9f --- /dev/null +++ b/src/app/(dynamic-pages)/(authenticated-pages)/github_app/error/page.tsx @@ -0,0 +1,11 @@ +import Link from "next/link"; + +export default function GithubAppError() { + const appSlug = process.env.NEXT_PUBLIC_GITHUB_APP_SLUG; + return ( + <> +
GitHub App installation failed. Maybe try re-install it?
+ > + ) +} \ No newline at end of file diff --git a/src/app/(dynamic-pages)/(authenticated-pages)/github_app/success/page.tsx b/src/app/(dynamic-pages)/(authenticated-pages)/github_app/success/page.tsx new file mode 100644 index 00000000..54b49cd3 --- /dev/null +++ b/src/app/(dynamic-pages)/(authenticated-pages)/github_app/success/page.tsx @@ -0,0 +1,10 @@ +import Link from "next/link"; + +export default function GithubAppError() { + return ( + <> +GitHub App installed successfully. You can now close this tab or go to dashboard
+ > + ) +} \ No newline at end of file diff --git a/src/app/(dynamic-pages)/(login-pages)/auth/callback/route.ts b/src/app/(dynamic-pages)/(login-pages)/auth/callback/route.ts index 9c698a2f..5a23953a 100644 --- a/src/app/(dynamic-pages)/(login-pages)/auth/callback/route.ts +++ b/src/app/(dynamic-pages)/(login-pages)/auth/callback/route.ts @@ -22,28 +22,6 @@ export async function GET(request: Request) { } } - // HACK_ALERT!!! - // cookie is probably set on 'next.digger.dev' we have to change it to `.digger.dev` - const cookieKey = `sb-${process.env.SUPABASE_PROJECT_REF}-auth-token`; - const cookieStore = cookies(); - const currentCookieValue = cookieStore.get(cookieKey)?.value; - // get domain of current reques - const domain = new URL(request.url).hostname; - if ( - domain.includes('next.digger.dev') && - currentCookieValue && - !isDevelopment - ) { - // set cookie to .digger.dev - cookieStore.set(cookieKey, currentCookieValue, { - domain: '.digger.dev', - secure: true, - path: '/', - sameSite: 'lax', - httpOnly: true, - }); - } - let redirectTo = new URL('/dashboard', requestUrl.origin); if (next) { diff --git a/src/app/api/github-callback/route.ts b/src/app/api/github-callback/route.ts new file mode 100644 index 00000000..9fff7c2d --- /dev/null +++ b/src/app/api/github-callback/route.ts @@ -0,0 +1,73 @@ +import { createSupabaseUserRouteHandlerClient } from '@/supabase-clients/user/createSupabaseUserRouteHandlerClient'; +import { toSiteURL } from '@/utils/helpers'; +import { NextRequest, NextResponse } from 'next/server'; + +// Use the environment variable for the callback URL +const AUTH_SERVICE_URL = process.env.GITHUB_CALLBACK_URL; +const DIGGER_WEBHOOK_SECRET = process.env.DIGGER_WEBHOOK_SECRET; + +if (!AUTH_SERVICE_URL) { + throw new Error('GITHUB_CALLBACK_URL environment variable is not set'); +} + +export async function GET(request: NextRequest) { + const searchParams = request.nextUrl.searchParams; + const installationId = searchParams.get('installation_id'); + + if (!installationId) { + return NextResponse.json( + { error: 'Missing installation_id' }, + { status: 400 }, + ); + } + + try { + console.log( + 'Trying to get org id for the following installation ID:', + installationId, + ); + const organizationId = await getOrganizationId(); + const response = await fetch( + `${AUTH_SERVICE_URL}?${searchParams.toString()}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'X-Digger-Org-ID': organizationId, + Authorization: `Bearer ${DIGGER_WEBHOOK_SECRET}`, + }, + }, + ); + + if (!response.ok) { + throw new Error(`Auth service responded with status: ${response.status}`); + } + return NextResponse.redirect(toSiteURL('/github_app/success')); + } catch (error) { + console.error('Error handling GitHub App installation callback:', error); + return NextResponse.redirect(toSiteURL('/github_app/error')); + } +} + +async function getOrganizationId(): Promise