N
Nuxt7mo ago
takburger

How to use Lucia with Nuxt Hub ? (error: missing cloudflare db binding)

As the title suggest, I have the following error :
ERROR [worker reload] [worker init] Missing Cloudflare DB binding (D1) 11:54:13 PM

at createError (node_modules/.pnpm/[email protected]/node_modules/h3/dist/index.mjs:74:12)
at hubDatabase (node_modules/.pnpm/@[email protected][email protected][email protected]_@[email protected]_@[email protected]_@uno_dwp6dcetq7zet4pibimgquizse/node_modules/@nuxthub/core/dist/runtime/server/utils/database.mjs:22:9)
at useDrizzle (server/utils/drizzle.ts:11:1)
at <anonymous> (server/utils/drizzle.ts:15:1)
at ModuleJob.run (node:internal/modules/esm/module_job:235:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:461:24)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:119:5)
ERROR [worker reload] [worker init] Missing Cloudflare DB binding (D1) 11:54:13 PM

at createError (node_modules/.pnpm/[email protected]/node_modules/h3/dist/index.mjs:74:12)
at hubDatabase (node_modules/.pnpm/@[email protected][email protected][email protected]_@[email protected]_@[email protected]_@uno_dwp6dcetq7zet4pibimgquizse/node_modules/@nuxthub/core/dist/runtime/server/utils/database.mjs:22:9)
at useDrizzle (server/utils/drizzle.ts:11:1)
at <anonymous> (server/utils/drizzle.ts:15:1)
at ModuleJob.run (node:internal/modules/esm/module_job:235:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:461:24)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:119:5)
I tried to implement as per the documentation of Lucia, with some changes.
import * as schema from '../database/schema'

export const tables = schema

export function useDrizzle() {
return drizzle(hubDatabase(), { schema })
}

// the following line is failing
const adapter = new DrizzleSQLiteAdapter(
useDrizzle(),
tables.session,
tables.user
)

export const lucia = new Lucia(adapter, {
sessionCookie: {
attributes: {
secure: !process.dev,
},
},
})
import * as schema from '../database/schema'

export const tables = schema

export function useDrizzle() {
return drizzle(hubDatabase(), { schema })
}

// the following line is failing
const adapter = new DrizzleSQLiteAdapter(
useDrizzle(),
tables.session,
tables.user
)

export const lucia = new Lucia(adapter, {
sessionCookie: {
attributes: {
secure: !process.dev,
},
},
})
docs: - https://hub.nuxt.com/docs/recipes/drizzle#usedrizzle - https://lucia-auth.com/database/drizzle - https://lucia-auth.com/getting-started/nuxt Definition of hubDatabase() with similar error on line 38 : https://github.com/nuxt-hub/core/blob/main/src/runtime/server/utils/database.ts reproduction link : https://stackblitz.com/~/github.com/rktmatt/help-drizzle-nuxt-hub
38 Replies
takburger
takburgerOP7mo ago
I was in the wrong doc. Apparently with D1 you have to do things a little bit differently for the adapter :
export function initializeLucia(D1: D1Database) {
const adapter = new D1Adapter(D1, {
user: 'user',
session: 'session',
})
return new Lucia(adapter)
}
export function initializeLucia(D1: D1Database) {
const adapter = new D1Adapter(D1, {
user: 'user',
session: 'session',
})
return new Lucia(adapter)
}
However, now instead of having an exported lucia util, I have a function to initialize and it doesn't work when initializing it with export const lucia = initializeLucia(hubDatabase())
Hum+
Hum+7mo ago
Hey burger! Im having the exact same issue Stuck on it for 1-2 days now
ERROR [worker reload] [worker init] Missing Cloudflare DB binding (D1)
ERROR [worker reload] [worker init] Missing Cloudflare DB binding (D1)
I'm not even getting my bindings to properly work each and every time i open up the project (which might be a skill issue on my end) It's kinda weird it's complaining about the D1 adapter, while in local dev we're running off the local sqlite3 db... which uses the better-sqlite3 adapter i dont see where nuxt hub is overriding this and decicing to go straight for the production db on cloudflare I feel like this situation is problematic, nuxt hub and db0 kinda are colliding here db0 is primarily focussed on local dbs atm, while nuxt hub is primarily focussed on remote D1 db's it feels like for now, the best option is to divert back to Turso + drizzle-orm from drizzle deploy on CF but db over on Turso + a local one using drizzle orm directly and not the integrated drizzle orm in db0 unless u wanna deploy a nightly nuxt build (it requires that experimental flag) i mean db0 is still a experimental native sql connector for nuxt in the nightly build atm and nuxt hub is in alpha...
takburger
takburgerOP7mo ago
I think I have a fix, I'm working on my example repo for a usable example to share. I'm currently implementing the auth functions and later the sessions to see if everything works. For now I think I understood that the initializeLucia(hubDatabase()) had to be called in each single line of code so that for each line of code a dedicated D1 binding.
Hum+
Hum+7mo ago
I'll happily tag along your work!
takburger
takburgerOP7mo ago
Like in the converted middleware :
import { verifyRequestOrigin } from 'lucia'
import type { Session, User } from 'lucia'

export default defineEventHandler(async (event) => {
if (event.method !== 'GET') {
const originHeader = getHeader(event, 'Origin') ?? null
const hostHeader = getHeader(event, 'Host') ?? null
if (
!originHeader ||
!hostHeader ||
!verifyRequestOrigin(originHeader, [hostHeader])
) {
return event.node.res.writeHead(403).end()
}
}

const sessionId =
getCookie(
event,
initializeLucia(hubDatabase()).sessionCookieName
) ?? null
if (!sessionId) {
event.context.session = null
event.context.user = null
return
}

const { session, user } = await initializeLucia(
hubDatabase()
).validateSession(sessionId)
if (session && session.fresh) {
appendResponseHeader(
event,
'Set-Cookie',
initializeLucia(hubDatabase())
.createSessionCookie(session.id)
.serialize()
)
}
if (!session) {
appendResponseHeader(
event,
'Set-Cookie',
initializeLucia(hubDatabase())
.createBlankSessionCookie()
.serialize()
)
}
event.context.session = session
event.context.user = user
})

declare module 'h3' {
interface H3EventContext {
user: User | null
session: Session | null
}
}
import { verifyRequestOrigin } from 'lucia'
import type { Session, User } from 'lucia'

export default defineEventHandler(async (event) => {
if (event.method !== 'GET') {
const originHeader = getHeader(event, 'Origin') ?? null
const hostHeader = getHeader(event, 'Host') ?? null
if (
!originHeader ||
!hostHeader ||
!verifyRequestOrigin(originHeader, [hostHeader])
) {
return event.node.res.writeHead(403).end()
}
}

const sessionId =
getCookie(
event,
initializeLucia(hubDatabase()).sessionCookieName
) ?? null
if (!sessionId) {
event.context.session = null
event.context.user = null
return
}

const { session, user } = await initializeLucia(
hubDatabase()
).validateSession(sessionId)
if (session && session.fresh) {
appendResponseHeader(
event,
'Set-Cookie',
initializeLucia(hubDatabase())
.createSessionCookie(session.id)
.serialize()
)
}
if (!session) {
appendResponseHeader(
event,
'Set-Cookie',
initializeLucia(hubDatabase())
.createBlankSessionCookie()
.serialize()
)
}
event.context.session = session
event.context.user = user
})

declare module 'h3' {
interface H3EventContext {
user: User | null
session: Session | null
}
}
Hum+
Hum+7mo ago
dang 38 lines just doubled but yeah, this looks good! Im not able to launch my nuxt app atm due to the consistent missing D1 bindings error
takburger
takburgerOP7mo ago
just replace every lucia. by ìnitializeLucia(hubDatabase())`
Hum+
Hum+7mo ago
updating the d1 bindings in root of the project or in the d1 folder/wrangler file keeps resetting it too all default values
takburger
takburgerOP7mo ago
what kind of auth strategy are you implementing ? I'm going for passkeys
Hum+
Hum+7mo ago
I'm using a pretty default lucia v3 setup with the password/github provider route i just made the jump from lucia v2 to v3, so its still new too for me
takburger
takburgerOP7mo ago
Ok. I'm using it for the first time. I'm also just a hobby dev, so don't trust my code
Hum+
Hum+7mo ago
no worries! im happy i found someone dealing with the same issue xD I spent my entire weekend on it alrdy
takburger
takburgerOP7mo ago
exactly, sometimes I feel that I could have gone on a stack that's less niche lol
Hum+
Hum+7mo ago
ngl.. we're really working on the edge of technology here, no docs, no posts, no pr's nothing xD pioneering this stuff as we try to make it work
takburger
takburgerOP7mo ago
the lucia and oslo passkeys have no docs too
Hum+
Hum+7mo ago
i mean, this is all still fun, im just wondering how upset i will feel when i get to the part where the built in node-crypto doesnt work on cf/vercel. this affects everything including oslo and arctic too without their edge version of it for hashing the passwords or generating unique-ids like vercel offers this @vercel/crypto module, u need to apply globally so auth works on their platform.. cf has the same issue, same route solution
takburger
takburgerOP7mo ago
didn't know. I guess we have to fork lucia and oslo then
Hum+
Hum+7mo ago
wrong link
takburger
takburgerOP7mo ago
Cloudflare Docs
Web Crypto · Cloudflare Workers docs
A set of low-level functions for common cryptographic tasks.
Hum+
Hum+7mo ago
https://discord.com/channels/1004048134218981416/1210630859019919430 heres the discussion on the lucia discord I might just deploy this to CF, turso in production for now and local sqlite for goofing around during dev
import { join } from 'pathe';
import type { Config } from "drizzle-kit";

export default {
out: 'server/database/migrations',
schema: 'server/database/schema.ts',
driver: process.env.devDatabase ? "better-sqlite" : "turso",
dbCredentials: {
url: process.env.devDatabase ? join(process.cwd(), './.data/db.sqlite3') : process.env.TURSO_DB_URL as string,
authToken: process.env.devDatabase ? "" : process.env.TURSO_DB_AUTH_TOKEN as string,
},
} satisfies Config;
import { join } from 'pathe';
import type { Config } from "drizzle-kit";

export default {
out: 'server/database/migrations',
schema: 'server/database/schema.ts',
driver: process.env.devDatabase ? "better-sqlite" : "turso",
dbCredentials: {
url: process.env.devDatabase ? join(process.cwd(), './.data/db.sqlite3') : process.env.TURSO_DB_URL as string,
authToken: process.env.devDatabase ? "" : process.env.TURSO_DB_AUTH_TOKEN as string,
},
} satisfies Config;
until you have a magic fix in your cloud reproduction repo 😛
takburger
takburgerOP7mo ago
On Youtube Mannil said he'll do a video about that.
Hum+
Hum+7mo ago
ill be on the look out for that
Hum+
Hum+7mo ago
GitHub
GitHub - justserdar/jsd-nuxt-turso-drizzle at nightly+lucia
Contribute to justserdar/jsd-nuxt-turso-drizzle development by creating an account on GitHub.
Hum+
Hum+7mo ago
this is my nightly build using experimental features with db0 directly with turso w lucia v3 for production and local dev db in the .data folder this shud only leave the issues with the differing node:crypto environments on cf
takburger
takburgerOP7mo ago
thanks, I'll look at it when production fails and I contemplate my new challenge xD
Hum+
Hum+7mo ago
i got two articles to help you through if you feel lost https://justserdar.dev/foundry/article/nuxt-experimental-features-connect-your-turso-db-natively-with-db0-and-drizzle experimental route ^ (w lucia v3) https://justserdar.dev/foundry/article/connect-a-turso-db-to-your-nuxt-3-project-with-drizzle normal route ^ (doesnt include lucia) @manniL / TheAlexLichter sorry to ping you, would love your attention and opinion on this matter, heard you are planning a new video surrounding the subject we're discussing. please feel free to come back at any time, dont wanna inconvencience you
manniL
manniL7mo ago
might take a while though 😄 Could cover that while building the association manager
Hum+
Hum+7mo ago
Id be watching it for sure! pretty sure w many others too i can understand haha xD
takburger
takburgerOP7mo ago
Hey @h+ Sorry for the delay, was a bit busy recently. I have a working local example : https://github.com/rktmatt/nuxthub-cloudflare-lucia On my way to check it deployed on cloudflare and see if the crypto part fails can't deploy it successfully. https://2c2f88ba.help-drizzle-nuxt-hub.pages.dev/
Martial
Martial7mo ago
I have a lucia + D1 + drizzle setup (without nuxthub) that is working and deployed on CF
Martial
Martial7mo ago
GitHub
GitHub - tlebeitsuk/nuxt-cloudflare-lucia: A demo using Nuxt, Cloud...
A demo using Nuxt, Cloudflare Pages, Cloudflare D1 database and Lucia for auth - tlebeitsuk/nuxt-cloudflare-lucia
takburger
takburgerOP7mo ago
it looks like the crypto functions are working out of the box. Thanks for your page, it helped me making the deployment work ! My test of nuxthub cloudflare lucia and passkeys auth is working in prod !
Martial
Martial7mo ago
I know the pain, glad it helped
Hum+
Hum+7mo ago
thank you a lot broski!! extremely helpful hey man, thanks! i recently checked ur cloud environment/repo to get some middleware going been very insightful i read the crypto works out of the box, thats such a relief happy coding!
takburger
takburgerOP4mo ago
@h+ Hey just coming back here to let you know I had to add password auth to another hub project and the build did fail as you said because the argon package is not allowed on Workers. I found a good repo with a rust based argon worker api. That works perfectly on CF to hash and verify passwords. I only had to add a Bearer token auth to it to make it work.
takburger
takburgerOP4mo ago
GitHub
GitHub - glotlabs/argon2-cloudflare
Contribute to glotlabs/argon2-cloudflare development by creating an account on GitHub.
Hum+
Hum+4mo ago
absolute legend that you are, ty for coming back on that!!
Want results from more Discord servers?
Add your server