auth

Auth for Lunora — a thin better-auth wrapper: email/password, OAuth, plugins, D1-backed


[![typescript-image][typescript-badge]][typescript-url] [![FSL-1.1-Apache-2.0 licence][license-badge]][license] [![npm version][npm-version-badge]][npm-version] [![npm downloads][npm-downloads-badge]][npm-downloads] [![PRs Welcome][prs-welcome-badge]][prs-welcome]
---

Daniel Bannert's open source work is supported by the community on GitHub Sponsors

--- Authentication for Lunora, built as a thin wrapper around [better-auth](https://better-auth.com). `createAuth` is `betterAuth` with a few Cloudflare-friendly defaults; the package backs the user/session store on D1, re-exports the better-auth plugins under `@lunora/auth/plugins`, and adds a `ctx.authApi` middleware plus standalone Turnstile helpers. It runs on your own Cloudflare account — there is no external auth service. Part of the [Lunora](https://github.com/anolilab/lunora) framework — a type-safe, real-time backend on Cloudflare Workers + Durable Objects with a Vite-first DX. ## Install ```sh npm install @lunora/auth ``` ```sh yarn add @lunora/auth ``` ```sh pnpm add @lunora/auth ``` ## Usage ```ts import { createAuth, ensureMigrated, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth"; const auth = createAuth({ secret: env.AUTH_SECRET, // Prefer lunoraD1Adapter over passing raw env.DB — the raw binding makes // better-auth resolve its Kysely adapter via a dynamic import that hangs // under @cloudflare/vite-plugin's dev runner. database: lunoraD1Adapter(env.DB), emailAndPassword: { enabled: true }, }); // In your Worker's fetch handler, route /api/auth/* to better-auth and fall // through to the Lunora worker for everything else: export default { async fetch(request, env, ctx) { await ensureMigrated(auth); // idempotent schema sync; dev/small deploys const authResponse = await handleAuthRequest(auth, request); if (authResponse) return authResponse; // … hand off to your Lunora worker }, }; ``` The runtime resolves the inbound session and stamps `ctx.auth` on every `query` / `mutation` / `action`: `ctx.auth.userId` is the signed-in user's id (or `null` when anonymous), and `ctx.auth.getIdentity()` resolves the decoded claims. ### Plugins & CAPTCHA better-auth's plugin factories are re-exported from `@lunora/auth/plugins` (so you don't need better-auth's deep import paths): `admin`, `anonymous`, `bearer`, `captcha`, `createAccessControl`, `customSession`, `deviceAuthorization`, `emailOTP`, `genericOAuth`, `haveIBeenPwned`, `jwt`, `magicLink`, `mcp`, `multiSession`, `oAuthProxy`, `oidcProvider`, `oneTimeToken`, `organization`, `passkey`, `phoneNumber`, `siwe`, `twoFactor`, `username`, and `withMcpAuth`. For Cloudflare Turnstile on the **auth flow**, use the `captcha` plugin (`captcha({ provider: "cloudflare-turnstile", secretKey: env.TURNSTILE_SECRET_KEY })`); it reads the token from the `x-captcha-response` header. For **non-auth** procedures, the package root also exports standalone helpers — `verifyTurnstile` (pure `siteverify`) and `verifyTurnstileMiddleware` (a `.use()` middleware that takes the token from the function args). > This README covers the basics. For the full API, options, and guides, see the **[documentation](https://lunora.sh/docs/packages/auth)**. ## Related - [`@lunora/server`](https://www.npmjs.com/package/@lunora/server) — define the queries and mutations that read `ctx.auth`. - [`@lunora/studio`](https://www.npmjs.com/package/@lunora/studio) — admin user dashboard, wired with `createAuthAdmin(auth)`. - [`@lunora/mail`](https://www.npmjs.com/package/@lunora/mail) — send better-auth's verification / reset / magic-link emails. ## Supported Node.js Versions Libraries in this ecosystem make the best effort to track [Node.js' release schedule](https://github.com/nodejs/release#release-schedule). Here's [a post on why we think this is important](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a). ## Contributing If you would like to help take a look at the [list of issues](https://github.com/anolilab/lunora/issues) and check our [Contributing](https://github.com/anolilab/lunora/blob/alpha/.github/CONTRIBUTING.md) guidelines. > **Note:** please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. ## Credits - [Daniel Bannert](https://github.com/prisis) - [All Contributors](https://github.com/anolilab/lunora/graphs/contributors) ## Made with ❤️ at Anolilab This is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Anolilab](https://www.anolilab.com/open-source) is a Development and AI Studio. Contact us at [hello@anolilab.com](mailto:hello@anolilab.com) if you need any help with these technologies or just want to say hi! ## License The Lunora auth package is open-sourced software licensed under the [FSL-1.1-Apache-2.0][license]. [license-badge]: https://img.shields.io/badge/license-FSL--1.1--Apache--2.0-blue.svg?style=for-the-badge [license]: https://github.com/anolilab/lunora/blob/alpha/LICENSE.md [npm-version-badge]: https://img.shields.io/npm/v/@lunora/auth?style=for-the-badge [npm-version]: https://www.npmjs.com/package/@lunora/auth [npm-downloads-badge]: https://img.shields.io/npm/dm/@lunora/auth?style=for-the-badge [npm-downloads]: https://www.npmjs.com/package/@lunora/auth [prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge [prs-welcome]: https://github.com/anolilab/lunora/blob/alpha/.github/CONTRIBUTING.md [typescript-badge]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript [typescript-url]: https://www.typescriptlang.org/