Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth.js Middleware #52

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ yarn-error.log
*.tgz

# for debug or playing
sandbox
sandbox
.env
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"build:sentry": "yarn workspace @hono/sentry build",
"build:firebase-auth": "yarn workspace @hono/firebase-auth build",
"build:trpc-server": "yarn workspace @hono/trpc-server build",
"build:authjs-server": "yarn workspace @hono/authjs-server build",
"build:typebox-validator": "yarn workspace @hono/typebox-validator build",
"build": "run-p build:*"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/authjs-server/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
AUTH_SECRET=
GITHUB_ID=
GITHUB_SECRET=
1 change: 1 addition & 0 deletions packages/authjs-server/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @honojs/auth-js
45 changes: 45 additions & 0 deletions packages/authjs-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Auth.js Server Middleware for Hono

Auth.js Server Middleware adapts [Auth.js](https://authjs.dev/) server as middleware for Hono.

## Usage

```ts
import { authjsServer } from '@hono/auth-js-server'
import { Hono } from 'hono'

const app = new Hono()

const authOpts: HonoAuthConfig = {
providers: [
//@ts-expect-error issue https://github.com/nextauthjs/next-auth/issues/6174
GitHub({
clientId: process.env.GITHUB_ID as string,
clientSecret: process.env.GITHUB_SECRET as string,
}),
],
debug: true,
}

app.use('/auth/*', authjsServer(authOpts))

export default app
```

## Testing

Copy the example .env file and populate it with credentials from GitHub

```
cp .env.examaple .env
```

## Author

Ivo Ilić <https://github.com/ivoilic>

Based on the [Auth.js frameworks-solid-start package](https://github.com/nextauthjs/next-auth/tree/main/packages/frameworks-solid-start) by [OrJDev](https://github.com/OrJDev)

## License

MIT
9 changes: 9 additions & 0 deletions packages/authjs-server/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const baseConfig = require('../../jest.config.js')

module.exports = {
...baseConfig,
transform: {
'^.+\\.(ts|tsx)$': ['ts-jest', { useESM: true }],
},
extensionsToTreatAsEsm: ['.ts'],
}
41 changes: 41 additions & 0 deletions packages/authjs-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@hono/authjs-server",
"version": "0.0.1",
"description": "Auth.js Server Middleware for Hono",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/esm/index.d.ts",
"files": [
"dist"
],
"scripts": {
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
"build:cjs": "tsc -p tsconfig.cjs.json",
"build:esm": "tsc -p tsconfig.esm.json",
"build": "rimraf dist && yarn build:cjs && yarn build:esm",
"prerelease": "yarn build && yarn test",
"release": "yarn publish"
},
"license": "MIT",
"private": false,
"publishConfig": {
"registry": "https://registry.npmjs.org",
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/honojs/middleware.git"
},
"homepage": "https://github.com/honojs/middleware",
"peerDependencies": {
"@auth/core": "^0.5.1",
"hono": "3.*"
},
"devDependencies": {
"@auth/core": "^0.5.1",
"hono": "^3.0.0"
},
"engines": {
"node": ">=16.0.0"
}
}
42 changes: 42 additions & 0 deletions packages/authjs-server/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Auth } from '@auth/core'
import type { AuthAction, AuthConfig, Session } from '@auth/core/types'
import type { Context, MiddlewareHandler } from 'hono'

export interface HonoAuthConfig extends AuthConfig {
/**
* Defines the base path for the auth routes.
* @default '/auth'
*/
prefix?: string
}

const actions: AuthAction[] = [
'providers',
'session',
'csrf',
'signin',
'signout',
'callback',
'verify-request',
'error',
]

function HonoAuthHandler(prefix: string, authOptions: HonoAuthConfig) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return async (c: Context) => {
const { req } = c
const url = new URL(req.url)
const action = url.pathname.slice(prefix.length + 1).split('/')[0] as AuthAction

if (!actions.includes(action) || !url.pathname.startsWith(prefix + '/')) {
return
}

return await Auth(req.raw, authOptions)
}
}

export const authjsServer = (config: HonoAuthConfig): MiddlewareHandler => {
const { prefix = '/auth', ...authOptions } = config
return HonoAuthHandler(prefix, authOptions)
}
30 changes: 30 additions & 0 deletions packages/authjs-server/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import GitHub from '@auth/core/providers/github'
import { Hono } from 'hono'
import { authjsServer, type HonoAuthConfig } from '../src'

describe('Auth.js Adapter Middleware', () => {
const app = new Hono()

app.use('/auth/*', (c, next) => {
const authOpts: HonoAuthConfig = {
secret: process.env.AUTH_SECRET as string,
trustHost: true,
providers: [
//@ts-expect-error issue https://github.com/nextauthjs/next-auth/issues/6174
GitHub({
clientId: process.env.GITHUB_ID as string,
clientSecret: process.env.GITHUB_SECRET as string,
}),
],
debug: true,
}
const auth = authjsServer(authOpts)
return auth(c, next)
})

it('Should return 200 response', async () => {
const req = new Request('http://localhost/auth/error')
const res = await app.request(req)
expect(res.status).toBe(200)
})
})
8 changes: 8 additions & 0 deletions packages/authjs-server/tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"declaration": false,
"outDir": "./dist/cjs"
}
}
8 changes: 8 additions & 0 deletions packages/authjs-server/tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"declaration": true,
"outDir": "./dist/esm"
}
}
9 changes: 9 additions & 0 deletions packages/authjs-server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
},
"include": [
"src/**/*.ts"
],
}
2 changes: 1 addition & 1 deletion packages/graphql-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@
"engines": {
"node": ">=16.0.0"
}
}
}
2 changes: 1 addition & 1 deletion packages/hello/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@
"devDependencies": {
"hono": "^2.7.2"
}
}
}
2 changes: 1 addition & 1 deletion packages/qwik-city/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@
"engines": {
"node": ">=18"
}
}
}
4 changes: 2 additions & 2 deletions packages/sentry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
"replacer": "dist/replacer.js"
},
"license": "MIT",
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/honojs/middleware.git"
},
"homepage": "https://github.com/honojs/middleware",
"author": "Samuel Lippert <[email protected]> (https://github.com/sam-lippert)",
"private": false,
"publishConfig": {
"registry": "https://registry.npmjs.org",
"access": "public"
Expand Down Expand Up @@ -61,4 +61,4 @@
"ts-jest": "^28.0.5",
"typescript": "^4.7.4"
}
}
}
2 changes: 1 addition & 1 deletion packages/zod-validator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@
"hono": "^3.0.0",
"zod": "3.19.1"
}
}
}
44 changes: 44 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@
call-me-maybe "^1.0.1"
js-yaml "^4.1.0"

"@auth/core@^0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@auth/core/-/core-0.4.0.tgz#271e763cab2ba7f75760a601e0a62ee033e888b7"
integrity sha512-wHVljvVGPmKSjlxQUYZCOL4GGe26YqhT351sA2REE43YskaqRMYh1TVjBxpXcdG8/P8bw2DsHgl+aBEV3P5+KQ==
dependencies:
"@panva/hkdf" "^1.0.2"
cookie "0.5.0"
jose "^4.11.1"
oauth4webapi "^2.0.6"
preact "10.11.3"
preact-render-to-string "5.2.3"

"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
Expand Down Expand Up @@ -1341,6 +1353,11 @@
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.3.1.tgz#ba07b864a3c955f061aa30ea3ef7f4ae4449794a"
integrity sha512-wU5J8rUoo32oSef/rFpOT1HIjLjAv3qIDHkw1QIhODV3OpAVHi5oVzlouozg9obUmZKtbZ0qUe/m7FP0y0yBzA==

"@panva/hkdf@^1.0.2":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.0.4.tgz#4e02bb248402ff6c5c024e23a68438e2b0e69d67"
integrity sha512-003xWiCuvePbLaPHT+CRuaV4GlyCAVm6XYSbBZDHoWZGn1mNkVKFaDbGJjjxmEFvizUwlCoM6O18FCBMMky2zQ==

"@pkgr/utils@^2.3.1":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.3.1.tgz#0a9b06ffddee364d6642b3cd562ca76f55b34a03"
Expand Down Expand Up @@ -6424,6 +6441,11 @@ join-path@^1.1.1:
url-join "0.0.1"
valid-url "^1"

jose@^4.11.1:
version "4.12.0"
resolved "https://registry.yarnpkg.com/jose/-/jose-4.12.0.tgz#7f00cd2f82499b91623cd413b7b5287fd52651ed"
integrity sha512-wW1u3cK81b+SFcHjGC8zw87yuyUweEFe0UJirrXEw1NasW00eF7sZjeG3SLBGz001ozxQ46Y9sofDvhBmWFtXQ==

js-sdsl@^4.1.4:
version "4.2.0"
resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0"
Expand Down Expand Up @@ -8014,6 +8036,11 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==

oauth4webapi@^2.0.6:
version "2.1.0"
resolved "https://registry.yarnpkg.com/oauth4webapi/-/oauth4webapi-2.1.0.tgz#1f52c5ed1a8b2fe4743be86581654428905dd932"
integrity sha512-0YjXQA3viCby/So8rja4sBrdLMTTyzuQTzotMTT6uAgqmqanrpt8eBfLLaugUZaMZSzt3IdjJdGadr5YTC+Cww==

object-assign@^4, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
Expand Down Expand Up @@ -8542,6 +8569,18 @@ portfinder@^1.0.32:
debug "^3.2.7"
mkdirp "^0.5.6"

[email protected]:
version "5.2.3"
resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz#23d17376182af720b1060d5a4099843c7fe92fe4"
integrity sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==
dependencies:
pretty-format "^3.8.0"

[email protected]:
version "10.11.3"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.11.3.tgz#8a7e4ba19d3992c488b0785afcc0f8aa13c78d19"
integrity sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==

preferred-pm@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/preferred-pm/-/preferred-pm-3.0.3.tgz#1b6338000371e3edbce52ef2e4f65eb2e73586d6"
Expand Down Expand Up @@ -8591,6 +8630,11 @@ pretty-format@^29.0.0, pretty-format@^29.3.1:
ansi-styles "^5.0.0"
react-is "^18.0.0"

pretty-format@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==

process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
Expand Down