@we8/cms 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -0
- package/dist/auth/auth.d.ts +87 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +90 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/routes.admin.d.ts +22 -0
- package/dist/auth/routes.admin.d.ts.map +1 -0
- package/dist/auth/routes.admin.js +106 -0
- package/dist/auth/routes.admin.js.map +1 -0
- package/dist/auth/schema.d.ts +1395 -0
- package/dist/auth/schema.d.ts.map +1 -0
- package/dist/auth/schema.js +76 -0
- package/dist/auth/schema.js.map +1 -0
- package/dist/env.d.ts +64 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +48 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +170 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/middleware.d.ts +54 -0
- package/dist/keys/middleware.d.ts.map +1 -0
- package/dist/keys/middleware.js +84 -0
- package/dist/keys/middleware.js.map +1 -0
- package/dist/keys/routes.admin.d.ts +16 -0
- package/dist/keys/routes.admin.d.ts.map +1 -0
- package/dist/keys/routes.admin.js +34 -0
- package/dist/keys/routes.admin.js.map +1 -0
- package/dist/keys/service.d.ts +36 -0
- package/dist/keys/service.d.ts.map +1 -0
- package/dist/keys/service.js +120 -0
- package/dist/keys/service.js.map +1 -0
- package/dist/lib/bots.d.ts +24 -0
- package/dist/lib/bots.d.ts.map +1 -0
- package/dist/lib/bots.js +79 -0
- package/dist/lib/bots.js.map +1 -0
- package/dist/lib/email.d.ts +62 -0
- package/dist/lib/email.d.ts.map +1 -0
- package/dist/lib/email.js +64 -0
- package/dist/lib/email.js.map +1 -0
- package/dist/lib/errors.d.ts +12 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +23 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/notify.d.ts +20 -0
- package/dist/lib/notify.d.ts.map +1 -0
- package/dist/lib/notify.js +60 -0
- package/dist/lib/notify.js.map +1 -0
- package/dist/lib/retention.d.ts +15 -0
- package/dist/lib/retention.d.ts.map +1 -0
- package/dist/lib/retention.js +40 -0
- package/dist/lib/retention.js.map +1 -0
- package/dist/lib/sanitize.d.ts +14 -0
- package/dist/lib/sanitize.d.ts.map +1 -0
- package/dist/lib/sanitize.js +145 -0
- package/dist/lib/sanitize.js.map +1 -0
- package/dist/lib/turnstile.d.ts +7 -0
- package/dist/lib/turnstile.d.ts.map +1 -0
- package/dist/lib/turnstile.js +32 -0
- package/dist/lib/turnstile.js.map +1 -0
- package/dist/lib/validate.d.ts +11 -0
- package/dist/lib/validate.d.ts.map +1 -0
- package/dist/lib/validate.js +22 -0
- package/dist/lib/validate.js.map +1 -0
- package/dist/lib/word-count.d.ts +7 -0
- package/dist/lib/word-count.d.ts.map +1 -0
- package/dist/lib/word-count.js +14 -0
- package/dist/lib/word-count.js.map +1 -0
- package/dist/middleware/auth.d.ts +46 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +60 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors.d.ts +33 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +55 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/module-gate.d.ts +11 -0
- package/dist/middleware/module-gate.d.ts.map +1 -0
- package/dist/middleware/module-gate.js +18 -0
- package/dist/middleware/module-gate.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +13 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +30 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/request-id.d.ts +8 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +11 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/modules/aeo/checks.d.ts +41 -0
- package/dist/modules/aeo/checks.d.ts.map +1 -0
- package/dist/modules/aeo/checks.js +127 -0
- package/dist/modules/aeo/checks.js.map +1 -0
- package/dist/modules/aeo/llms.d.ts +24 -0
- package/dist/modules/aeo/llms.d.ts.map +1 -0
- package/dist/modules/aeo/llms.js +92 -0
- package/dist/modules/aeo/llms.js.map +1 -0
- package/dist/modules/aeo/routes.admin.d.ts +12 -0
- package/dist/modules/aeo/routes.admin.d.ts.map +1 -0
- package/dist/modules/aeo/routes.admin.js +37 -0
- package/dist/modules/aeo/routes.admin.js.map +1 -0
- package/dist/modules/analytics/db.d.ts +24 -0
- package/dist/modules/analytics/db.d.ts.map +1 -0
- package/dist/modules/analytics/db.js +24 -0
- package/dist/modules/analytics/db.js.map +1 -0
- package/dist/modules/analytics/routes.admin.d.ts +6 -0
- package/dist/modules/analytics/routes.admin.d.ts.map +1 -0
- package/dist/modules/analytics/routes.admin.js +21 -0
- package/dist/modules/analytics/routes.admin.js.map +1 -0
- package/dist/modules/analytics/routes.public.d.ts +6 -0
- package/dist/modules/analytics/routes.public.d.ts.map +1 -0
- package/dist/modules/analytics/routes.public.js +33 -0
- package/dist/modules/analytics/routes.public.js.map +1 -0
- package/dist/modules/analytics/service.d.ts +16 -0
- package/dist/modules/analytics/service.d.ts.map +1 -0
- package/dist/modules/analytics/service.js +148 -0
- package/dist/modules/analytics/service.js.map +1 -0
- package/dist/modules/authors/routes.admin.d.ts +6 -0
- package/dist/modules/authors/routes.admin.d.ts.map +1 -0
- package/dist/modules/authors/routes.admin.js +29 -0
- package/dist/modules/authors/routes.admin.js.map +1 -0
- package/dist/modules/authors/routes.public.d.ts +6 -0
- package/dist/modules/authors/routes.public.d.ts.map +1 -0
- package/dist/modules/authors/routes.public.js +11 -0
- package/dist/modules/authors/routes.public.js.map +1 -0
- package/dist/modules/authors/service.d.ts +26 -0
- package/dist/modules/authors/service.d.ts.map +1 -0
- package/dist/modules/authors/service.js +116 -0
- package/dist/modules/authors/service.js.map +1 -0
- package/dist/modules/content/db.d.ts +127 -0
- package/dist/modules/content/db.d.ts.map +1 -0
- package/dist/modules/content/db.js +203 -0
- package/dist/modules/content/db.js.map +1 -0
- package/dist/modules/content/publish.d.ts +38 -0
- package/dist/modules/content/publish.d.ts.map +1 -0
- package/dist/modules/content/publish.js +184 -0
- package/dist/modules/content/publish.js.map +1 -0
- package/dist/modules/content/routes.admin.d.ts +8 -0
- package/dist/modules/content/routes.admin.d.ts.map +1 -0
- package/dist/modules/content/routes.admin.js +122 -0
- package/dist/modules/content/routes.admin.js.map +1 -0
- package/dist/modules/content/routes.public.d.ts +6 -0
- package/dist/modules/content/routes.public.d.ts.map +1 -0
- package/dist/modules/content/routes.public.js +56 -0
- package/dist/modules/content/routes.public.js.map +1 -0
- package/dist/modules/content/service.d.ts +137 -0
- package/dist/modules/content/service.d.ts.map +1 -0
- package/dist/modules/content/service.js +348 -0
- package/dist/modules/content/service.js.map +1 -0
- package/dist/modules/forms/db.d.ts +42 -0
- package/dist/modules/forms/db.d.ts.map +1 -0
- package/dist/modules/forms/db.js +62 -0
- package/dist/modules/forms/db.js.map +1 -0
- package/dist/modules/forms/forms-routes.admin.d.ts +6 -0
- package/dist/modules/forms/forms-routes.admin.d.ts.map +1 -0
- package/dist/modules/forms/forms-routes.admin.js +37 -0
- package/dist/modules/forms/forms-routes.admin.js.map +1 -0
- package/dist/modules/forms/forms-service.d.ts +18 -0
- package/dist/modules/forms/forms-service.d.ts.map +1 -0
- package/dist/modules/forms/forms-service.js +121 -0
- package/dist/modules/forms/forms-service.js.map +1 -0
- package/dist/modules/forms/routes.public.d.ts +6 -0
- package/dist/modules/forms/routes.public.d.ts.map +1 -0
- package/dist/modules/forms/routes.public.js +41 -0
- package/dist/modules/forms/routes.public.js.map +1 -0
- package/dist/modules/forms/submissions-routes.admin.d.ts +6 -0
- package/dist/modules/forms/submissions-routes.admin.d.ts.map +1 -0
- package/dist/modules/forms/submissions-routes.admin.js +46 -0
- package/dist/modules/forms/submissions-routes.admin.js.map +1 -0
- package/dist/modules/forms/submissions-service.d.ts +45 -0
- package/dist/modules/forms/submissions-service.d.ts.map +1 -0
- package/dist/modules/forms/submissions-service.js +174 -0
- package/dist/modules/forms/submissions-service.js.map +1 -0
- package/dist/modules/media/db.d.ts +15 -0
- package/dist/modules/media/db.d.ts.map +1 -0
- package/dist/modules/media/db.js +24 -0
- package/dist/modules/media/db.js.map +1 -0
- package/dist/modules/media/routes.admin.d.ts +6 -0
- package/dist/modules/media/routes.admin.d.ts.map +1 -0
- package/dist/modules/media/routes.admin.js +30 -0
- package/dist/modules/media/routes.admin.js.map +1 -0
- package/dist/modules/media/routes.public.d.ts +6 -0
- package/dist/modules/media/routes.public.d.ts.map +1 -0
- package/dist/modules/media/routes.public.js +35 -0
- package/dist/modules/media/routes.public.js.map +1 -0
- package/dist/modules/media/service.d.ts +32 -0
- package/dist/modules/media/service.d.ts.map +1 -0
- package/dist/modules/media/service.js +99 -0
- package/dist/modules/media/service.js.map +1 -0
- package/dist/modules/openapi/spec.d.ts +21 -0
- package/dist/modules/openapi/spec.d.ts.map +1 -0
- package/dist/modules/openapi/spec.js +468 -0
- package/dist/modules/openapi/spec.js.map +1 -0
- package/dist/modules/seo/jsonld.d.ts +25 -0
- package/dist/modules/seo/jsonld.d.ts.map +1 -0
- package/dist/modules/seo/jsonld.js +67 -0
- package/dist/modules/seo/jsonld.js.map +1 -0
- package/dist/modules/seo/routes.public.d.ts +6 -0
- package/dist/modules/seo/routes.public.d.ts.map +1 -0
- package/dist/modules/seo/routes.public.js +39 -0
- package/dist/modules/seo/routes.public.js.map +1 -0
- package/dist/modules/seo/sitemap.d.ts +3 -0
- package/dist/modules/seo/sitemap.d.ts.map +1 -0
- package/dist/modules/seo/sitemap.js +39 -0
- package/dist/modules/seo/sitemap.js.map +1 -0
- package/dist/modules/settings/routes.admin.d.ts +12 -0
- package/dist/modules/settings/routes.admin.d.ts.map +1 -0
- package/dist/modules/settings/routes.admin.js +27 -0
- package/dist/modules/settings/routes.admin.js.map +1 -0
- package/dist/modules/site-documents/routes.admin.d.ts +10 -0
- package/dist/modules/site-documents/routes.admin.d.ts.map +1 -0
- package/dist/modules/site-documents/routes.admin.js +29 -0
- package/dist/modules/site-documents/routes.admin.js.map +1 -0
- package/dist/modules/site-documents/routes.public.d.ts +6 -0
- package/dist/modules/site-documents/routes.public.d.ts.map +1 -0
- package/dist/modules/site-documents/routes.public.js +16 -0
- package/dist/modules/site-documents/routes.public.js.map +1 -0
- package/dist/modules/site-documents/service.d.ts +11 -0
- package/dist/modules/site-documents/service.d.ts.map +1 -0
- package/dist/modules/site-documents/service.js +42 -0
- package/dist/modules/site-documents/service.js.map +1 -0
- package/dist/modules/webhooks/dispatch.d.ts +14 -0
- package/dist/modules/webhooks/dispatch.d.ts.map +1 -0
- package/dist/modules/webhooks/dispatch.js +84 -0
- package/dist/modules/webhooks/dispatch.js.map +1 -0
- package/dist/shared/constants.d.ts +79 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +89 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/envelope.d.ts +37 -0
- package/dist/shared/envelope.d.ts.map +1 -0
- package/dist/shared/envelope.js +46 -0
- package/dist/shared/envelope.js.map +1 -0
- package/dist/shared/hash.d.ts +2 -0
- package/dist/shared/hash.d.ts.map +1 -0
- package/dist/shared/hash.js +8 -0
- package/dist/shared/hash.js.map +1 -0
- package/dist/shared/index.d.ts +13 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +13 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/schemas/aeo.d.ts +182 -0
- package/dist/shared/schemas/aeo.d.ts.map +1 -0
- package/dist/shared/schemas/aeo.js +43 -0
- package/dist/shared/schemas/aeo.js.map +1 -0
- package/dist/shared/schemas/analytics.d.ts +277 -0
- package/dist/shared/schemas/analytics.d.ts.map +1 -0
- package/dist/shared/schemas/analytics.js +74 -0
- package/dist/shared/schemas/analytics.js.map +1 -0
- package/dist/shared/schemas/api-key.d.ts +77 -0
- package/dist/shared/schemas/api-key.d.ts.map +1 -0
- package/dist/shared/schemas/api-key.js +27 -0
- package/dist/shared/schemas/api-key.js.map +1 -0
- package/dist/shared/schemas/author.d.ts +147 -0
- package/dist/shared/schemas/author.d.ts.map +1 -0
- package/dist/shared/schemas/author.js +27 -0
- package/dist/shared/schemas/author.js.map +1 -0
- package/dist/shared/schemas/form.d.ts +341 -0
- package/dist/shared/schemas/form.d.ts.map +1 -0
- package/dist/shared/schemas/form.js +117 -0
- package/dist/shared/schemas/form.js.map +1 -0
- package/dist/shared/schemas/index.d.ts +12 -0
- package/dist/shared/schemas/index.d.ts.map +1 -0
- package/dist/shared/schemas/index.js +12 -0
- package/dist/shared/schemas/index.js.map +1 -0
- package/dist/shared/schemas/media.d.ts +42 -0
- package/dist/shared/schemas/media.d.ts.map +1 -0
- package/dist/shared/schemas/media.js +16 -0
- package/dist/shared/schemas/media.js.map +1 -0
- package/dist/shared/schemas/pagination.d.ts +34 -0
- package/dist/shared/schemas/pagination.d.ts.map +1 -0
- package/dist/shared/schemas/pagination.js +21 -0
- package/dist/shared/schemas/pagination.js.map +1 -0
- package/dist/shared/schemas/post.d.ts +862 -0
- package/dist/shared/schemas/post.d.ts.map +1 -0
- package/dist/shared/schemas/post.js +187 -0
- package/dist/shared/schemas/post.js.map +1 -0
- package/dist/shared/schemas/settings.d.ts +839 -0
- package/dist/shared/schemas/settings.d.ts.map +1 -0
- package/dist/shared/schemas/settings.js +202 -0
- package/dist/shared/schemas/settings.js.map +1 -0
- package/dist/shared/schemas/site-document.d.ts +38 -0
- package/dist/shared/schemas/site-document.d.ts.map +1 -0
- package/dist/shared/schemas/site-document.js +21 -0
- package/dist/shared/schemas/site-document.js.map +1 -0
- package/dist/shared/schemas/webhook.d.ts +39 -0
- package/dist/shared/schemas/webhook.d.ts.map +1 -0
- package/dist/shared/schemas/webhook.js +20 -0
- package/dist/shared/schemas/webhook.js.map +1 -0
- package/dist/spa.d.ts +9 -0
- package/dist/spa.d.ts.map +1 -0
- package/dist/spa.js +57 -0
- package/dist/spa.js.map +1 -0
- package/migrations/0001_settings.sql +39 -0
- package/migrations/0002_content.sql +135 -0
- package/migrations/0003_forms.sql +35 -0
- package/migrations/0004_analytics.sql +42 -0
- package/migrations/0005_media.sql +17 -0
- package/migrations/0006_site_documents.sql +18 -0
- package/migrations/0007_auth.sql +81 -0
- package/migrations/0008_api_keys.sql +20 -0
- package/package.json +68 -0
- package/scripts/bundle-admin.mjs +54 -0
- package/seed/local.sql +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# @we8/cms
|
|
2
|
+
|
|
3
|
+
`@we8/cms` is the core headless CMS of the we8 package: a Hono application
|
|
4
|
+
carrying the content, forms, analytics, media, and SEO modules, with embedded
|
|
5
|
+
Better Auth for sign-in and the `/v1` public API that every frontend consumes.
|
|
6
|
+
It is single-site by construction (one site, one worker, one database, one
|
|
7
|
+
bucket), it validates public pk and sk API keys itself, and it owns the AEO
|
|
8
|
+
backend that is a headline feature of 0.1: llms.txt publishing,
|
|
9
|
+
answer-oriented content fields, AEO check endpoints, and crawler attribution.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- Runs on Cloudflare Workers. Deploy it with `@we8/cloudflare` and `wrangler`
|
|
14
|
+
(what `npm create we8` sets up), or with your own Worker config.
|
|
15
|
+
- Bindings: a D1 database as `DB`, an R2 bucket as `MEDIA`, and optionally
|
|
16
|
+
static assets as `ASSETS` for the admin portal.
|
|
17
|
+
- Secrets: `BETTER_AUTH_SECRET` is required; the admin API refuses every
|
|
18
|
+
request without it. `TURNSTILE_SECRET` is optional.
|
|
19
|
+
- Runtime dependencies, bundled at deploy: `hono`, `better-auth`,
|
|
20
|
+
`drizzle-orm`, `zod`. Node 20 or newer for the tooling around it.
|
|
21
|
+
## Local development
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
cp .dev.vars.example .dev.vars # then set a real BETTER_AUTH_SECRET
|
|
25
|
+
npm run db:migrate # apply the migrations to the local D1
|
|
26
|
+
npm run db:seed # a working site: settings, a post, a form, dev keys
|
|
27
|
+
npm run dev # http://localhost:8787
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The seed publishes two development API keys in plain text, which is what makes
|
|
31
|
+
local curl calls possible. Never run it against a real deployment.
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
curl http://localhost:8787/v1/health
|
|
35
|
+
curl http://localhost:8787/llms.txt
|
|
36
|
+
curl -H "X-We8-Key: pk_live_000000000000000000000000000000000000000000000000" \
|
|
37
|
+
http://localhost:8787/v1/posts
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Create the owner account by signing up once; the endpoint closes as soon as an
|
|
41
|
+
account exists.
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
curl -X POST http://localhost:8787/api/auth/sign-up/email \
|
|
45
|
+
-H 'Content-Type: application/json' \
|
|
46
|
+
-d '{"email":"you@example.com","password":"a-long-enough-password","name":"You"}'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Serving the admin portal
|
|
50
|
+
|
|
51
|
+
This worker can serve the admin portal from its own origin, so the SPA, the
|
|
52
|
+
API, and the session cookie all share one host and nothing is cross-origin.
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npm run build --workspace @we8/admin-app # build the portal
|
|
56
|
+
npm run admin:bundle # copy it into ./public
|
|
57
|
+
npm run dev # the portal is now at /
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`./public` is the worker's static-asset root and ships empty. A deployment that
|
|
61
|
+
skips those two steps serves no assets and runs API-only, which is the headless
|
|
62
|
+
install; the SPA fallback in `src/spa.ts` stands down on its own when there is
|
|
63
|
+
no bundle behind the binding.
|
|
64
|
+
|
|
65
|
+
## Bindings
|
|
66
|
+
|
|
67
|
+
`DB` (D1) and `MEDIA` (R2), plus the vars `SITE_URL` and `CMS_VERSION` and the
|
|
68
|
+
secret `BETTER_AUTH_SECRET`. `AUTH_URL`, `TURNSTILE_SECRET`, `EMAIL_MODE`, and
|
|
69
|
+
`EMAIL_FROM` are optional, and `ASSETS` is the optional static-asset binding
|
|
70
|
+
that carries the admin portal. See [the CMS doc](https://github.com/reveriext/we8-package/blob/main/docs/cms.md) for what
|
|
71
|
+
each one does and for the architecture behind them.
|
|
72
|
+
|
|
73
|
+
## More
|
|
74
|
+
|
|
75
|
+
- [docs/quick-start.md](https://github.com/reveriext/we8-package/blob/main/docs/quick-start.md): three paths from nothing to
|
|
76
|
+
a working site.
|
|
77
|
+
- [docs/api.md](https://github.com/reveriext/we8-package/blob/main/docs/api.md): the `/v1` contract from a frontend's side.
|
|
78
|
+
- `GET /v1/openapi.json` on any install: the same contract, live and keyless.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Bindings } from '../env.js';
|
|
2
|
+
import type { UserRole } from '../shared/index.js';
|
|
3
|
+
/** Where the auth handler is mounted. The browser calls exactly this prefix. */
|
|
4
|
+
export declare const AUTH_BASE_PATH = "/api/auth";
|
|
5
|
+
/**
|
|
6
|
+
* Counts users to decide whether an account creation is the bootstrap one. A
|
|
7
|
+
* direct D1 read rather than a Better Auth call: this runs inside the user
|
|
8
|
+
* creation hook, where re-entering the auth API would be circular.
|
|
9
|
+
*/
|
|
10
|
+
export declare function countUsers(db: D1Database): Promise<number>;
|
|
11
|
+
/** True while no account exists, which is the only window public sign-up is open. */
|
|
12
|
+
export declare function isBootstrapOpen(db: D1Database): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Normalizes whatever the session carries into one of the two roles. Anything
|
|
15
|
+
* unrecognized, absent, or empty reads as `member`: least privilege, so a row
|
|
16
|
+
* written by hand or left over from a botched migration cannot grant ownership.
|
|
17
|
+
*/
|
|
18
|
+
export declare function normalizeRole(role: unknown): UserRole;
|
|
19
|
+
/**
|
|
20
|
+
* Builds the embedded auth instance for this request's environment.
|
|
21
|
+
*
|
|
22
|
+
* Managed we8 keeps auth in a control plane and has the tenant engine trust a
|
|
23
|
+
* signed internal header. Here there is no plane to trust: Better Auth runs
|
|
24
|
+
* inside this worker, over this worker's own D1, and a session cookie is the
|
|
25
|
+
* whole story. Same library and the same patterns as the managed platform, so
|
|
26
|
+
* what is learned on one side transfers to the other.
|
|
27
|
+
*
|
|
28
|
+
* Email and password only in 0.1. Sign-up is open exactly once, to create the
|
|
29
|
+
* first user, who becomes the owner; after that the endpoint is closed at the
|
|
30
|
+
* HTTP layer (see requireBootstrapOpen) and further users are created by the
|
|
31
|
+
* owner through the admin API. Password reset sends through the email seam, so
|
|
32
|
+
* it does nothing useful until a deployment configures a sender, which is the
|
|
33
|
+
* honest behavior for a CMS that ships with no mail transport.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createAuth(env: Bindings): import("better-auth").Auth<{
|
|
36
|
+
database: (options: import("better-auth").BetterAuthOptions) => import("better-auth").DBAdapter<import("better-auth").BetterAuthOptions>;
|
|
37
|
+
secret: string;
|
|
38
|
+
baseURL: string;
|
|
39
|
+
basePath: string;
|
|
40
|
+
trustedOrigins: string[];
|
|
41
|
+
emailAndPassword: {
|
|
42
|
+
enabled: true;
|
|
43
|
+
requireEmailVerification: false;
|
|
44
|
+
sendResetPassword: ({ user, url }: {
|
|
45
|
+
user: import("better-auth").User;
|
|
46
|
+
url: string;
|
|
47
|
+
token: string;
|
|
48
|
+
}) => Promise<void>;
|
|
49
|
+
};
|
|
50
|
+
user: {
|
|
51
|
+
additionalFields: {
|
|
52
|
+
role: {
|
|
53
|
+
type: "string";
|
|
54
|
+
required: false;
|
|
55
|
+
input: false;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
databaseHooks: {
|
|
60
|
+
user: {
|
|
61
|
+
create: {
|
|
62
|
+
before: (newUser: {
|
|
63
|
+
id: string;
|
|
64
|
+
createdAt: Date;
|
|
65
|
+
updatedAt: Date;
|
|
66
|
+
email: string;
|
|
67
|
+
emailVerified: boolean;
|
|
68
|
+
name: string;
|
|
69
|
+
image?: string | null | undefined;
|
|
70
|
+
} & Record<string, unknown>) => Promise<{
|
|
71
|
+
data: {
|
|
72
|
+
role: "owner" | "member";
|
|
73
|
+
id: string;
|
|
74
|
+
createdAt: Date;
|
|
75
|
+
updatedAt: Date;
|
|
76
|
+
email: string;
|
|
77
|
+
emailVerified: boolean;
|
|
78
|
+
name: string;
|
|
79
|
+
image?: string | null | undefined;
|
|
80
|
+
};
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}>;
|
|
86
|
+
export type Auth = ReturnType<typeof createAuth>;
|
|
87
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAI1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,gFAAgF;AAChF,eAAO,MAAM,cAAc,cAAc,CAAC;AAE1C;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhE;AAED,qFAAqF;AACrF,wBAAsB,eAAe,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAErD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CvC;AAED,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { betterAuth } from 'better-auth';
|
|
2
|
+
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
|
|
3
|
+
import { drizzle } from 'drizzle-orm/d1';
|
|
4
|
+
import { resolveEmailSender, sendBestEffort } from '../lib/email.js';
|
|
5
|
+
import { buildPasswordResetEmail } from '../lib/notify.js';
|
|
6
|
+
import { authSchema } from './schema.js';
|
|
7
|
+
/** Where the auth handler is mounted. The browser calls exactly this prefix. */
|
|
8
|
+
export const AUTH_BASE_PATH = '/api/auth';
|
|
9
|
+
/**
|
|
10
|
+
* Counts users to decide whether an account creation is the bootstrap one. A
|
|
11
|
+
* direct D1 read rather than a Better Auth call: this runs inside the user
|
|
12
|
+
* creation hook, where re-entering the auth API would be circular.
|
|
13
|
+
*/
|
|
14
|
+
export async function countUsers(db) {
|
|
15
|
+
const row = await db.prepare('SELECT COUNT(*) AS count FROM user').first();
|
|
16
|
+
return row?.count ?? 0;
|
|
17
|
+
}
|
|
18
|
+
/** True while no account exists, which is the only window public sign-up is open. */
|
|
19
|
+
export async function isBootstrapOpen(db) {
|
|
20
|
+
return (await countUsers(db)) === 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Normalizes whatever the session carries into one of the two roles. Anything
|
|
24
|
+
* unrecognized, absent, or empty reads as `member`: least privilege, so a row
|
|
25
|
+
* written by hand or left over from a botched migration cannot grant ownership.
|
|
26
|
+
*/
|
|
27
|
+
export function normalizeRole(role) {
|
|
28
|
+
return role === 'owner' ? 'owner' : 'member';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds the embedded auth instance for this request's environment.
|
|
32
|
+
*
|
|
33
|
+
* Managed we8 keeps auth in a control plane and has the tenant engine trust a
|
|
34
|
+
* signed internal header. Here there is no plane to trust: Better Auth runs
|
|
35
|
+
* inside this worker, over this worker's own D1, and a session cookie is the
|
|
36
|
+
* whole story. Same library and the same patterns as the managed platform, so
|
|
37
|
+
* what is learned on one side transfers to the other.
|
|
38
|
+
*
|
|
39
|
+
* Email and password only in 0.1. Sign-up is open exactly once, to create the
|
|
40
|
+
* first user, who becomes the owner; after that the endpoint is closed at the
|
|
41
|
+
* HTTP layer (see requireBootstrapOpen) and further users are created by the
|
|
42
|
+
* owner through the admin API. Password reset sends through the email seam, so
|
|
43
|
+
* it does nothing useful until a deployment configures a sender, which is the
|
|
44
|
+
* honest behavior for a CMS that ships with no mail transport.
|
|
45
|
+
*/
|
|
46
|
+
export function createAuth(env) {
|
|
47
|
+
const db = drizzle(env.DB);
|
|
48
|
+
const emailSender = resolveEmailSender(env);
|
|
49
|
+
const baseURL = env.AUTH_URL ?? env.SITE_URL;
|
|
50
|
+
return betterAuth({
|
|
51
|
+
database: drizzleAdapter(db, { provider: 'sqlite', schema: authSchema }),
|
|
52
|
+
// A deployment must set this. index.ts refuses to build the handler
|
|
53
|
+
// without it rather than substituting a default, because a predictable
|
|
54
|
+
// session secret is a forged session.
|
|
55
|
+
secret: env.BETTER_AUTH_SECRET ?? '',
|
|
56
|
+
baseURL,
|
|
57
|
+
basePath: AUTH_BASE_PATH,
|
|
58
|
+
trustedOrigins: [baseURL],
|
|
59
|
+
emailAndPassword: {
|
|
60
|
+
enabled: true,
|
|
61
|
+
// No mail transport is configured by default, so requiring a
|
|
62
|
+
// verification click would lock every self-hoster out of their own CMS.
|
|
63
|
+
requireEmailVerification: false,
|
|
64
|
+
// Setting this callback is what enables the reset endpoints at all. The
|
|
65
|
+
// URL is Better Auth's own, carrying the one-time token, used verbatim.
|
|
66
|
+
sendResetPassword: async ({ user, url }) => {
|
|
67
|
+
await sendBestEffort(emailSender, buildPasswordResetEmail(user.email, url));
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
user: {
|
|
71
|
+
additionalFields: {
|
|
72
|
+
// input: false is the load-bearing half. It keeps `role` out of the
|
|
73
|
+
// account-update endpoint's accepted fields, so a member cannot patch
|
|
74
|
+
// themselves to owner; the hook below is the only writer.
|
|
75
|
+
role: { type: 'string', required: false, input: false },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
databaseHooks: {
|
|
79
|
+
user: {
|
|
80
|
+
create: {
|
|
81
|
+
before: async (newUser) => {
|
|
82
|
+
const role = (await isBootstrapOpen(env.DB)) ? 'owner' : 'member';
|
|
83
|
+
return { data: { ...newUser, role } };
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC;AAE1C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAc;IAC7C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,KAAK,EAAqB,CAAC;IAC9F,OAAO,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAc;IAClD,OAAO,CAAC,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CAAC,GAAa;IACtC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC;IAE7C,OAAO,UAAU,CAAC;QAChB,QAAQ,EAAE,cAAc,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QACxE,oEAAoE;QACpE,uEAAuE;QACvE,sCAAsC;QACtC,MAAM,EAAE,GAAG,CAAC,kBAAkB,IAAI,EAAE;QACpC,OAAO;QACP,QAAQ,EAAE,cAAc;QACxB,cAAc,EAAE,CAAC,OAAO,CAAC;QACzB,gBAAgB,EAAE;YAChB,OAAO,EAAE,IAAI;YACb,6DAA6D;YAC7D,wEAAwE;YACxE,wBAAwB,EAAE,KAAK;YAC/B,wEAAwE;YACxE,wEAAwE;YACxE,iBAAiB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;gBACzC,MAAM,cAAc,CAAC,WAAW,EAAE,uBAAuB,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;YAC9E,CAAC;SACF;QACD,IAAI,EAAE;YACJ,gBAAgB,EAAE;gBAChB,oEAAoE;gBACpE,sEAAsE;gBACtE,0DAA0D;gBAC1D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;aACxD;SACF;QACD,aAAa,EAAE;YACb,IAAI,EAAE;gBACJ,MAAM,EAAE;oBACN,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;wBACxB,MAAM,IAAI,GAAa,CAAC,MAAM,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;wBAC5E,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;oBACxC,CAAC;iBACF;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { Bindings } from '../env.js';
|
|
3
|
+
import { type AuthVariables } from '../middleware/auth.js';
|
|
4
|
+
/**
|
|
5
|
+
* Site users, owner-only in full.
|
|
6
|
+
*
|
|
7
|
+
* Public sign-up closes as soon as the first account exists (see the bootstrap
|
|
8
|
+
* gate in src/index.ts), so this is how everybody after the owner gets in.
|
|
9
|
+
* Managed we8 does this from an operator command center over an organization
|
|
10
|
+
* model; standalone, the owner is the operator and there is one site, so it is
|
|
11
|
+
* four routes over the auth tables.
|
|
12
|
+
*
|
|
13
|
+
* Two invariants hold throughout: a site always keeps at least one owner, and
|
|
14
|
+
* nobody changes or deletes their own account here (the account endpoints
|
|
15
|
+
* under /api/auth are for that). Together they make it impossible to lock a
|
|
16
|
+
* site out of its own admin with a single request.
|
|
17
|
+
*/
|
|
18
|
+
export declare const usersAdminRoutes: Hono<{
|
|
19
|
+
Bindings: Bindings;
|
|
20
|
+
Variables: AuthVariables;
|
|
21
|
+
}, import("hono/types").BlankSchema, "/">;
|
|
22
|
+
//# sourceMappingURL=routes.admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.admin.d.ts","sourceRoot":"","sources":["../../src/auth/routes.admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAyDzE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB;cAAwB,QAAQ;eAAa,aAAa;yCAAK,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { ok, USER_ROLES } from '../shared/index.js';
|
|
4
|
+
import { HttpError } from '../lib/errors.js';
|
|
5
|
+
import { parseOrThrow } from '../lib/validate.js';
|
|
6
|
+
import { requireOwner } from '../middleware/auth.js';
|
|
7
|
+
import { createAuth, normalizeRole } from './auth.js';
|
|
8
|
+
const userCreateInputSchema = z.object({
|
|
9
|
+
email: z.string().email(),
|
|
10
|
+
name: z.string().min(1).max(200),
|
|
11
|
+
password: z.string().min(8).max(200),
|
|
12
|
+
});
|
|
13
|
+
const userRoleInputSchema = z.object({
|
|
14
|
+
role: z.enum(USER_ROLES),
|
|
15
|
+
});
|
|
16
|
+
function toAdminUser(row) {
|
|
17
|
+
return {
|
|
18
|
+
id: row.id,
|
|
19
|
+
email: row.email,
|
|
20
|
+
name: row.name,
|
|
21
|
+
role: normalizeRole(row.role),
|
|
22
|
+
// Better Auth stores its timestamps as epoch seconds; the rest of this API
|
|
23
|
+
// speaks ISO strings, so the conversion happens at this boundary.
|
|
24
|
+
createdAt: new Date(row.createdAt * 1000).toISOString(),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async function countOwners(db) {
|
|
28
|
+
const row = await db
|
|
29
|
+
.prepare(`SELECT COUNT(*) AS count FROM user WHERE role = 'owner'`)
|
|
30
|
+
.first();
|
|
31
|
+
return row?.count ?? 0;
|
|
32
|
+
}
|
|
33
|
+
async function fetchUser(db, id) {
|
|
34
|
+
const row = await db
|
|
35
|
+
.prepare('SELECT id, email, name, role, createdAt FROM user WHERE id = ?1')
|
|
36
|
+
.bind(id)
|
|
37
|
+
.first();
|
|
38
|
+
if (!row)
|
|
39
|
+
throw new HttpError('not_found', 'user not found');
|
|
40
|
+
return row;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Site users, owner-only in full.
|
|
44
|
+
*
|
|
45
|
+
* Public sign-up closes as soon as the first account exists (see the bootstrap
|
|
46
|
+
* gate in src/index.ts), so this is how everybody after the owner gets in.
|
|
47
|
+
* Managed we8 does this from an operator command center over an organization
|
|
48
|
+
* model; standalone, the owner is the operator and there is one site, so it is
|
|
49
|
+
* four routes over the auth tables.
|
|
50
|
+
*
|
|
51
|
+
* Two invariants hold throughout: a site always keeps at least one owner, and
|
|
52
|
+
* nobody changes or deletes their own account here (the account endpoints
|
|
53
|
+
* under /api/auth are for that). Together they make it impossible to lock a
|
|
54
|
+
* site out of its own admin with a single request.
|
|
55
|
+
*/
|
|
56
|
+
export const usersAdminRoutes = new Hono();
|
|
57
|
+
usersAdminRoutes.use('*', requireOwner);
|
|
58
|
+
usersAdminRoutes.get('/', async (c) => {
|
|
59
|
+
const { results } = await c.env.DB.prepare('SELECT id, email, name, role, createdAt FROM user ORDER BY createdAt ASC').all();
|
|
60
|
+
return c.json(ok({ items: results.map(toAdminUser) }));
|
|
61
|
+
});
|
|
62
|
+
usersAdminRoutes.post('/', async (c) => {
|
|
63
|
+
const input = parseOrThrow(userCreateInputSchema, await c.req.json());
|
|
64
|
+
const auth = createAuth(c.env);
|
|
65
|
+
// Through the auth API rather than a direct insert, so the password is
|
|
66
|
+
// hashed by the same code that will later verify it. The returned session is
|
|
67
|
+
// discarded: this creates an account, it does not sign anyone in.
|
|
68
|
+
const created = await auth.api.signUpEmail({
|
|
69
|
+
body: { email: input.email, name: input.name, password: input.password },
|
|
70
|
+
});
|
|
71
|
+
return c.json(ok({ user: toAdminUser(await fetchUser(c.env.DB, created.user.id)) }), 201);
|
|
72
|
+
});
|
|
73
|
+
usersAdminRoutes.patch('/:id', async (c) => {
|
|
74
|
+
const input = parseOrThrow(userRoleInputSchema, await c.req.json());
|
|
75
|
+
const target = await fetchUser(c.env.DB, c.req.param('id'));
|
|
76
|
+
if (target.id === c.get('auth').userId) {
|
|
77
|
+
throw new HttpError('validation_error', 'you cannot change your own role');
|
|
78
|
+
}
|
|
79
|
+
if (normalizeRole(target.role) === 'owner' &&
|
|
80
|
+
input.role !== 'owner' &&
|
|
81
|
+
(await countOwners(c.env.DB)) <= 1) {
|
|
82
|
+
throw new HttpError('validation_error', 'a site needs at least one owner');
|
|
83
|
+
}
|
|
84
|
+
await c.env.DB.prepare(`UPDATE user SET role = ?2 WHERE id = ?1`)
|
|
85
|
+
.bind(target.id, input.role)
|
|
86
|
+
.run();
|
|
87
|
+
return c.json(ok({ user: toAdminUser(await fetchUser(c.env.DB, target.id)) }));
|
|
88
|
+
});
|
|
89
|
+
usersAdminRoutes.delete('/:id', async (c) => {
|
|
90
|
+
const target = await fetchUser(c.env.DB, c.req.param('id'));
|
|
91
|
+
if (target.id === c.get('auth').userId) {
|
|
92
|
+
throw new HttpError('validation_error', 'you cannot delete your own account');
|
|
93
|
+
}
|
|
94
|
+
if (normalizeRole(target.role) === 'owner' && (await countOwners(c.env.DB)) <= 1) {
|
|
95
|
+
throw new HttpError('validation_error', 'a site needs at least one owner');
|
|
96
|
+
}
|
|
97
|
+
// The foreign keys declare ON DELETE CASCADE, but D1 does not enforce
|
|
98
|
+
// foreign keys by default, so the children go explicitly and first.
|
|
99
|
+
await c.env.DB.batch([
|
|
100
|
+
c.env.DB.prepare('DELETE FROM session WHERE userId = ?1').bind(target.id),
|
|
101
|
+
c.env.DB.prepare('DELETE FROM account WHERE userId = ?1').bind(target.id),
|
|
102
|
+
c.env.DB.prepare('DELETE FROM user WHERE id = ?1').bind(target.id),
|
|
103
|
+
]);
|
|
104
|
+
return c.json(ok({}));
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=routes.admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.admin.js","sourceRoot":"","sources":["../../src/auth/routes.admin.ts"],"names":[],"mappings":"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"}
|