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 @@ 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 +}