Skip to content

Commit

Permalink
fix compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity committed Oct 24, 2024
1 parent 0d9a7a7 commit 1452214
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 61 deletions.
56 changes: 1 addition & 55 deletions app/api/login/route.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,10 @@
import { SignJWT } from 'jose'
import { createCallbackUrl, signFernJWT } from '@/auth/utils'
import { NextRequest, NextResponse } from 'next/server'

// Please reach out to the Fern Team if you have any questions about this setup.
// In this example, we show how you can write a lambda handler (or cloudflare worker) can be setup after the user logs in via your identity provider
// and mint a JWT (which we refer to as the `fern_token`) which will give users access to VIEW your docs.

// your domain
const JWT_ISSUER = 'https://test-jwt-auth-smoky.vercel.app'

// this is the domain of your docs, (or, if subpathed, use the apex here: yourdomain.com);
const DOCS_ORIGIN = 'https://test-jwt-auth-smoky.docs.buildwithfern.com'

// this is path that you will redirect to in the docs instance, and let Fern set the fern_token. This is preferred.
// alternatively, you may opt to set the `Set-Cookie` header directly using `fern_token` (case sensitive) if on the same domain.
// if subpathed docs, be sure to include the subpath set by your proxy, i.e. `/docs/api/fern-docs/auth/jwt/callback`.
const JWT_CALLBACK_PATHNAME = '/api/fern-docs/auth/jwt/callback'

// JWT payload must include a `fern` key. All fields are optional:
interface FernUser {
apiKey?: string // api key injection into the runnable API Playground
audience?: string[] // ACLs -> this controls which part of the docs are visible to the user
}

// this is the symmetric secret key that will be provided by Fern:
function getJwtTokenSecret(): Uint8Array {
if (!process.env.JWT_TOKEN_SECRET) {
throw new Error('JWT_TOKEN_SECRET is not set')
}
return new TextEncoder().encode(process.env.JWT_TOKEN_SECRET)
}

export function signFernJWT(fern: FernUser): Promise<string> {
return (
new SignJWT({ fern })
.setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
.setIssuedAt()
// be sure to set an appropriate expiration duration based on the level of sensitivity (i.e. api key) contained within the token, and the access that the token confers
.setExpirationTime('30d')
.setIssuer(JWT_ISSUER)
.sign(getJwtTokenSecret())
)
}

export function createCallbackUrl(
fern_token: string,
state: string | null
): URL {
const url = new URL(JWT_CALLBACK_PATHNAME, DOCS_ORIGIN)

// sends the fern_token to fern docs as a query parameter (please be sure that this is over HTTPS)
url.searchParams.set('fern_token', fern_token)

// preserve the state
if (state) {
url.searchParams.set('state', state)
}

return url
}

export const dynamic = 'force-dynamic'

// After the user has either signed up or logged in, they will be redirected back to a `/callback` url.
Expand Down
14 changes: 8 additions & 6 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { signFernJWT, createCallbackUrl } from '@/auth/utils'
import { redirect } from 'next/navigation'
import { createCallbackUrl, signFernJWT } from './api/login/route'
import { use } from 'react'

const audiences = ['internal', 'beta']

export default function Home({
searchParams: searchParamsPromise,
}: {
interface HomeProps {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const searchParams = use(searchParamsPromise)
}

export default function Home(props: HomeProps) {
const searchParams = use(props.searchParams)

// This is a server action that mocks the login process.
// please see `app/api/login/route.ts` for a full implementation.
async function handleSubmit(formData: FormData) {
'use server'
const audience = formData
Expand Down
55 changes: 55 additions & 0 deletions auth/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { SignJWT } from 'jose'

// your domain
const JWT_ISSUER = 'https://test-jwt-auth-smoky.vercel.app'

// this is the domain of your docs, (or, if subpathed, use the apex here: yourdomain.com);
const DOCS_ORIGIN = 'https://test-jwt-auth-smoky.docs.buildwithfern.com'

// this is path that you will redirect to in the docs instance, and let Fern set the fern_token. This is preferred.
// alternatively, you may opt to set the `Set-Cookie` header directly using `fern_token` (case sensitive) if on the same domain.
// if subpathed docs, be sure to include the subpath set by your proxy, i.e. `/docs/api/fern-docs/auth/jwt/callback`.
const JWT_CALLBACK_PATHNAME = '/api/fern-docs/auth/jwt/callback'

// JWT payload must include a `fern` key. All fields are optional:
interface FernUser {
apiKey?: string // api key injection into the runnable API Playground
audience?: string[] // ACLs -> this controls which part of the docs are visible to the user
}

// this is the symmetric secret key that will be provided by Fern:
function getJwtTokenSecret(): Uint8Array {
if (!process.env.JWT_TOKEN_SECRET) {
throw new Error('JWT_TOKEN_SECRET is not set')
}
return new TextEncoder().encode(process.env.JWT_TOKEN_SECRET)
}

export function signFernJWT(fern: FernUser): Promise<string> {
return (
new SignJWT({ fern })
.setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
.setIssuedAt()
// be sure to set an appropriate expiration duration based on the level of sensitivity (i.e. api key) contained within the token, and the access that the token confers
.setExpirationTime('30d')
.setIssuer(JWT_ISSUER)
.sign(getJwtTokenSecret())
)
}

export function createCallbackUrl(
fern_token: string,
state: string | null
): URL {
const url = new URL(JWT_CALLBACK_PATHNAME, DOCS_ORIGIN)

// sends the fern_token to fern docs as a query parameter (please be sure that this is over HTTPS)
url.searchParams.set('fern_token', fern_token)

// preserve the state
if (state) {
url.searchParams.set('state', state)
}

return url
}

1 comment on commit 1452214

@vercel
Copy link

@vercel vercel bot commented on 1452214 Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.