Skip to content

Commit

Permalink
refactor: assing names for built-in plugins (#86)
Browse files Browse the repository at this point in the history
* Update module.ts

* refactor: assign names to used plugins

* refactor: do not require `enforce=pre` on `directus:loggedIn` hook

* Update package.json

* Update .gitignore
  • Loading branch information
becem-gharbi committed Jun 17, 2024
1 parent 350f9d7 commit 45f1859
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 115 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ To implement a custom logic on user login/logout events, you can use `directus:l

```js
export default defineNuxtPlugin({
enforce: "pre", // Should be registered before built-in `auth` plugin
hooks: {
"directus:loggedIn": (state) => {},
},
Expand Down
3 changes: 2 additions & 1 deletion directus/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
!.env
!.env
data
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
"dist"
],
"scripts": {
"directus:init": "cd directus && directus bootstrap",
"directus:start": "cd directus && directus start",
"directus:init": "cd directus && npx directus bootstrap",
"directus:start": "cd directus && npx directus start",
"dev": "nuxi dev playground",
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
"dev:build:ssr:session": "cross-env NUXT_SSR=true NUXT_PUBLIC_DIRECTUS_AUTH_MODE=session NODE_OPTIONS=--no-deprecation nuxi build playground",
Expand Down
1 change: 0 additions & 1 deletion playground/plugins/auth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { defineNuxtPlugin } from '#imports'

export default defineNuxtPlugin({
enforce: 'pre',
hooks: {
'directus:loggedIn': state => console.log(`LoggedIn ${state}`),
},
Expand Down
9 changes: 3 additions & 6 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ export default defineNuxtModule<ModuleOptions>({
// ################################## Rest setup ##################################
// ################################################################################

const restPlugin = resolve(runtimeDir, options.auth.enabled ? './plugins/rest' : './plugins/rest.basic')
addPlugin(restPlugin, { append: true })
addPlugin(resolve(runtimeDir, options.auth.enabled ? './plugins/rest' : './plugins/rest.basic'))

addImports({
name: 'useDirectusRest',
Expand Down Expand Up @@ -158,8 +157,7 @@ export default defineNuxtModule<ModuleOptions>({
},
])

const authPlugin = resolve(runtimeDir, './plugins/auth')
addPlugin(authPlugin, { append: true })
addPlugin(resolve(runtimeDir, './plugins/auth'))

addRouteMiddleware({
name: 'auth',
Expand All @@ -185,8 +183,7 @@ export default defineNuxtModule<ModuleOptions>({

if (options.graphql.enabled) {
if (options.auth.enabled && options.auth.mode === 'cookie') {
const graphqlPlugin = resolve(runtimeDir, './plugins/graphql')
addPlugin(graphqlPlugin, { append: true })
addPlugin(resolve(runtimeDir, './plugins/graphql'))
}

await installModule('nuxt-apollo', {
Expand Down
100 changes: 53 additions & 47 deletions src/runtime/plugins/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,67 @@ import {
useRouter,
} from '#imports'

export default defineNuxtPlugin(async (nuxtApp) => {
const config = nuxtApp.$config.public.directus as PublicConfig & { auth: { enabled: true } }
const { _loggedInFlag, _refreshOn, refresh, autoRefresh } = useDirectusSession()
const { user, _onLogout, fetchUser } = useDirectusAuth()
const { currentRoute } = useRouter()
export default defineNuxtPlugin({
name: 'directus:auth',
dependsOn: ['directus:rest'],
enforce: 'post',

_refreshOn.value = 0
setup: async (nuxtApp) => {
const config = nuxtApp.$config.public.directus as PublicConfig & { auth: { enabled: true } }
const { _loggedInFlag, _refreshOn, refresh, autoRefresh } = useDirectusSession()
const { user, _onLogout, fetchUser } = useDirectusAuth()
const { currentRoute } = useRouter()

nuxtApp.hook('directus:loggedIn', (state) => {
_loggedInFlag.value = state ? 1 : 0
})
_refreshOn.value = 0

nuxtApp.hook('app:mounted', () => {
addEventListener('storage', (event) => {
if (event.key === config.auth.loggedInFlagName) {
if (event.oldValue === '1' && event.newValue === '0' && user.value) {
_onLogout()
}
else if (event.oldValue === '0' && event.newValue === '1') {
location.reload()
nuxtApp.hook('directus:loggedIn', (state) => {
_loggedInFlag.value = state ? 1 : 0
})

nuxtApp.hook('app:mounted', () => {
addEventListener('storage', (event) => {
if (event.key === config.auth.loggedInFlagName) {
if (event.oldValue === '1' && event.newValue === '0' && user.value) {
_onLogout()
}
else if (event.oldValue === '0' && event.newValue === '1') {
location.reload()
}
}
}
})
})
})

function isFirstTime() {
const isPageFound = currentRoute.value?.matched.length > 0
const isPrerenderd = typeof nuxtApp.payload.prerenderedAt === 'number'
const isServerRendered = nuxtApp.payload.serverRendered
return (import.meta.server && !isPrerenderd && isPageFound) || (import.meta.client && (!isServerRendered || isPrerenderd || !isPageFound))
}
function isFirstTime() {
const isPageFound = currentRoute.value?.matched.length > 0
const isPrerenderd = typeof nuxtApp.payload.prerenderedAt === 'number'
const isServerRendered = nuxtApp.payload.serverRendered
return (import.meta.server && !isPrerenderd && isPageFound) || (import.meta.client && (!isServerRendered || isPrerenderd || !isPageFound))
}

async function isExpired() {
const authData = await useDirectusStorage().get()
const now = new Date().getTime()
return !authData?.expires_at || authData.expires_at < now + config.auth.msRefreshBeforeExpires!
}
async function isExpired() {
const authData = await useDirectusStorage().get()
const now = new Date().getTime()
return !authData?.expires_at || authData.expires_at < now + config.auth.msRefreshBeforeExpires!
}

function canFetchUser() {
const isSSO = currentRoute.value?.path === config.auth.redirect.callback && !currentRoute.value.query.reason
const { _loggedInFlag, _refreshToken, _sessionToken } = useDirectusSession()
return isSSO || _loggedInFlag.value || _refreshToken.get() || _sessionToken.get()
}
function canFetchUser() {
const isSSO = currentRoute.value?.path === config.auth.redirect.callback && !currentRoute.value.query.reason
const { _loggedInFlag, _refreshToken, _sessionToken } = useDirectusSession()
return isSSO || _loggedInFlag.value || _refreshToken.get() || _sessionToken.get()
}

if (isFirstTime() && canFetchUser()) {
await isExpired()
? await refresh().then(b => b ? fetchUser() : null)
: await fetchUser()
}
if (isFirstTime() && canFetchUser()) {
await isExpired()
? await refresh().then(b => b ? fetchUser() : null)
: await fetchUser()
}

if (user.value) {
await autoRefresh(true)
await nuxtApp.callHook('directus:loggedIn', true)
}
else {
_loggedInFlag.value = 0
}
if (user.value) {
await autoRefresh(true)
await nuxtApp.callHook('directus:loggedIn', true)
}
else {
_loggedInFlag.value = 0
}
},
})
3 changes: 3 additions & 0 deletions src/runtime/plugins/graphql.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { defineNuxtPlugin, useDirectusSession } from '#imports'

export default defineNuxtPlugin({
name: 'directus:graphql',
dependsOn: ['directus:rest'],

hooks: {
'apollo:http-auth': async (args) => {
const accessToken = await useDirectusSession().getToken()
Expand Down
34 changes: 19 additions & 15 deletions src/runtime/plugins/rest.basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,27 @@ import { createDirectus, rest } from '@directus/sdk'
import type { PublicConfig } from '../types'
import { defineNuxtPlugin, useRuntimeConfig } from '#imports'

export default defineNuxtPlugin(() => {
const config = useRuntimeConfig().public.directus as PublicConfig
export default defineNuxtPlugin({
name: 'directus:rest',

const directus = createDirectus<DirectusSchema>(config.rest.baseUrl, {
globals: {
fetch: $fetch,
},
})
setup: () => {
const config = useRuntimeConfig().public.directus as PublicConfig

const client = directus.with(rest())
const directus = createDirectus<DirectusSchema>(config.rest.baseUrl, {
globals: {
fetch: $fetch,
},
})

const client = directus.with(rest())

return {
provide: {
directus: {
client,
_refreshTimeout: null,
return {
provide: {
directus: {
client,
_refreshTimeout: null,
},
},
},
}
}
},
})
88 changes: 46 additions & 42 deletions src/runtime/plugins/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,58 @@ import type { PublicConfig } from '../types'
import { useDirectusStorage } from '../composables/useDirectusStorage'
import { defineNuxtPlugin, useRequestHeaders, useRequestEvent } from '#imports'

export default defineNuxtPlugin((nuxtApp) => {
const config = nuxtApp.$config.public.directus as PublicConfig & { auth: { enabled: true } }
const event = useRequestEvent()
const reqHeaders = useRequestHeaders(['cookie'])
export default defineNuxtPlugin({
name: 'directus:rest',

const fetch = $fetch.create({
onRequest({ options }) {
if (import.meta.server) {
options.headers = {
...options.headers,
...reqHeaders,
setup: (nuxtApp) => {
const config = nuxtApp.$config.public.directus as PublicConfig & { auth: { enabled: true } }
const event = useRequestEvent()
const reqHeaders = useRequestHeaders(['cookie'])

const fetch = $fetch.create({
onRequest({ options }) {
if (import.meta.server) {
options.headers = {
...options.headers,
...reqHeaders,
}
}
}
},
onResponse({ response }) {
if (import.meta.server) {
const cookies = splitCookiesString(response.headers.get('set-cookie') ?? '')
},
onResponse({ response }) {
if (import.meta.server) {
const cookies = splitCookiesString(response.headers.get('set-cookie') ?? '')

for (const cookie of cookies) {
appendResponseHeader(event!, 'set-cookie', cookie)
for (const cookie of cookies) {
appendResponseHeader(event!, 'set-cookie', cookie)
}
}
}
},
})
},
})

const directus = createDirectus<DirectusSchema>(config.rest.baseUrl, {
globals: {
fetch,
},
})
const directus = createDirectus<DirectusSchema>(config.rest.baseUrl, {
globals: {
fetch,
},
})

const client = directus
.with(rest({
credentials: config.auth.mode === 'session' ? 'include' : 'same-origin',
}))
.with(authentication(config.auth.mode, {
autoRefresh: false,
msRefreshBeforeExpires: config.auth.msRefreshBeforeExpires,
credentials: 'include',
storage: useDirectusStorage(),
}))
const client = directus
.with(rest({
credentials: config.auth.mode === 'session' ? 'include' : 'same-origin',
}))
.with(authentication(config.auth.mode, {
autoRefresh: false,
msRefreshBeforeExpires: config.auth.msRefreshBeforeExpires,
credentials: 'include',
storage: useDirectusStorage(),
}))

return {
provide: {
directus: {
client,
_refreshTimeout: null,
return {
provide: {
directus: {
client,
_refreshTimeout: null,
},
},
},
}
}
},
})

0 comments on commit 45f1859

Please sign in to comment.