Skip to content

Commit

Permalink
chore(examples): Add Auth.js chained middleware example using Nosecone
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmytton committed Dec 19, 2024
1 parent 02e4435 commit 83d732f
Show file tree
Hide file tree
Showing 15 changed files with 1,486 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,33 @@ updates:
- dependency-name: eslint
versions: [">=9"]

- package-ecosystem: npm
directory: /examples/nextjs-authjs-nosecone
schedule:
# Our dependencies should be checked daily
interval: daily
assignees:
- blaine-arcjet
- e-moran
reviewers:
- blaine-arcjet
- e-moran
commit-message:
prefix: deps(example)
prefix-development: deps(example)
groups:
dependencies:
patterns:
- "*"
ignore:
# Ignore updates to the @types/node package due to conflict between
# Headers in DOM.
- dependency-name: "@types/node"
versions: [">18.18"]
# TODO(#539): Upgrade to eslint 9
- dependency-name: eslint
versions: [">=9"]

- package-ecosystem: npm
directory: /examples/nextjs-bot-categories
schedule:
Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/reusable-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,50 @@ jobs:
AUTH_SECRET: TEST_SECRET
run: npm run build

nextjs-authjs-nosecone:
name: Next.js + Auth.js 5 + Nosecone
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# Environment security
- name: Harden Runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
fonts.googleapis.com:443
fonts.gstatic.com:443
github.com:443
registry.npmjs.org:443
# Checkout
# Most toolchains require checkout first
- name: Checkout
uses: actions/checkout@v4

# Language toolchains
- name: Install Node
uses: actions/[email protected]
with:
node-version: 20

# Workflow

- name: Install dependencies
run: npm ci

- name: Install example dependencies
working-directory: examples/nextjs-authjs-nosecone
run: npm ci

- name: Build
working-directory: examples/nextjs-authjs-nosecone
env:
AUTH_SECRET: TEST_SECRET
run: npm run build

nextjs-bot-categories:
name: Next.js + Bot categories
runs-on: ubuntu-latest
Expand Down
8 changes: 8 additions & 0 deletions examples/nextjs-authjs-nosecone/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Set a secret for NextAuth.js
# Linux: `openssl rand -hex 32` or go to https://generate-secret.vercel.app/32
AUTH_SECRET=
# Set your GitHub credentials by creating a new OAuth App at
# https://github.com/settings/developers See also:
# https://authjs.dev/reference/core/providers/github
GITHUB_ID=
GITHUB_SECRET=
20 changes: 20 additions & 0 deletions examples/nextjs-authjs-nosecone/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.DS_Store

node_modules/
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.yarn-integrity
.npm

.eslintcache

*.tsbuildinfo
next-env.d.ts

.next
.vercel
.env*.local
40 changes: 40 additions & 0 deletions examples/nextjs-authjs-nosecone/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<a href="https://arcjet.com" target="_arcjet-home">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://arcjet.com/logo/arcjet-dark-lockup-voyage-horizontal.svg">
<img src="https://arcjet.com/logo/arcjet-light-lockup-voyage-horizontal.svg" alt="Arcjet Logo" height="128" width="auto">
</picture>
</a>

# Arcjet Nosecone / Auth.js 5 Chained Middleware Example

This example shows how to create a base Auth.js setup with Nosecone chained in
the middleware to provide security headers.

## How to use

1. From the root of the project, install the SDK dependencies.

```bash
npm ci
```

2. Enter this directory and install the example's dependencies.

```bash
cd examples/nextjs-authjs-nosecone
npm ci
```

3. Rename `.env.local.example` to `.env.local` and fill in the required
environment variables. You will need to [create a GitHub OAuth
app](https://github.com/settings/applications) for testing. The callback URL
setting for your OAuth app is usually `http://localhost:3000`.

4. Start the dev server.

```bash
npm run dev
```

5. Visit `http://localhost:3000`.
6. Inspect the network requests to see the default security headers.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { handlers } from "auth";

export const { GET, POST } = handlers
16 changes: 16 additions & 0 deletions examples/nextjs-authjs-nosecone/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const metadata = {
title: 'Next.js',
description: 'Generated by Next.js',
}

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
12 changes: 12 additions & 0 deletions examples/nextjs-authjs-nosecone/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { auth } from "auth"

export default async function Index() {
const session = await auth()
if (!session) return <div>Not authenticated</div>

return (
<div>
<h1>Hello world</h1>
</div>
)
}
139 changes: 139 additions & 0 deletions examples/nextjs-authjs-nosecone/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import NextAuth from "next-auth"

// import Apple from "next-auth/providers/apple"
// import Atlassian from "next-auth/providers/atlassian"
// import Auth0 from "next-auth/providers/auth0"
// import Authentik from "next-auth/providers/authentik"
// import AzureAD from "next-auth/providers/azure-ad"
// import AzureB2C from "next-auth/providers/azure-ad-b2c"
// import Battlenet from "next-auth/providers/battlenet"
// import Box from "next-auth/providers/box"
// import BoxyHQSAML from "next-auth/providers/boxyhq-saml"
// import Bungie from "next-auth/providers/bungie"
// import Cognito from "next-auth/providers/cognito"
// import Coinbase from "next-auth/providers/coinbase"
// import Discord from "next-auth/providers/discord"
// import Dropbox from "next-auth/providers/dropbox"
// import DuendeIDS6 from "next-auth/providers/duende-identity-server6"
// import Eveonline from "next-auth/providers/eveonline"
// import Facebook from "next-auth/providers/facebook"
// import Faceit from "next-auth/providers/faceit"
// import FortyTwoSchool from "next-auth/providers/42-school"
// import Foursquare from "next-auth/providers/foursquare"
// import Freshbooks from "next-auth/providers/freshbooks"
// import Fusionauth from "next-auth/providers/fusionauth"
import GitHub from "next-auth/providers/github"
// import Gitlab from "next-auth/providers/gitlab"
// import Google from "next-auth/providers/google"
// import Hubspot from "next-auth/providers/hubspot"
// import Instagram from "next-auth/providers/instagram"
// import Kakao from "next-auth/providers/kakao"
// import Keycloak from "next-auth/providers/keycloak"
// import Line from "next-auth/providers/line"
// import LinkedIn from "next-auth/providers/linkedin"
// import Mailchimp from "next-auth/providers/mailchimp"
// import Mailru from "next-auth/providers/mailru"
// import Medium from "next-auth/providers/medium"
// import Naver from "next-auth/providers/naver"
// import Netlify from "next-auth/providers/netlify"
// import Okta from "next-auth/providers/okta"
// import Onelogin from "next-auth/providers/onelogin"
// import Osso from "next-auth/providers/osso"
// import Osu from "next-auth/providers/osu"
// import Passage from "next-auth/providers/passage"
// import Patreon from "next-auth/providers/patreon"
// import Pinterest from "next-auth/providers/pinterest"
// import Pipedrive from "next-auth/providers/pipedrive"
// import Reddit from "next-auth/providers/reddit"
// import Salesforce from "next-auth/providers/salesforce"
// import Slack from "next-auth/providers/slack"
// import Spotify from "next-auth/providers/spotify"
// import Strava from "next-auth/providers/strava"
// import Todoist from "next-auth/providers/todoist"
// import Trakt from "next-auth/providers/trakt"
// import Twitch from "next-auth/providers/twitch"
// import Twitter from "next-auth/providers/twitter"
// import UnitedEffects from "next-auth/providers/united-effects"
// import Vk from "next-auth/providers/vk"
// import Wikimedia from "next-auth/providers/wikimedia"
// import Wordpress from "next-auth/providers/wordpress"
// import WorkOS from "next-auth/providers/workos"
// import Yandex from "next-auth/providers/yandex"
// import Zitadel from "next-auth/providers/zitadel"
// import Zoho from "next-auth/providers/zoho"
// import Zoom from "next-auth/providers/zoom"

import type { NextAuthConfig } from "next-auth"

export const config = {
theme: {
logo: "https://next-auth.js.org/img/logo/logo-sm.png",
},
providers: [
// Apple,
// Atlassian,
// Auth0,
// Authentik,
// AzureAD,
// AzureB2C,
// Battlenet,
// Box,
// BoxyHQSAML,
// Bungie,
// Cognito,
// Coinbase,
// Discord,
// Dropbox,
// DuendeIDS6,
// Eveonline,
// Facebook,
// Faceit,
// FortyTwoSchool,
// Foursquare,
// Freshbooks,
// Fusionauth,
GitHub,
// Gitlab,
// Google,
// Hubspot,
// Instagram,
// Kakao,
// Keycloak,
// Line,
// LinkedIn,
// Mailchimp,
// Mailru,
// Medium,
// Naver,
// Netlify,
// Okta,
// Onelogin,
// Osso,
// Osu,
// Passage,
// Patreon,
// Pinterest,
// Pipedrive,
// Reddit,
// Salesforce,
// Slack,
// Spotify,
// Strava,
// Todoist,
// Trakt,
// Twitch,
// Twitter,
// UnitedEffects,
// Vk,
// Wikimedia,
// Wordpress,
// WorkOS,
// Yandex,
// Zitadel,
// Zoho,
// Zoom,
],
basePath: "/auth",
} satisfies NextAuthConfig

export const { handlers, auth, signIn, signOut } = NextAuth(config)
7 changes: 7 additions & 0 deletions examples/nextjs-authjs-nosecone/environment.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare namespace NodeJS {
export interface ProcessEnv {
readonly AUTH_SECRET: string;
readonly AUTH_GITHUB_ID: string;
readonly AUTH_GITHUB_SECRET: string;
}
}
23 changes: 23 additions & 0 deletions examples/nextjs-authjs-nosecone/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { type NoseconeOptions, createMiddleware, defaults } from "@nosecone/next";
import { auth } from "auth";

// Nosecone security headers configuration
// https://docs.arcjet.com/nosecone/quick-start
const noseconeOptions: NoseconeOptions = {
...defaults,
};

const securityHeaders = createMiddleware(noseconeOptions);

export default auth(async (req) => {
if (!req.auth && !req.nextUrl.pathname.startsWith("/auth")) {
const newUrl = new URL("/auth/signin", req.nextUrl.origin)
return Response.redirect(newUrl)
}

return securityHeaders();
})

export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}
2 changes: 2 additions & 0 deletions examples/nextjs-authjs-nosecone/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** @type {import("next").NextConfig} */
module.exports = {}
Loading

0 comments on commit 83d732f

Please sign in to comment.