diff --git a/playground/app.vue b/playground/app.vue
index f4e424ba..177a8339 100644
--- a/playground/app.vue
+++ b/playground/app.vue
@@ -1,5 +1,13 @@
@@ -53,6 +61,17 @@ const { loggedIn, session, clear } = useUserSession()
>
Login with Twitch
+
+ Login with JWT
+
diff --git a/playground/auth.d.ts b/playground/auth.d.ts
index 8d22d014..0e5f183a 100644
--- a/playground/auth.d.ts
+++ b/playground/auth.d.ts
@@ -5,6 +5,7 @@ declare module '#auth-utils' {
github?: any
google?: any
twitch?: any
+ jwt?: any
}
loggedInAt: number
}
diff --git a/playground/server/routes/auth/jwt.post.ts b/playground/server/routes/auth/jwt.post.ts
new file mode 100644
index 00000000..ededc26f
--- /dev/null
+++ b/playground/server/routes/auth/jwt.post.ts
@@ -0,0 +1,15 @@
+export default local.jwtEventHandler({
+ config: {
+ },
+ async onSuccess (event, { user }) {
+ await setUserSession(event, {
+ user: {
+ jwt: user,
+
+ },
+ loggedInAt: Date.now()
+ })
+
+ return user
+ }
+})
diff --git a/src/module.ts b/src/module.ts
index 59ae2623..96fc4dd4 100644
--- a/src/module.ts
+++ b/src/module.ts
@@ -3,7 +3,7 @@ import { sha256 } from 'ohash'
import { defu } from 'defu'
// Module options TypeScript interface definition
-export interface ModuleOptions {}
+export interface ModuleOptions { }
export default defineNuxtModule({
meta: {
@@ -36,6 +36,10 @@ export default defineNuxtModule({
from: resolver.resolve('./runtime/server/utils/oauth'),
imports: ['oauth']
},
+ {
+ from: resolver.resolve('./runtime/server/utils/local'),
+ imports: ['local']
+ },
{
from: resolver.resolve('./runtime/server/utils/session'),
imports: [
@@ -69,6 +73,7 @@ export default defineNuxtModule({
})
// OAuth settings
runtimeConfig.oauth = defu(runtimeConfig.oauth, {})
+
// GitHub Oauth
runtimeConfig.oauth.github = defu(runtimeConfig.oauth.github, {
clientId: '',
@@ -89,5 +94,15 @@ export default defineNuxtModule({
clientId: '',
clientSecret: ''
})
+
+ // Local settings
+ runtimeConfig.local = defu(runtimeConfig.local, {})
+
+ // JWT Local
+ runtimeConfig.local.jwt = defu(runtimeConfig.local.jwt, {
+ loginURL: '',
+ userURL: ''
+ })
+
}
})
diff --git a/src/runtime/server/lib/local/jwt.ts b/src/runtime/server/lib/local/jwt.ts
new file mode 100644
index 00000000..74e32b6e
--- /dev/null
+++ b/src/runtime/server/lib/local/jwt.ts
@@ -0,0 +1,63 @@
+import type { H3Event, H3Error } from 'h3'
+import { createError, eventHandler } from 'h3'
+import { ofetch } from 'ofetch'
+import { defu } from 'defu'
+import { useRuntimeConfig } from '#imports'
+
+export interface JWTConfig {
+ /**
+ * GitHub OAuth Client ID
+ * @default process.env.NUXT_LOCAL_JWT_LOGIN_URL
+ */
+ loginURL?: string
+
+ /**
+ * GitHub OAuth Client ID
+ * @default process.env.NUXT_LOCAL_JWT_USER_URL
+ */
+ userURL?: string
+}
+
+interface JWTAuthConfig {
+ config?: JWTConfig
+ onSuccess: (event: H3Event, result: { user: any, tokens: any }) => Promise | void
+ onError?: (event: H3Event, error: H3Error) => Promise | void
+}
+
+export function jwtEventHandler ({ config, onSuccess, onError }: JWTAuthConfig) {
+ return eventHandler(async (event: H3Event) => {
+ // @ts-ignore
+ config = defu(config, useRuntimeConfig(event).local?.jwt) as JWTConfig
+ console.log(config)
+ if (!config.loginURL || !config.userURL) {
+ const error = createError({
+ statusCode: 500,
+ message: 'Missing NUXT_LOCAL_JWT_LOGIN_URL or NUXT_LOCAL_JWT_USER_URL env variables.'
+ })
+ if (!onError) throw error
+ return onError(event, error)
+ }
+ const body = await readBody(event)
+
+
+ const tokens: any = await ofetch(config.loginURL, {
+ method: 'POST',
+ body
+ })
+
+ const user: any = await ofetch(
+ config.userURL,
+ {
+ headers: {
+ Authorization: `Bearer ${tokens.token}`,
+ },
+ }
+ )
+
+
+ return onSuccess(event, {
+ user,
+ tokens
+ })
+ })
+}
diff --git a/src/runtime/server/utils/local.ts b/src/runtime/server/utils/local.ts
new file mode 100644
index 00000000..cf89bf6e
--- /dev/null
+++ b/src/runtime/server/utils/local.ts
@@ -0,0 +1,5 @@
+import { jwtEventHandler } from '../lib/local/jwt'
+
+export const local = {
+ jwtEventHandler
+}