From 486f83445b5e88ba99608f34a6a054c034e25d39 Mon Sep 17 00:00:00 2001 From: Seiya Nuta Date: Thu, 3 Nov 2022 03:17:41 +0900 Subject: [PATCH] [edge-functions/jwt-authentication] Fix for breaking changes in Next.js canary (#443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some following breaking changes were introduced in Next.js canary. This PR includes fixes for them. - https://github.com/vercel/next.js/pull/41767 - https://github.com/vercel/next.js/pull/41526 In addition to that, it also adds a runtime check to throw user-friendly error if `$JWT_SECRET_KEY` is missing. ### Description ### Demo URL ### Type of Change - [ ] New Example - [x] Example updates (Bug fixes, new features, etc.) - [ ] Other (changes to the codebase, but not to examples) ### New Example Checklist - [ ] 🛫 `npm run new-example` was used to create the example - [ ] 📚 The template wasn't used but I carefuly read the [Adding a new example](https://github.com/vercel/examples#adding-a-new-example) steps and implemented them in the example - [ ] 📱 Is it responsive? Are mobile and tablets considered? --- edge-functions/jwt-authentication/lib/auth.ts | 8 ++++---- edge-functions/jwt-authentication/lib/constants.ts | 10 +++++++++- edge-functions/jwt-authentication/pages/protected.tsx | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/edge-functions/jwt-authentication/lib/auth.ts b/edge-functions/jwt-authentication/lib/auth.ts index a1a2aab78..d7b5d7a0f 100644 --- a/edge-functions/jwt-authentication/lib/auth.ts +++ b/edge-functions/jwt-authentication/lib/auth.ts @@ -1,7 +1,7 @@ import type { NextRequest, NextResponse } from 'next/server' import { nanoid } from 'nanoid' import { SignJWT, jwtVerify } from 'jose' -import { USER_TOKEN, JWT_SECRET_KEY } from './constants' +import { USER_TOKEN, getJwtSecretKey } from './constants' interface UserJwtPayload { jti: string @@ -14,14 +14,14 @@ export class AuthError extends Error {} * Verifies the user's JWT token and returns its payload if it's valid. */ export async function verifyAuth(req: NextRequest) { - const token = req.cookies.get(USER_TOKEN) + const token = req.cookies.get(USER_TOKEN)?.value if (!token) throw new AuthError('Missing user token') try { const verified = await jwtVerify( token, - new TextEncoder().encode(JWT_SECRET_KEY) + new TextEncoder().encode(getJwtSecretKey()) ) return verified.payload as UserJwtPayload } catch (err) { @@ -38,7 +38,7 @@ export async function setUserCookie(res: NextResponse) { .setJti(nanoid()) .setIssuedAt() .setExpirationTime('2h') - .sign(new TextEncoder().encode(JWT_SECRET_KEY)) + .sign(new TextEncoder().encode(getJwtSecretKey())) res.cookies.set(USER_TOKEN, token, { httpOnly: true, diff --git a/edge-functions/jwt-authentication/lib/constants.ts b/edge-functions/jwt-authentication/lib/constants.ts index 340be6031..55c318ae9 100644 --- a/edge-functions/jwt-authentication/lib/constants.ts +++ b/edge-functions/jwt-authentication/lib/constants.ts @@ -1,3 +1,11 @@ export const USER_TOKEN = 'user-token' -export const JWT_SECRET_KEY = process.env.JWT_SECRET_KEY! +const JWT_SECRET_KEY: string | undefined = process.env.JWT_SECRET_KEY! + +export function getJwtSecretKey(): string { + if (!JWT_SECRET_KEY || JWT_SECRET_KEY.length === 0) { + throw new Error('The environment variable JWT_SECRET_KEY is not set.') + } + + return JWT_SECRET_KEY +} diff --git a/edge-functions/jwt-authentication/pages/protected.tsx b/edge-functions/jwt-authentication/pages/protected.tsx index 7da67676f..d7407d768 100644 --- a/edge-functions/jwt-authentication/pages/protected.tsx +++ b/edge-functions/jwt-authentication/pages/protected.tsx @@ -4,7 +4,7 @@ import { Page, Text, Code, Link, Button } from '@vercel/examples-ui' import { USER_TOKEN } from '@lib/constants' export default function Protected() { - const { reload } = useRouter() + const { reload } = useRouter(true) return (