Skip to content

Commit fbc89ea

Browse files
authored
chore(apps): add separate apps/dev/express app (#10736)
1 parent b7d1f9e commit fbc89ea

File tree

20 files changed

+754
-93
lines changed

20 files changed

+754
-93
lines changed

apps/dev/express/.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
AUTH_SECRET=
2+
3+
AUTH_GITHUB_ID=
4+
AUTH_GITHUB_SECRET=
5+
6+
AUTH_GOOGLE_ID=
7+
AUTH_GOOGLE_SECRET=

apps/dev/express/.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# API keys and secrets
2+
.env
3+
4+
# Dependency directory
5+
node_modules
6+
7+
# Editors
8+
.idea
9+
*.iml
10+
.vscode/settings.json
11+
12+
# OS metadata
13+
.DS_Store
14+
Thumbs.db
15+
16+
# Ignore built ts files
17+
dist/**/*
18+
19+
# Ignore built css files
20+
/public/css/output.css
21+

apps/dev/express/.prettierignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
.DS_Store
3+
node_modules
4+
/dist
5+
/.turbo
6+
/package
7+
.env
8+
.env.*
9+
!.env.example
10+
11+
# Ignore files for PNPM, NPM and YARN
12+
pnpm-lock.yaml
13+
package-lock.json
14+
yarn.lock

apps/dev/express/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
> The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/examples/express). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth).
2+
3+
<p align="center">
4+
<br/>
5+
<a href="https://authjs.dev" target="_blank"><img width="150px" src="https://authjs.dev/img/logo-sm.png" /></a>
6+
<h3 align="center">Auth.js Example App with <a href="https://expressjs.com">Express</a></h3>
7+
<p align="center">
8+
Open Source. Full Stack. Own Your Data.
9+
</p>
10+
<p align="center" style="align: center;">
11+
<a href="https://npm.im/@auth/express">
12+
<img alt="npm" src="https://img.shields.io/npm/v/@auth/express?color=green&label=@auth/express&style=flat-square">
13+
</a>
14+
<a href="https://bundlephobia.com/result?p=@auth/express">
15+
<img src="https://img.shields.io/bundlephobia/minzip/@auth/express?label=size&style=flat-square" alt="Bundle Size"/>
16+
</a>
17+
<a href="https://www.npmtrends.com/@auth/express">
18+
<img src="https://img.shields.io/npm/dm/@auth/express?label=%20downloads&style=flat-square" alt="Downloads" />
19+
</a>
20+
<a href="https://npm.im/next-auth">
21+
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
22+
</a>
23+
</p>
24+
</p>
25+
26+
# Documentation
27+
28+
- [express.authjs.dev](https://express.authjs.dev)

apps/dev/express/api/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { app } from "../src/app.js"
2+
3+
export default app

apps/dev/express/package.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "express-auth-app",
3+
"description": "Express + Auth.js Developer app",
4+
"type": "module",
5+
"private": true,
6+
"scripts": {
7+
"start": "node --env-file=.env dist/server.js",
8+
"clean": "rm -rf dist",
9+
"build": "pnpm build:ts && pnpm build:css",
10+
"build:ts": "tsc",
11+
"build:css": "tailwindcss -i ./public/css/style.css -o ./public/css/output.css",
12+
"dev": "tsx watch --env-file=.env src/server.ts & pnpm build:css -w",
13+
"lint": "eslint src/*.ts --fix",
14+
"prettier": "prettier src/*.ts --write"
15+
},
16+
"author": "Auth.js Team (https://authjs.dev/contributors)",
17+
"license": "MIT",
18+
"dependencies": {
19+
"@auth/express": "workspace:*",
20+
"express": "^4.19.2",
21+
"morgan": "^1.10.0",
22+
"pug": "^3.0.2"
23+
},
24+
"devDependencies": {
25+
"@prettier/plugin-pug": "^3.0.0",
26+
"@types/express": "^4.17.21",
27+
"@types/morgan": "^1.9.9",
28+
"@types/pug": "^2.0.10",
29+
"tsx": "^4.7.3",
30+
"typescript": "5.4.5"
31+
},
32+
"engines": {
33+
"node": ">=20.11.0"
34+
}
35+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@tailwind base;
2+
3+
@tailwind components;
4+
5+
@tailwind utilities;

apps/dev/express/src/app.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import express, { type Request, type Response } from "express"
2+
import logger from "morgan"
3+
import { join } from "node:path"
4+
5+
import {
6+
errorHandler,
7+
errorNotFoundHandler,
8+
} from "./middleware/error.middleware.js"
9+
10+
import {
11+
authenticatedUser,
12+
currentSession,
13+
} from "./middleware/auth.middleware.js"
14+
import { ExpressAuth } from "@auth/express"
15+
import { authConfig } from "./config/auth.config.js"
16+
import * as pug from "pug"
17+
18+
export const app = express()
19+
20+
app.set("port", process.env.PORT || 3004)
21+
22+
// @ts-expect-error (https://stackoverflow.com/questions/45342307/error-cannot-find-module-pug)
23+
app.engine("pug", pug.__express)
24+
app.set("views", join(import.meta.dirname, "..", "views"))
25+
app.set("view engine", "pug")
26+
27+
// Trust Proxy for Proxies (Heroku, Render.com, Docker behind Nginx, etc)
28+
// https://stackoverflow.com/questions/40459511/in-express-js-req-protocol-is-not-picking-up-https-for-my-secure-link-it-alwa
29+
app.set("trust proxy", true)
30+
31+
app.use(logger("dev"))
32+
33+
// Serve static files
34+
// NB: Uncomment this out if you want Express to serve static files for you vs. using a
35+
// hosting provider which does so for you (for example through a CDN).
36+
// app.use(express.static(join(import.meta.dirname, "..", "public")))
37+
38+
// Parse incoming requests data
39+
app.use(express.urlencoded({ extended: true }))
40+
app.use(express.json())
41+
42+
// Set session in res.locals
43+
app.use(currentSession)
44+
45+
// Set up ExpressAuth to handle authentication
46+
// IMPORTANT: It is highly encouraged set up rate limiting on this route
47+
app.use("/api/auth/*", ExpressAuth(authConfig))
48+
49+
// Routes
50+
app.get("/protected", async (_req: Request, res: Response) => {
51+
res.render("protected", { session: res.locals.session })
52+
})
53+
54+
app.get(
55+
"/api/protected",
56+
authenticatedUser,
57+
async (_req: Request, res: Response) => {
58+
res.json(res.locals.session)
59+
},
60+
)
61+
62+
app.get("/", async (_req: Request, res: Response) => {
63+
res.render("index", {
64+
title: "Express Auth Example",
65+
user: res.locals.session?.user,
66+
})
67+
})
68+
69+
// Error handlers
70+
app.use(errorNotFoundHandler)
71+
app.use(errorHandler)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Apple from "@auth/express/providers/apple"
2+
import Auth0 from "@auth/express/providers/auth0"
3+
import AzureB2C from "@auth/express/providers/azure-ad-b2c"
4+
import BoxyHQSAML from "@auth/express/providers/boxyhq-saml"
5+
import Cognito from "@auth/express/providers/cognito"
6+
import Coinbase from "@auth/express/providers/coinbase"
7+
import Discord from "@auth/express/providers/discord"
8+
import Dropbox from "@auth/express/providers/dropbox"
9+
import Facebook from "@auth/express/providers/facebook"
10+
import GitHub from "@auth/express/providers/github"
11+
import Gitlab from "@auth/express/providers/gitlab"
12+
import Google from "@auth/express/providers/google"
13+
import Hubspot from "@auth/express/providers/hubspot"
14+
import Keycloak from "@auth/express/providers/keycloak"
15+
import LinkedIn from "@auth/express/providers/linkedin"
16+
import Netlify from "@auth/express/providers/netlify"
17+
import Okta from "@auth/express/providers/okta"
18+
import Passage from "@auth/express/providers/passage"
19+
import Pinterest from "@auth/express/providers/pinterest"
20+
import Reddit from "@auth/express/providers/reddit"
21+
import Slack from "@auth/express/providers/slack"
22+
import Spotify from "@auth/express/providers/spotify"
23+
import Twitch from "@auth/express/providers/twitch"
24+
import Twitter from "@auth/express/providers/twitter"
25+
import WorkOS from "@auth/express/providers/workos"
26+
import Zoom from "@auth/express/providers/zoom"
27+
28+
export const authConfig = {
29+
trustHost: true,
30+
debug: process.env.NODE_ENV !== "production" ? true : false,
31+
providers: [
32+
Apple,
33+
Auth0,
34+
AzureB2C({
35+
clientId: process.env.AUTH_AZURE_AD_B2C_ID,
36+
clientSecret: process.env.AUTH_AZURE_AD_B2C_SECRET,
37+
issuer: process.env.AUTH_AZURE_AD_B2C_ISSUER,
38+
}),
39+
BoxyHQSAML({
40+
clientId: "dummy",
41+
clientSecret: "dummy",
42+
issuer: process.env.AUTH_BOXYHQ_SAML_ISSUER,
43+
}),
44+
Cognito,
45+
Coinbase,
46+
Discord,
47+
Dropbox,
48+
Facebook,
49+
GitHub,
50+
Gitlab,
51+
Google,
52+
Hubspot,
53+
Keycloak,
54+
LinkedIn,
55+
Netlify,
56+
Okta,
57+
Passage,
58+
Pinterest,
59+
Reddit,
60+
Slack,
61+
Spotify,
62+
Twitch,
63+
Twitter,
64+
WorkOS({
65+
connection: process.env.AUTH_WORKOS_CONNECTION!,
66+
}),
67+
Zoom,
68+
],
69+
}

apps/dev/express/src/errors.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export class HttpError extends Error {
2+
status: number
3+
constructor(status: number, message: string) {
4+
super(message)
5+
this.status = status
6+
}
7+
}
8+
9+
export class NotFoundError extends HttpError {
10+
constructor(message: string, status = 404) {
11+
super(status, message)
12+
this.name = "NotFoundError"
13+
}
14+
}

0 commit comments

Comments
 (0)