Skip to content

Commit

Permalink
feat(#673, #523, #848): back-port authjs migration (#849)
Browse files Browse the repository at this point in the history
Co-authored-by: Zoey <[email protected]>
  • Loading branch information
phoenix-ru and zoey-kaiser authored Aug 20, 2024
1 parent 2374f40 commit 355e865
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 244 deletions.
16 changes: 13 additions & 3 deletions playground-authjs/app.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
<script setup lang="ts">
import { useAuth, useRoute, useFetch, useRequestHeaders } from '#imports'
import { useAuth, useRoute, useRequestHeaders, useAsyncData } from '#imports'
const { data, status, lastRefreshedAt, getCsrfToken, getProviders, signIn, signOut, getSession } = useAuth()
const providers = await getProviders()
const csrfToken = await getCsrfToken()
const headers = useRequestHeaders(['cookie']) as HeadersInit
const { data: token } = await useFetch('/api/token', { headers })
// TEMP: Due to a bug in Nuxt `$fetch` (and thus in `useFetch`),
// we need to transform `undefined` returned from `$fetch` to `null`.
// The issue seems to be in type coalescing happening under the hood of `$fetch`:
// `null` and `''` are both transformed into `undefined` which is not correct.
const { data: token } = await useAsyncData(
'/api/token',
async () => {
const headers = useRequestHeaders(['cookie'])
const result = await $fetch('/api/token', { headers })
return result ?? null
}
)
const route = useRoute()
</script>
Expand Down
6 changes: 3 additions & 3 deletions playground-local/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@nuxt/test-utils": "^3.14.0",
"@playwright/test": "^1.45.3",
"@nuxt/test-utils": "^3.14.1",
"@playwright/test": "^1.46.0",
"@types/jsonwebtoken": "^9.0.6",
"@types/node": "^18.19.42",
"@types/node": "^18.19.44",
"@vue/test-utils": "^2.4.6",
"eslint": "^8.57.0",
"nuxt": "^3.12.4",
Expand Down
4 changes: 2 additions & 2 deletions playground-refresh/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@nuxt/test-utils": "^3.14.0",
"@playwright/test": "^1.45.3",
"@nuxt/test-utils": "^3.14.1",
"@playwright/test": "^1.46.0",
"@types/jsonwebtoken": "^9.0.6",
"@vue/test-utils": "^2.4.6",
"eslint": "^8.57.0",
Expand Down
306 changes: 226 additions & 80 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

318 changes: 183 additions & 135 deletions src/runtime/server/services/authjs/nuxtAuthHandler.ts

Large diffs are not rendered by default.

35 changes: 15 additions & 20 deletions src/runtime/server/services/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { H3Event } from 'h3'
import getURL from 'requrl'
import { joinURL } from 'ufo'
import { camelCase } from 'scule'
import { isProduction } from '../../helpers'
import { ERROR_MESSAGES } from './errors'
Expand All @@ -9,13 +8,13 @@ import { useRuntimeConfig } from '#imports'
/**
* Get `origin` and fallback to `x-forwarded-host` or `host` headers if not in production.
*/
export const getServerOrigin = (event?: H3Event): string => {
export function getServerOrigin (event?: H3Event): string {
const config = useRuntimeConfig()

// Prio 1: Environment variable
const envOriginKey = config.public.auth.originEnvKey!
const envOriginKeyCamelcase = camelCase(envOriginKey, { normalize: true })
const envOrigin = (config[envOriginKeyCamelcase] ?? process.env[envOriginKey]) as string | undefined
const envOriginKey = config.public.auth.originEnvKey
const envFromRuntimeConfig = extractFromRuntimeConfig(config, envOriginKey)
const envOrigin = envFromRuntimeConfig ?? process.env[envOriginKey]
if (envOrigin) {
return envOrigin
}
Expand All @@ -34,20 +33,16 @@ export const getServerOrigin = (event?: H3Event): string => {
throw new Error(ERROR_MESSAGES.NO_ORIGIN)
}

/** Get the request url or construct it */
export const getRequestURLFromRequest = (event: H3Event, { trustHost }: { trustHost: boolean }): string | undefined => {
if (trustHost) {
const forwardedValue = getURL(event.node.req)
if (forwardedValue) {
return Array.isArray(forwardedValue) ? forwardedValue[0] : forwardedValue
}
}
type RuntimeConfig = ReturnType<typeof useRuntimeConfig>

let origin
try {
origin = getServerOrigin(event)
} catch (error) {
return undefined
}
return joinURL(origin, useRuntimeConfig().public.auth.computed.pathname)
function extractFromRuntimeConfig (config: RuntimeConfig, envVariableName: string): string | undefined {
let normalized = envVariableName.startsWith('NUXT_')
? envVariableName.slice(5)
: envVariableName
normalized = camelCase(normalized, { normalize: true })

const extracted = config[normalized]
return typeof extracted === 'string'
? extracted
: undefined
}
1 change: 1 addition & 0 deletions src/runtime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ export interface ModuleOptionsNormalized extends ModuleOptions {
provider: Required<NonNullable<ModuleOptions['provider']>>
sessionRefresh: NonNullable<ModuleOptions['sessionRefresh']>
globalAppMiddleware: NonNullable<ModuleOptions['globalAppMiddleware']>
originEnvKey: string

computed: {
origin: string | undefined
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/utils/checkSessionResult.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const isNonEmptyObject = (obj: any) => typeof obj === 'object' && Object.keys(obj).length > 0
export const isNonEmptyObject = (obj: any) => typeof obj === 'object' && obj !== null && Object.keys(obj).length > 0

0 comments on commit 355e865

Please sign in to comment.