@mandujs/core 0.53.3 → 0.54.1
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 +654 -654
- package/package.json +1 -1
- package/src/a11y/__tests__/run-audit.test.ts +333 -333
- package/src/a11y/fix-hints.ts +76 -76
- package/src/a11y/index.ts +18 -18
- package/src/a11y/run-audit.ts +394 -394
- package/src/a11y/types.ts +125 -125
- package/src/auth/__tests__/login.test.ts +1 -1
- package/src/auth/__tests__/password.test.ts +122 -122
- package/src/auth/__tests__/tokens.test.ts +274 -274
- package/src/auth/__tests__/verification.test.ts +274 -274
- package/src/auth/index.ts +76 -76
- package/src/auth/login.ts +225 -225
- package/src/auth/password.ts +120 -120
- package/src/auth/reset.ts +243 -243
- package/src/auth/tokens.ts +612 -612
- package/src/auth/verification.ts +253 -253
- package/src/brain/__tests__/redactor.test.ts +94 -94
- package/src/brain/adapters/__tests__/_helpers.ts +83 -83
- package/src/brain/adapters/__tests__/anthropic-oauth.test.ts +196 -196
- package/src/brain/adapters/__tests__/chatgpt-auth.test.ts +193 -193
- package/src/brain/adapters/__tests__/openai-oauth.test.ts +209 -209
- package/src/brain/adapters/__tests__/resolver.test.ts +143 -143
- package/src/brain/adapters/anthropic-oauth.ts +1 -1
- package/src/brain/adapters/chatgpt-auth.ts +300 -300
- package/src/brain/adapters/index.ts +319 -319
- package/src/brain/adapters/oauth-flow.ts +439 -439
- package/src/brain/consent.ts +240 -240
- package/src/brain/credentials.ts +396 -396
- package/src/bundler/__tests__/build-runner.ts +113 -113
- package/src/bundler/__tests__/dev-reliability.test.ts +619 -619
- package/src/bundler/__tests__/extended-watch.test.ts +711 -711
- package/src/bundler/__tests__/fast-refresh.test.ts +10 -10
- package/src/bundler/__tests__/hdr.test.ts +353 -353
- package/src/bundler/__tests__/hmr-client.test.ts +532 -532
- package/src/bundler/__tests__/manifest-schema.test.ts +266 -266
- package/src/bundler/__tests__/prod-smoke.test.ts +138 -138
- package/src/bundler/__tests__/reverse-import-graph.test.ts +519 -519
- package/src/bundler/__tests__/slot-dispatch.test.ts +573 -573
- package/src/bundler/__tests__/url-cap-and-slot-regex.test.ts +286 -286
- package/src/bundler/__tests__/vendor-cache.test.ts +455 -455
- package/src/bundler/budget.ts +404 -404
- package/src/bundler/build.test.ts +179 -179
- package/src/bundler/build.ts +55 -55
- package/src/bundler/dev.ts +42 -42
- package/src/bundler/manifest-schema.ts +301 -301
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +263 -263
- package/src/bundler/plugins/__tests__/react-compiler-config.test.ts +83 -83
- package/src/bundler/plugins/__tests__/react-compiler-lint.test.ts +110 -110
- package/src/bundler/plugins/block-generated-imports.ts +155 -155
- package/src/bundler/plugins/index.ts +83 -83
- package/src/bundler/plugins/react-compiler-config.ts +108 -108
- package/src/bundler/plugins/react-compiler-lint.ts +253 -253
- package/src/bundler/plugins/react-compiler.ts +162 -162
- package/src/bundler/reverse-import-graph.ts +339 -339
- package/src/bundler/safe-build.test.ts +201 -201
- package/src/bundler/safe-build.ts +103 -103
- package/src/bundler/scenario-matrix.ts +229 -229
- package/src/bundler/types.ts +10 -10
- package/src/bundler/vendor-cache-types.ts +130 -130
- package/src/bundler/vendor-cache.ts +526 -526
- package/src/change/snapshot.ts +18 -18
- package/src/client/Form.tsx +105 -105
- package/src/client/Link.tsx +9 -9
- package/src/client/__tests__/use-sse.test.ts +153 -153
- package/src/client/globals.ts +1 -1
- package/src/client/hooks.ts +362 -362
- package/src/client/hydrate.ts +340 -340
- package/src/client/prefetch-helper.ts +55 -55
- package/src/client/router.ts +11 -11
- package/src/client/runtime.ts +47 -47
- package/src/client/serialize.ts +404 -404
- package/src/client/use-fetch.ts +6 -6
- package/src/client/use-head.ts +197 -197
- package/src/client/use-sse.ts +378 -378
- package/src/client/window-state.ts +101 -101
- package/src/components/Image.tsx +162 -162
- package/src/config/validate.ts +3 -3
- package/src/config/watcher.ts +311 -311
- package/src/constants.ts +40 -40
- package/src/content/collection.ts +8 -8
- package/src/content/content-layer.ts +7 -7
- package/src/content/data-store.ts +245 -245
- package/src/content/frontmatter.ts +189 -189
- package/src/content/loader-context.ts +171 -171
- package/src/content/loaders/api.ts +216 -216
- package/src/content/loaders/file.ts +172 -172
- package/src/content/loaders/glob.ts +253 -253
- package/src/content/loaders/index.ts +34 -34
- package/src/content/loaders/types.ts +137 -137
- package/src/content/meta-store.ts +209 -209
- package/src/content/prebuild.test.ts +571 -571
- package/src/content/prebuild.ts +636 -636
- package/src/content/schema.ts +20 -20
- package/src/content/sidebar.ts +630 -630
- package/src/content/slug.ts +110 -110
- package/src/content/types.ts +282 -282
- package/src/content/watcher.ts +135 -135
- package/src/contract/client-safe.test.ts +42 -42
- package/src/contract/client-safe.ts +114 -114
- package/src/contract/define.ts +11 -11
- package/src/contract/index.ts +1 -1
- package/src/contract/normalize.test.ts +276 -276
- package/src/contract/normalize.ts +410 -410
- package/src/contract/registry.test.ts +206 -206
- package/src/contract/route-helpers.ts +1 -1
- package/src/contract/rpc.ts +443 -443
- package/src/contract/schema.ts +48 -48
- package/src/contract/types.ts +58 -58
- package/src/db/__tests__/db.test.ts +482 -482
- package/src/db/index.ts +138 -138
- package/src/db/migrations/history-table.ts +345 -345
- package/src/db/migrations/index.ts +3 -3
- package/src/db/migrations/lock.ts +324 -324
- package/src/db/migrations/runner.ts +650 -650
- package/src/deploy/cache.ts +140 -140
- package/src/deploy/compile/vercel.ts +344 -344
- package/src/deploy/index.ts +87 -87
- package/src/deploy/inference/brain.ts +268 -268
- package/src/deploy/inference/context.ts +182 -182
- package/src/deploy/inference/filling-extract.ts +245 -245
- package/src/deploy/inference/heuristic.ts +182 -182
- package/src/deploy/intent.ts +173 -173
- package/src/deploy/plan.ts +178 -178
- package/src/design/__tests__/agents-link.test.ts +109 -109
- package/src/design/__tests__/extract-patch-diff.test.ts +265 -265
- package/src/design/__tests__/lint.test.ts +110 -110
- package/src/design/__tests__/parser.test.ts +195 -195
- package/src/design/__tests__/tailwind-theme.test.ts +229 -229
- package/src/design/agents-link.ts +165 -165
- package/src/design/diff.ts +138 -138
- package/src/design/extract.ts +285 -285
- package/src/design/index.ts +102 -102
- package/src/design/lint.ts +209 -209
- package/src/design/parser.ts +555 -555
- package/src/design/patch.ts +241 -241
- package/src/design/scaffold.ts +147 -147
- package/src/design/tailwind-theme.ts +441 -441
- package/src/design/types.ts +210 -210
- package/src/desktop/__tests__/webview-fallback.test.ts +254 -254
- package/src/desktop/__tests__/window.test.ts +248 -248
- package/src/desktop/__tests__/worker.test.ts +266 -266
- package/src/desktop/index.ts +43 -43
- package/src/desktop/types.ts +158 -158
- package/src/desktop/worker.ts +180 -180
- package/src/dev-error-overlay/__tests__/overlay-injector.test.ts +241 -241
- package/src/dev-error-overlay/index.ts +30 -30
- package/src/dev-error-overlay/overlay-injector.ts +243 -243
- package/src/dev-error-overlay/overlay-styles.ts +52 -52
- package/src/dev-error-overlay/types.ts +66 -66
- package/src/devtools/ai/context-builder.ts +375 -375
- package/src/devtools/ai/index.ts +25 -25
- package/src/devtools/ai/mcp-connector.ts +25 -25
- package/src/devtools/client/catchers/error-catcher.ts +344 -344
- package/src/devtools/client/catchers/index.ts +18 -18
- package/src/devtools/client/components/index.ts +39 -39
- package/src/devtools/client/components/mandu-character.tsx +331 -331
- package/src/devtools/client/components/overlay.tsx +368 -368
- package/src/devtools/client/components/panel/errors-panel.tsx +259 -259
- package/src/devtools/client/components/panel/guard-panel.tsx +30 -30
- package/src/devtools/client/components/panel/islands-panel.tsx +320 -320
- package/src/devtools/client/components/panel/network-panel.tsx +291 -291
- package/src/devtools/client/components/panel/panel-container.tsx +500 -500
- package/src/devtools/client/components/panel/preview-panel.tsx +46 -46
- package/src/devtools/client/filters/context-filters.ts +282 -282
- package/src/devtools/client/filters/index.ts +16 -16
- package/src/devtools/client/index.ts +63 -63
- package/src/devtools/client/persistence.ts +335 -335
- package/src/devtools/hook/create-hook.ts +207 -207
- package/src/devtools/hook/index.ts +13 -13
- package/src/devtools/index.ts +439 -439
- package/src/devtools/init.ts +265 -265
- package/src/devtools/protocol.ts +237 -237
- package/src/devtools/server/index.ts +17 -17
- package/src/devtools/server/source-context.ts +450 -450
- package/src/devtools/types.ts +35 -35
- package/src/devtools/worker/index.ts +25 -25
- package/src/devtools/worker/redaction-worker.ts +233 -233
- package/src/devtools/worker/worker-manager.ts +410 -410
- package/src/diagnose/__tests__/checks.test.ts +451 -451
- package/src/diagnose/checks.ts +832 -832
- package/src/diagnose/index.ts +17 -17
- package/src/diagnose/run.ts +93 -93
- package/src/diagnose/types.ts +53 -53
- package/src/email/__tests__/email.test.ts +355 -355
- package/src/email/index.ts +282 -282
- package/src/email/smtp.ts +64 -64
- package/src/error/domains.ts +265 -265
- package/src/error/result.ts +60 -60
- package/src/error/types.ts +6 -6
- package/src/errors/extractor.ts +409 -409
- package/src/errors/index.ts +19 -19
- package/src/filling/__tests__/session-sqlite.test.ts +454 -454
- package/src/filling/auth.ts +308 -308
- package/src/filling/cookie-codec.ts +299 -299
- package/src/filling/deps.ts +265 -265
- package/src/filling/session-sqlite.ts +617 -617
- package/src/filling/sse.ts +5 -5
- package/src/filling/ws.ts +78 -78
- package/src/generator/index.ts +3 -3
- package/src/guard/__tests__/design-inline-class.test.ts +219 -219
- package/src/guard/__tests__/tsgolint-bridge.test.ts +347 -347
- package/src/guard/analyzer.ts +360 -360
- package/src/guard/auto-correct.ts +1 -1
- package/src/guard/contract-guard.ts +9 -9
- package/src/guard/define-rule.ts +243 -243
- package/src/guard/design-inline-class.ts +393 -393
- package/src/guard/file-type.test.ts +24 -24
- package/src/guard/graph.ts +1 -1
- package/src/guard/healing.ts +36 -36
- package/src/guard/presets/atomic.ts +70 -70
- package/src/guard/presets/clean.ts +77 -77
- package/src/guard/presets/fsd.ts +79 -79
- package/src/guard/presets/hexagonal.ts +68 -68
- package/src/guard/reporter.ts +442 -442
- package/src/guard/rule-presets.ts +379 -379
- package/src/guard/semantic-slots.ts +1 -1
- package/src/guard/suggestions.ts +358 -358
- package/src/guard/tsgolint-bridge.ts +512 -512
- package/src/guard/types.ts +348 -348
- package/src/guard/watcher.ts +405 -405
- package/src/i18n/define.ts +126 -126
- package/src/i18n/index.ts +52 -52
- package/src/i18n/message-registry.ts +173 -173
- package/src/i18n/types.ts +112 -112
- package/src/id/index.ts +105 -105
- package/src/index.ts +2 -2
- package/src/kitchen/api/agent-devtools-api.ts +779 -544
- package/src/kitchen/api/errors-grouping.ts +126 -0
- package/src/kitchen/kitchen-handler.ts +192 -63
- package/src/kitchen/kitchen-ui.ts +842 -464
- package/src/logging/index.ts +22 -22
- package/src/logging/transports.ts +365 -365
- package/src/middleware/bridge.ts +147 -147
- package/src/middleware/compose.ts +134 -134
- package/src/middleware/compress.ts +62 -62
- package/src/middleware/cors.ts +47 -47
- package/src/middleware/csrf.ts +328 -328
- package/src/middleware/define.ts +132 -132
- package/src/middleware/jwt.ts +134 -134
- package/src/middleware/logger.ts +58 -58
- package/src/middleware/oauth/__tests__/oauth.test.ts +1 -1
- package/src/middleware/oauth/index.ts +505 -505
- package/src/middleware/oauth/providers.ts +115 -115
- package/src/middleware/rate-limit/index.ts +522 -522
- package/src/middleware/rate-limit/sqlite-store.ts +382 -382
- package/src/middleware/scheduler-cron.ts +96 -96
- package/src/middleware/secure/__tests__/secure.test.ts +360 -360
- package/src/middleware/secure/csp.ts +193 -193
- package/src/middleware/session.ts +174 -174
- package/src/middleware/timeout.ts +55 -55
- package/src/observability/logger-adapter.ts +36 -36
- package/src/observability/sqlite-store.ts +254 -254
- package/src/openapi/generator.ts +1 -1
- package/src/openapi/openapi.test.ts +43 -43
- package/src/perf/__tests__/user-marks.test.ts +354 -354
- package/src/perf/index.ts +133 -133
- package/src/plugins/__tests__/lifecycle-integration.test.ts +272 -272
- package/src/plugins/__tests__/runner.test.ts +409 -409
- package/src/plugins/define.ts +124 -124
- package/src/plugins/examples/dep-check-plugin.ts +80 -80
- package/src/plugins/examples/prerender-cache-plugin.ts +111 -111
- package/src/plugins/examples/sitemap-plugin.ts +65 -65
- package/src/plugins/runner.ts +361 -361
- package/src/plugins/types.ts +368 -368
- package/src/report/index.ts +1 -1
- package/src/resource/__tests__/generator.test.ts +32 -32
- package/src/resource/ddl/__tests__/diff.test.ts +639 -639
- package/src/resource/ddl/__tests__/emit.test.ts +823 -823
- package/src/resource/ddl/__tests__/snapshot.test.ts +499 -499
- package/src/resource/ddl/emit.ts +559 -559
- package/src/resource/ddl/persistence-types.ts +218 -218
- package/src/resource/ddl/type-map.ts +223 -223
- package/src/resource/ddl/types.ts +232 -232
- package/src/resource/generator-repo.ts +630 -630
- package/src/resource/schema.ts +1 -1
- package/src/router/fs-patterns.test.ts +96 -96
- package/src/router/fs-routes.ts +6 -6
- package/src/routes/index.ts +74 -74
- package/src/routes/metadata-routes.ts +427 -427
- package/src/routes/types.ts +341 -341
- package/src/runtime/__tests__/error-boundary-redaction.test.ts +141 -141
- package/src/runtime/__tests__/hdr-client.test.ts +223 -223
- package/src/runtime/__tests__/http-errors.test.ts +117 -117
- package/src/runtime/__tests__/not-found.test.ts +152 -152
- package/src/runtime/adapter.ts +47 -47
- package/src/runtime/boundary.tsx +252 -252
- package/src/runtime/cache.ts +494 -494
- package/src/runtime/compose.ts +222 -222
- package/src/runtime/fast-refresh-runtime.ts +322 -322
- package/src/runtime/handler.ts +65 -65
- package/src/runtime/handlers.ts +300 -300
- package/src/runtime/http-errors.ts +113 -113
- package/src/runtime/image-handler.ts +1 -1
- package/src/runtime/lifecycle.ts +381 -381
- package/src/runtime/logger.test.ts +345 -345
- package/src/runtime/middleware.ts +264 -264
- package/src/runtime/not-found.ts +93 -93
- package/src/runtime/openapi-endpoint.ts +236 -236
- package/src/runtime/ppr.ts +74 -74
- package/src/runtime/registry.ts +171 -171
- package/src/runtime/router.ts +105 -105
- package/src/runtime/server.ts +67 -67
- package/src/runtime/shims.ts +48 -48
- package/src/runtime/trace.ts +144 -144
- package/src/scheduler/validate.ts +169 -169
- package/src/seo/index.ts +219 -219
- package/src/seo/integration/ssr.ts +306 -306
- package/src/seo/render/basic.ts +435 -435
- package/src/seo/render/index.ts +143 -143
- package/src/seo/render/jsonld.ts +539 -539
- package/src/seo/render/opengraph.ts +197 -197
- package/src/seo/render/robots.ts +116 -116
- package/src/seo/render/sitemap.ts +137 -137
- package/src/seo/render/twitter.ts +127 -127
- package/src/seo/resolve/opengraph.ts +143 -143
- package/src/seo/resolve/robots.ts +73 -73
- package/src/seo/resolve/title.ts +94 -94
- package/src/seo/resolve/twitter.ts +73 -73
- package/src/seo/resolve/url.ts +104 -104
- package/src/seo/routes/index.ts +290 -290
- package/src/seo/types.ts +588 -588
- package/src/slot/validator.ts +39 -39
- package/src/storage/s3/__tests__/s3.test.ts +479 -479
- package/src/storage/s3/index.ts +412 -412
- package/src/testing/__tests__/assertions.test.ts +632 -632
- package/src/testing/__tests__/reporter.test.ts +454 -454
- package/src/testing/assertions.ts +986 -986
- package/src/testing/db.ts +157 -157
- package/src/testing/mocks.ts +203 -203
- package/src/testing/session.ts +190 -190
- package/src/types/branded.ts +56 -56
- package/src/types/index.ts +1 -1
- package/src/utils/safe-io.ts +188 -188
- package/src/utils/string-safe.ts +298 -298
- package/src/watcher/watcher.ts +18 -18
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider presets for the OAuth middleware.
|
|
3
|
-
*
|
|
4
|
-
* Each factory returns a fresh {@link OAuthProvider} — callers should treat
|
|
5
|
-
* the returned object as immutable, but constructing a new one per `oauth()`
|
|
6
|
-
* invocation means mutations by one consumer never leak across another.
|
|
7
|
-
*
|
|
8
|
-
* Only GitHub and Google ship here. Twitter, Discord, Microsoft etc. are
|
|
9
|
-
* user-contribution territory — the {@link OAuthProvider} shape is stable
|
|
10
|
-
* and narrow on purpose.
|
|
11
|
-
*
|
|
12
|
-
* @module middleware/oauth/providers
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { OAuthProfile, OAuthProvider } from "./index";
|
|
16
|
-
|
|
17
|
-
// ========== GitHub ==========
|
|
18
|
-
|
|
19
|
-
/** Raw shape of `GET https://api.github.com/user`. Fields we consume + passthrough. */
|
|
20
|
-
interface GitHubRawUser {
|
|
21
|
-
id: number | string;
|
|
22
|
-
email?: string | null;
|
|
23
|
-
name?: string | null;
|
|
24
|
-
avatar_url?: string | null;
|
|
25
|
-
[key: string]: unknown;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* GitHub OAuth preset.
|
|
30
|
-
*
|
|
31
|
-
* Docs: https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps
|
|
32
|
-
*
|
|
33
|
-
* Notes:
|
|
34
|
-
* - The token endpoint defaults to urlencoded responses; the middleware
|
|
35
|
-
* sets `Accept: application/json` on the POST so we always parse JSON.
|
|
36
|
-
* - `user:email` scope covers the case where the user's primary email is
|
|
37
|
-
* private — without it, `raw.email` comes back as `null`.
|
|
38
|
-
* - PKCE is supported and enabled by default.
|
|
39
|
-
*/
|
|
40
|
-
export function github(): OAuthProvider {
|
|
41
|
-
return {
|
|
42
|
-
name: "github",
|
|
43
|
-
authorizationEndpoint: "https://github.com/login/oauth/authorize",
|
|
44
|
-
tokenEndpoint: "https://github.com/login/oauth/access_token",
|
|
45
|
-
userinfoEndpoint: "https://api.github.com/user",
|
|
46
|
-
scopes: ["read:user", "user:email"],
|
|
47
|
-
pkce: true,
|
|
48
|
-
normalizeProfile: (raw: unknown): OAuthProfile => {
|
|
49
|
-
if (!raw || typeof raw !== "object") {
|
|
50
|
-
throw new Error("[Mandu OAuth/github] userinfo payload is not an object");
|
|
51
|
-
}
|
|
52
|
-
const r = raw as GitHubRawUser;
|
|
53
|
-
if (r.id === undefined || r.id === null) {
|
|
54
|
-
throw new Error("[Mandu OAuth/github] userinfo payload missing `id`");
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
id: String(r.id),
|
|
58
|
-
email: typeof r.email === "string" ? r.email : undefined,
|
|
59
|
-
name: typeof r.name === "string" ? r.name : undefined,
|
|
60
|
-
avatarUrl: typeof r.avatar_url === "string" ? r.avatar_url : undefined,
|
|
61
|
-
raw,
|
|
62
|
-
};
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ========== Google ==========
|
|
68
|
-
|
|
69
|
-
/** Raw shape of Google's OIDC `userinfo` endpoint. */
|
|
70
|
-
interface GoogleRawUser {
|
|
71
|
-
sub: string;
|
|
72
|
-
email?: string;
|
|
73
|
-
name?: string;
|
|
74
|
-
picture?: string;
|
|
75
|
-
[key: string]: unknown;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Google OAuth preset (OpenID Connect flavor).
|
|
80
|
-
*
|
|
81
|
-
* Docs: https://developers.google.com/identity/protocols/oauth2/openid-connect
|
|
82
|
-
*
|
|
83
|
-
* Notes:
|
|
84
|
-
* - Uses the static OIDC userinfo endpoint (no discovery at runtime).
|
|
85
|
-
* - `sub` is the stable provider-scoped user id; `email` may still change
|
|
86
|
-
* if the user renames their account, so consumers keying user records
|
|
87
|
-
* should prefer `profile.id` over `profile.email`.
|
|
88
|
-
* - PKCE is supported and enabled by default.
|
|
89
|
-
*/
|
|
90
|
-
export function google(): OAuthProvider {
|
|
91
|
-
return {
|
|
92
|
-
name: "google",
|
|
93
|
-
authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
94
|
-
tokenEndpoint: "https://oauth2.googleapis.com/token",
|
|
95
|
-
userinfoEndpoint: "https://openidconnect.googleapis.com/v1/userinfo",
|
|
96
|
-
scopes: ["openid", "email", "profile"],
|
|
97
|
-
pkce: true,
|
|
98
|
-
normalizeProfile: (raw: unknown): OAuthProfile => {
|
|
99
|
-
if (!raw || typeof raw !== "object") {
|
|
100
|
-
throw new Error("[Mandu OAuth/google] userinfo payload is not an object");
|
|
101
|
-
}
|
|
102
|
-
const r = raw as GoogleRawUser;
|
|
103
|
-
if (typeof r.sub !== "string" || r.sub.length === 0) {
|
|
104
|
-
throw new Error("[Mandu OAuth/google] userinfo payload missing `sub`");
|
|
105
|
-
}
|
|
106
|
-
return {
|
|
107
|
-
id: r.sub,
|
|
108
|
-
email: typeof r.email === "string" ? r.email : undefined,
|
|
109
|
-
name: typeof r.name === "string" ? r.name : undefined,
|
|
110
|
-
avatarUrl: typeof r.picture === "string" ? r.picture : undefined,
|
|
111
|
-
raw,
|
|
112
|
-
};
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Provider presets for the OAuth middleware.
|
|
3
|
+
*
|
|
4
|
+
* Each factory returns a fresh {@link OAuthProvider} — callers should treat
|
|
5
|
+
* the returned object as immutable, but constructing a new one per `oauth()`
|
|
6
|
+
* invocation means mutations by one consumer never leak across another.
|
|
7
|
+
*
|
|
8
|
+
* Only GitHub and Google ship here. Twitter, Discord, Microsoft etc. are
|
|
9
|
+
* user-contribution territory — the {@link OAuthProvider} shape is stable
|
|
10
|
+
* and narrow on purpose.
|
|
11
|
+
*
|
|
12
|
+
* @module middleware/oauth/providers
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { OAuthProfile, OAuthProvider } from "./index";
|
|
16
|
+
|
|
17
|
+
// ========== GitHub ==========
|
|
18
|
+
|
|
19
|
+
/** Raw shape of `GET https://api.github.com/user`. Fields we consume + passthrough. */
|
|
20
|
+
interface GitHubRawUser {
|
|
21
|
+
id: number | string;
|
|
22
|
+
email?: string | null;
|
|
23
|
+
name?: string | null;
|
|
24
|
+
avatar_url?: string | null;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* GitHub OAuth preset.
|
|
30
|
+
*
|
|
31
|
+
* Docs: https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps
|
|
32
|
+
*
|
|
33
|
+
* Notes:
|
|
34
|
+
* - The token endpoint defaults to urlencoded responses; the middleware
|
|
35
|
+
* sets `Accept: application/json` on the POST so we always parse JSON.
|
|
36
|
+
* - `user:email` scope covers the case where the user's primary email is
|
|
37
|
+
* private — without it, `raw.email` comes back as `null`.
|
|
38
|
+
* - PKCE is supported and enabled by default.
|
|
39
|
+
*/
|
|
40
|
+
export function github(): OAuthProvider {
|
|
41
|
+
return {
|
|
42
|
+
name: "github",
|
|
43
|
+
authorizationEndpoint: "https://github.com/login/oauth/authorize",
|
|
44
|
+
tokenEndpoint: "https://github.com/login/oauth/access_token",
|
|
45
|
+
userinfoEndpoint: "https://api.github.com/user",
|
|
46
|
+
scopes: ["read:user", "user:email"],
|
|
47
|
+
pkce: true,
|
|
48
|
+
normalizeProfile: (raw: unknown): OAuthProfile => {
|
|
49
|
+
if (!raw || typeof raw !== "object") {
|
|
50
|
+
throw new Error("[Mandu OAuth/github] userinfo payload is not an object");
|
|
51
|
+
}
|
|
52
|
+
const r = raw as GitHubRawUser;
|
|
53
|
+
if (r.id === undefined || r.id === null) {
|
|
54
|
+
throw new Error("[Mandu OAuth/github] userinfo payload missing `id`");
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
id: String(r.id),
|
|
58
|
+
email: typeof r.email === "string" ? r.email : undefined,
|
|
59
|
+
name: typeof r.name === "string" ? r.name : undefined,
|
|
60
|
+
avatarUrl: typeof r.avatar_url === "string" ? r.avatar_url : undefined,
|
|
61
|
+
raw,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ========== Google ==========
|
|
68
|
+
|
|
69
|
+
/** Raw shape of Google's OIDC `userinfo` endpoint. */
|
|
70
|
+
interface GoogleRawUser {
|
|
71
|
+
sub: string;
|
|
72
|
+
email?: string;
|
|
73
|
+
name?: string;
|
|
74
|
+
picture?: string;
|
|
75
|
+
[key: string]: unknown;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Google OAuth preset (OpenID Connect flavor).
|
|
80
|
+
*
|
|
81
|
+
* Docs: https://developers.google.com/identity/protocols/oauth2/openid-connect
|
|
82
|
+
*
|
|
83
|
+
* Notes:
|
|
84
|
+
* - Uses the static OIDC userinfo endpoint (no discovery at runtime).
|
|
85
|
+
* - `sub` is the stable provider-scoped user id; `email` may still change
|
|
86
|
+
* if the user renames their account, so consumers keying user records
|
|
87
|
+
* should prefer `profile.id` over `profile.email`.
|
|
88
|
+
* - PKCE is supported and enabled by default.
|
|
89
|
+
*/
|
|
90
|
+
export function google(): OAuthProvider {
|
|
91
|
+
return {
|
|
92
|
+
name: "google",
|
|
93
|
+
authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
94
|
+
tokenEndpoint: "https://oauth2.googleapis.com/token",
|
|
95
|
+
userinfoEndpoint: "https://openidconnect.googleapis.com/v1/userinfo",
|
|
96
|
+
scopes: ["openid", "email", "profile"],
|
|
97
|
+
pkce: true,
|
|
98
|
+
normalizeProfile: (raw: unknown): OAuthProfile => {
|
|
99
|
+
if (!raw || typeof raw !== "object") {
|
|
100
|
+
throw new Error("[Mandu OAuth/google] userinfo payload is not an object");
|
|
101
|
+
}
|
|
102
|
+
const r = raw as GoogleRawUser;
|
|
103
|
+
if (typeof r.sub !== "string" || r.sub.length === 0) {
|
|
104
|
+
throw new Error("[Mandu OAuth/google] userinfo payload missing `sub`");
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
id: r.sub,
|
|
108
|
+
email: typeof r.email === "string" ? r.email : undefined,
|
|
109
|
+
name: typeof r.name === "string" ? r.name : undefined,
|
|
110
|
+
avatarUrl: typeof r.picture === "string" ? r.picture : undefined,
|
|
111
|
+
raw,
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|