Skip to content

Commit

Permalink
Added the authjs-server middleware package
Browse files Browse the repository at this point in the history
  • Loading branch information
ivoilic committed Feb 19, 2023
1 parent 148f114 commit 5fadb1f
Show file tree
Hide file tree
Showing 19 changed files with 264 additions and 9 deletions.
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": "run-p build:*"
},
"license": "MIT",
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
1 change: 1 addition & 0 deletions packages/authjs-server/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../jest.config.js')
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": "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.4.0",
"hono": "3.*"
},
"devDependencies": {
"@auth/core": "^0.4.0",
"hono": "^3.0.0"
},
"engines": {
"node": ">=16.0.0"
}
}
67 changes: 67 additions & 0 deletions packages/authjs-server/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
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
authOptions.secret ??= process.env.AUTH_SECRET
authOptions.trustHost ??= !!(
process.env.AUTH_TRUST_HOST ??
process.env.VERCEL ??
process.env.NODE_ENV !== 'production'
)
return HonoAuthHandler(prefix, authOptions)
}

export type GetSessionResult = Promise<Session | null>

export async function getSession(req: Request, options: AuthConfig): GetSessionResult {
options.secret ??= process.env.AUTH_SECRET
options.trustHost ??= true

const url = new URL('/auth/session', req.url)
const response = await Auth(new Request(url, { headers: req.headers }), options)

const { status = 200 } = response

const data = await response.json()

if (!data || !Object.keys(data).length) return null
if (status === 200) return data as Session
const error = data as { message?: string }
throw new Error(error?.message)
}
26 changes: 26 additions & 0 deletions packages/authjs-server/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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()

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))

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"
],
}
4 changes: 2 additions & 2 deletions packages/firebase-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
"hono": "^2.7.2"
},
"devDependencies": {
"hono": "^2.7.2",
"@cloudflare/workers-types": "^3.14.1",
"@types/jest": "^28.1.4",
"firebase-tools": "^11.4.0",
"hono": "^2.7.2",
"jest": "^28.1.2",
"jest-environment-miniflare": "^2.6.0",
"prettier": "^2.7.1",
"ts-jest": "^28.0.5",
"typescript": "^4.7.4"
}
}
}
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 @@ -6414,6 +6431,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 @@ -8004,6 +8026,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 @@ -8532,6 +8559,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 @@ -8581,6 +8620,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

0 comments on commit 5fadb1f

Please sign in to comment.