@schlessera/brain-ui-server 0.30.1 → 0.32.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 +46 -5
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +49 -25
- package/dist/app.js.map +1 -1
- package/dist/config/env.d.ts +6 -5
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +13 -7
- package/dist/config/env.js.map +1 -1
- package/dist/files/walker.d.ts.map +1 -1
- package/dist/files/walker.js +70 -10
- package/dist/files/walker.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/auth.d.ts +25 -5
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +255 -47
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/body-limit.d.ts +15 -0
- package/dist/middleware/body-limit.d.ts.map +1 -0
- package/dist/middleware/body-limit.js +41 -0
- package/dist/middleware/body-limit.js.map +1 -0
- package/dist/middleware/origin.d.ts +20 -12
- package/dist/middleware/origin.d.ts.map +1 -1
- package/dist/middleware/origin.js +71 -25
- package/dist/middleware/origin.js.map +1 -1
- package/dist/middleware/passkeys.d.ts +5 -1
- package/dist/middleware/passkeys.d.ts.map +1 -1
- package/dist/middleware/passkeys.js +67 -26
- package/dist/middleware/passkeys.js.map +1 -1
- package/dist/routes/brain.d.ts.map +1 -1
- package/dist/routes/brain.js +7 -2
- package/dist/routes/brain.js.map +1 -1
- package/dist/routes/files.js +2 -2
- package/dist/routes/files.js.map +1 -1
- package/dist/routes/models.d.ts.map +1 -1
- package/dist/routes/models.js +22 -10
- package/dist/routes/models.js.map +1 -1
- package/dist/routes/pi-auth.d.ts.map +1 -1
- package/dist/routes/pi-auth.js +12 -4
- package/dist/routes/pi-auth.js.map +1 -1
- package/dist/routes/push.d.ts.map +1 -1
- package/dist/routes/push.js +12 -4
- package/dist/routes/push.js.map +1 -1
- package/dist/routes/render.d.ts +6 -0
- package/dist/routes/render.d.ts.map +1 -1
- package/dist/routes/render.js +8 -11
- package/dist/routes/render.js.map +1 -1
- package/dist/routes/share.d.ts +2 -0
- package/dist/routes/share.d.ts.map +1 -1
- package/dist/routes/share.js +30 -31
- package/dist/routes/share.js.map +1 -1
- package/dist/routes/skills.d.ts.map +1 -1
- package/dist/routes/skills.js +22 -8
- package/dist/routes/skills.js.map +1 -1
- package/dist/routes/web-search.d.ts.map +1 -1
- package/dist/routes/web-search.js +7 -2
- package/dist/routes/web-search.js.map +1 -1
- package/dist/share/staging.d.ts.map +1 -1
- package/dist/share/staging.js +2 -1
- package/dist/share/staging.js.map +1 -1
- package/dist/ws/clients.d.ts +13 -4
- package/dist/ws/clients.d.ts.map +1 -1
- package/dist/ws/clients.js +41 -5
- package/dist/ws/clients.js.map +1 -1
- package/dist/ws/connection.d.ts.map +1 -1
- package/dist/ws/connection.js +10 -2
- package/dist/ws/connection.js.map +1 -1
- package/dist/ws/host.d.ts +5 -0
- package/dist/ws/host.d.ts.map +1 -1
- package/dist/ws/host.js +18 -1
- package/dist/ws/host.js.map +1 -1
- package/package.json +3 -3
- package/src/app.ts +55 -23
- package/src/config/env.ts +18 -7
- package/src/files/walker.ts +66 -10
- package/src/index.ts +8 -0
- package/src/middleware/auth.ts +311 -48
- package/src/middleware/body-limit.ts +47 -0
- package/src/middleware/origin.ts +92 -24
- package/src/middleware/passkeys.ts +80 -29
- package/src/routes/brain.ts +7 -3
- package/src/routes/files.ts +2 -2
- package/src/routes/models.ts +17 -10
- package/src/routes/pi-auth.ts +10 -4
- package/src/routes/push.ts +10 -4
- package/src/routes/render.ts +14 -10
- package/src/routes/share.ts +35 -34
- package/src/routes/skills.ts +18 -8
- package/src/routes/web-search.ts +6 -2
- package/src/share/staging.ts +2 -1
- package/src/ws/clients.ts +45 -7
- package/src/ws/connection.ts +11 -2
- package/src/ws/host.ts +23 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export { createApp, type CreateAppOptions, type BrainUiApp, type AppRenderer, } from "./app.js";
|
|
12
12
|
export { ENV_VARS, resolveServerConfig, type EnvVarDescriptor, type ServerConfig, type AuthConfig, type WebAuthnConfig, type AgentConfig, type VoiceConfig, } from "./config/env.js";
|
|
13
13
|
export { assertBackendResolvable, createBackendRegistry, createStaticBackendRegistry, type BackendLogFn, type BackendRegistry, type ModelDiscoverySource, type ModelDiscoveryState, } from "./agent/backend.js";
|
|
14
|
-
export { resolveAuthMode, type AuthMode, type AuthRuntime, } from "./middleware/auth.js";
|
|
14
|
+
export { authGuard, bumpSessionsEpoch, isWsAuthorized, resolveAuthMode, type AuthMode, type AuthRuntime, } from "./middleware/auth.js";
|
|
15
15
|
export { createUiDb } from "./db/client.js";
|
|
16
16
|
export { openBrainDb, withBrainDb, BrainDbUnavailableError, MIN_BRAIN_SCHEMA_VERSION, } from "./db/brain-db.js";
|
|
17
17
|
export { WsHost, type WsHostOptions } from "./ws/host.js";
|
|
@@ -26,6 +26,7 @@ export { createActivityStream, type ActivityStream } from "./activity/stream.js"
|
|
|
26
26
|
export { ingestSpanSink } from "./activity/span-sink.js";
|
|
27
27
|
export { generateActivityDigest, latestActivityDigest, DIGEST_JOB_NAME, type ActivityDigest, } from "./activity/digest.js";
|
|
28
28
|
export { pruneShareStaging, shareStagingRoot } from "./share/staging.js";
|
|
29
|
+
export { MAX_ARCHIVE_BYTES } from "./skills/install.js";
|
|
29
30
|
export { createObservability, createRecordingObservability, createSilentObservability, createConsoleLoggerProvider, createRecordingLoggerProvider, createSilentLoggerProvider, createInMemoryMeterProvider, SEVERITIES, severityRank, seriesKey, } from "./observability/index.js";
|
|
30
31
|
export type { Observability, ObservabilityOptions, RecordingObservability, RecordingLoggerProvider, InMemoryMeterProvider, LogReader, LogWriter, MetricsReader, Severity, CapturedLog, LogQuery, MetricPoint, MetricSnapshot, } from "./observability/index.js";
|
|
31
32
|
export { buildKeyterms, writeCache, type KeytermSettings, } from "./voice/keyterm-builder.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,GACpB,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKxE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKxE,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,KAAK,cAAc,GACpB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKzE,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,aAAa,EACb,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,aAAa,EACb,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,GACpB,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKxE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKxE,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,KAAK,cAAc,GACpB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAKxD,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,aAAa,EACb,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,aAAa,EACb,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ export { ENV_VARS, resolveServerConfig, } from "./config/env.js";
|
|
|
15
15
|
// Boot-time diagnostics (fail fast on a bad AGENT_BACKEND / profile config,
|
|
16
16
|
// log the resolved auth mode).
|
|
17
17
|
export { assertBackendResolvable, createBackendRegistry, createStaticBackendRegistry, } from "./agent/backend.js";
|
|
18
|
-
export { resolveAuthMode, } from "./middleware/auth.js";
|
|
18
|
+
export { authGuard, bumpSessionsEpoch, isWsAuthorized, resolveAuthMode, } from "./middleware/auth.js";
|
|
19
19
|
// The app's own SQLite database (sessions, passkeys, settings).
|
|
20
20
|
export { createUiDb } from "./db/client.js";
|
|
21
21
|
// Brain database access (read-only, schema-gated) for embedders adding
|
|
@@ -44,6 +44,10 @@ export { generateActivityDigest, latestActivityDigest, DIGEST_JOB_NAME, } from "
|
|
|
44
44
|
// Share staging: a deployment can sweep expired staging dirs at boot; the
|
|
45
45
|
// intake route also sweeps opportunistically on every share.
|
|
46
46
|
export { pruneShareStaging, shareStagingRoot } from "./share/staging.js";
|
|
47
|
+
// Skill archive transport sizing for deployment shells. The route keeps the
|
|
48
|
+
// application-level check; consumers use this value only to avoid setting a
|
|
49
|
+
// smaller process-level request ceiling.
|
|
50
|
+
export { MAX_ARCHIVE_BYTES } from "./skills/install.js";
|
|
47
51
|
// Observability: the producing side is the OpenTelemetry API, the consuming
|
|
48
52
|
// side is ours. Swap the consumer to change where a deployment reports; a test
|
|
49
53
|
// swaps in the recording one and asserts on what the server actually said.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,GAIV,MAAM,UAAU,CAAC;AAElB,6EAA6E;AAC7E,8EAA8E;AAC9E,OAAO,EACL,QAAQ,EACR,mBAAmB,GAOpB,MAAM,iBAAiB,CAAC;AAEzB,4EAA4E;AAC5E,+BAA+B;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,GAK5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,GAGhB,MAAM,sBAAsB,CAAC;AAE9B,gEAAgE;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,uEAAuE;AACvE,qBAAqB;AACrB,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAE1B,+CAA+C;AAC/C,OAAO,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,GAEd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,GAErB,MAAM,yBAAyB,CAAC;AAEjC,0EAA0E;AAC1E,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAExE,8EAA8E;AAC9E,yEAAyE;AACzE,yCAAyC;AACzC,OAAO,EAAE,aAAa,EAAsB,MAAM,qBAAqB,CAAC;AAExE,0EAA0E;AAC1E,6EAA6E;AAC7E,oCAAoC;AACpC,OAAO,EACL,mBAAmB,EACnB,aAAa,GAQd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAuB,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAE9B,0EAA0E;AAC1E,6DAA6D;AAC7D,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,4EAA4E;AAC5E,+EAA+E;AAC/E,2EAA2E;AAC3E,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAiBlC,wEAAwE;AACxE,OAAO,EACL,aAAa,EACb,UAAU,GAEX,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,GAIV,MAAM,UAAU,CAAC;AAElB,6EAA6E;AAC7E,8EAA8E;AAC9E,OAAO,EACL,QAAQ,EACR,mBAAmB,GAOpB,MAAM,iBAAiB,CAAC;AAEzB,4EAA4E;AAC5E,+BAA+B;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,GAK5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,eAAe,GAGhB,MAAM,sBAAsB,CAAC;AAE9B,gEAAgE;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,uEAAuE;AACvE,qBAAqB;AACrB,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAE1B,+CAA+C;AAC/C,OAAO,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,GAEd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,GAErB,MAAM,yBAAyB,CAAC;AAEjC,0EAA0E;AAC1E,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAExE,8EAA8E;AAC9E,yEAAyE;AACzE,yCAAyC;AACzC,OAAO,EAAE,aAAa,EAAsB,MAAM,qBAAqB,CAAC;AAExE,0EAA0E;AAC1E,6EAA6E;AAC7E,oCAAoC;AACpC,OAAO,EACL,mBAAmB,EACnB,aAAa,GAQd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAuB,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAE9B,0EAA0E;AAC1E,6DAA6D;AAC7D,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,4EAA4E;AAC5E,4EAA4E;AAC5E,yCAAyC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,4EAA4E;AAC5E,+EAA+E;AAC/E,2EAA2E;AAC3E,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAiBlC,wEAAwE;AACxE,OAAO,EACL,aAAa,EACb,UAAU,GAEX,MAAM,4BAA4B,CAAC"}
|
|
@@ -2,7 +2,9 @@ import type { Counter } from "@opentelemetry/api";
|
|
|
2
2
|
import type { Logger } from "@opentelemetry/api-logs";
|
|
3
3
|
import { Hono } from "hono";
|
|
4
4
|
import type { Context, MiddlewareHandler } from "hono";
|
|
5
|
+
import type { Database } from "bun:sqlite";
|
|
5
6
|
import type { AuthConfig } from "../config/env.js";
|
|
7
|
+
import type { ClientSet } from "../ws/clients.js";
|
|
6
8
|
/**
|
|
7
9
|
* Authentication for a remote surface to an agent with write access to the
|
|
8
10
|
* user's files. Modes (AUTH_MODE):
|
|
@@ -33,7 +35,8 @@ export interface AuthRuntime extends AuthConfig {
|
|
|
33
35
|
host: string;
|
|
34
36
|
}
|
|
35
37
|
export declare const LOGIN_RATE_LIMIT = 5;
|
|
36
|
-
export declare const GLOBAL_LOGIN_RATE_LIMIT =
|
|
38
|
+
export declare const GLOBAL_LOGIN_RATE_LIMIT = 100;
|
|
39
|
+
export declare const PASSKEY_LOGIN_RATE_LIMIT = 5;
|
|
37
40
|
export declare function resolveAuthMode(auth: AuthRuntime, log?: Logger): AuthMode;
|
|
38
41
|
/**
|
|
39
42
|
* Validate the auth configuration at startup. Throws (refusing to boot) on an
|
|
@@ -41,7 +44,7 @@ export declare function resolveAuthMode(auth: AuthRuntime, log?: Logger): AuthMo
|
|
|
41
44
|
*/
|
|
42
45
|
export declare function assertAuthConfig(mode: AuthMode, auth: AuthRuntime, log?: Logger): void;
|
|
43
46
|
/** Middleware guarding /api/* according to the resolved mode. */
|
|
44
|
-
export declare function authGuard(mode: AuthMode, auth: AuthRuntime): MiddlewareHandler;
|
|
47
|
+
export declare function authGuard(mode: AuthMode, auth: AuthRuntime, db: Database): MiddlewareHandler;
|
|
45
48
|
/**
|
|
46
49
|
* Authorize a WebSocket upgrade. The upgrade handler must call this itself —
|
|
47
50
|
* browsers can't set headers on the WS handshake, so the session cookie (sent
|
|
@@ -49,18 +52,33 @@ export declare function authGuard(mode: AuthMode, auth: AuthRuntime): Middleware
|
|
|
49
52
|
* middleware may sit on the WS route (immutable-header errors). Mirrors
|
|
50
53
|
* {@link authGuard} without emitting a response.
|
|
51
54
|
*/
|
|
52
|
-
export declare function isWsAuthorized(c: Context, mode: AuthMode, auth: AuthRuntime): Promise<boolean>;
|
|
55
|
+
export declare function isWsAuthorized(c: Context, mode: AuthMode, auth: AuthRuntime, db: Database): Promise<boolean>;
|
|
53
56
|
/**
|
|
54
57
|
* Mint the session cookie. The single place a session comes into existence —
|
|
55
58
|
* both password login and passkey login (middleware/passkeys.ts) call this, so
|
|
56
59
|
* authGuard / isWsAuthorized / TTL semantics stay identical across methods.
|
|
57
60
|
*/
|
|
58
|
-
export declare function issueSessionCookie(c: Context, auth: AuthRuntime): Promise<void>;
|
|
61
|
+
export declare function issueSessionCookie(c: Context, auth: AuthRuntime, db: Database): Promise<void>;
|
|
62
|
+
/** Invalidate every issued session and disconnect every attached client. */
|
|
63
|
+
export declare function bumpSessionsEpoch(db: Database, clients: ClientSet): number;
|
|
64
|
+
/** Record one genuine authentication failure in a fixed one-minute window. */
|
|
65
|
+
export declare function recordLoginFailure(key: string, limit: number): void;
|
|
66
|
+
/** Read without allocating: junk requests cannot grow the failure map. */
|
|
67
|
+
export declare function isLoginBlocked(key: string, limit: number): boolean;
|
|
68
|
+
/** Internal middleware coordination; not exported from the package root. */
|
|
69
|
+
export declare function acquirePasskeyVerification(ip: string): boolean;
|
|
70
|
+
/** Internal middleware coordination; not exported from the package root. */
|
|
71
|
+
export declare function releasePasskeyVerification(ip: string): void;
|
|
59
72
|
/** Test-only: clear all rate-limit buckets (they are module-global state). */
|
|
60
73
|
export declare function resetLoginRateLimiter(): void;
|
|
74
|
+
/** Attempt-counting bucket retained for passkey option generation. */
|
|
61
75
|
export declare function consumeLoginToken(key: string, limit: number): boolean;
|
|
62
76
|
/** Login/logout routes. Only functional in `password` mode. */
|
|
63
|
-
export declare function authRoutes(mode: AuthMode, auth: AuthRuntime, deps
|
|
77
|
+
export declare function authRoutes(mode: AuthMode, auth: AuthRuntime, deps: {
|
|
78
|
+
/** Authoritative session state. */
|
|
79
|
+
db: Database;
|
|
80
|
+
/** Live sockets closed whenever the global session epoch advances. */
|
|
81
|
+
clients: ClientSet;
|
|
64
82
|
/**
|
|
65
83
|
* When provided and returning true, password login is refused (the app
|
|
66
84
|
* injects passkeys' passwordLoginDisabled so the shared password dies
|
|
@@ -72,5 +90,7 @@ export declare function authRoutes(mode: AuthMode, auth: AuthRuntime, deps?: {
|
|
|
72
90
|
log?: Logger;
|
|
73
91
|
/** Failed-login counter — the same `auth.failures` instrument passkeys use. */
|
|
74
92
|
failures?: Counter;
|
|
93
|
+
/** Test-only password verifier; production uses Bun.password.verify. */
|
|
94
|
+
verifyPassword?: (password: string, hash: string) => Promise<boolean>;
|
|
75
95
|
}): Hono;
|
|
76
96
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import { getSignedCookie, setSignedCookie, deleteCookie } from "hono/cookie";
|
|
3
3
|
import { isTailscaleAllowed, clientIp } from "./tailscale.js";
|
|
4
|
+
import { readJsonBody } from "./body-limit.js";
|
|
5
|
+
import { requireJson } from "./origin.js";
|
|
6
|
+
import { setSetting } from "../db/settings.js";
|
|
4
7
|
const COOKIE_NAME = "brain_ui_session";
|
|
5
8
|
const SESSION_TTL_SECONDS = 30 * 24 * 60 * 60; // 30 days
|
|
6
|
-
|
|
9
|
+
const SESSIONS_EPOCH_KEY = "auth.sessionsEpoch";
|
|
10
|
+
const SESSION_REVOKED_CLOSE_CODE = 1008;
|
|
11
|
+
const SESSION_REVOKED_CLOSE_REASON = "Sessions invalidated";
|
|
12
|
+
export const LOGIN_RATE_LIMIT = 5; // failures per window, per client IP
|
|
7
13
|
const LOGIN_RATE_WINDOW_MS = 60_000; // per minute
|
|
8
14
|
// A global cap in addition to the per-IP one: the per-IP key is derived from
|
|
9
15
|
// X-Forwarded-For, which a client behind a trusted proxy can rotate to mint a
|
|
10
16
|
// fresh bucket per request. The global cap bounds brute force across rotated
|
|
11
|
-
// IPs.
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
17
|
+
// IPs. At 100 genuine failures/minute it stays well above a human's needs and
|
|
18
|
+
// makes a global lockout substantially harder to weaponize, while still
|
|
19
|
+
// bounding distributed online guessing. Per-IP failures remain at 5/minute.
|
|
20
|
+
// Passkeys get 5 matched-but-invalid assertions/minute in an independent
|
|
21
|
+
// `pk:` bucket: assertions are not guessable, but verification still consumes
|
|
22
|
+
// resources. Password and passkey verification therefore each allow two
|
|
23
|
+
// in-flight operations per IP and eight process-wide. Two tolerates a browser
|
|
24
|
+
// retry/double-submit; eight bounds either verifier's comparable CPU cost.
|
|
25
|
+
// Keeping the reservation pools separate preserves passkeys' independent
|
|
26
|
+
// admission path while each pool still has a process-wide ceiling. The failure
|
|
27
|
+
// map and both reservation maps cap at 1,024 source keys, comfortably above
|
|
28
|
+
// the global password-failure budget while bounding forged-IP memory growth.
|
|
29
|
+
export const GLOBAL_LOGIN_RATE_LIMIT = 100; // failures per window, all IPs combined
|
|
30
|
+
export const PASSKEY_LOGIN_RATE_LIMIT = 5;
|
|
31
|
+
const PASSWORD_VERIFY_IN_FLIGHT_PER_IP = 2;
|
|
32
|
+
const PASSWORD_VERIFY_IN_FLIGHT_GLOBAL = 8;
|
|
33
|
+
const PASSKEY_VERIFY_IN_FLIGHT_PER_IP = 2;
|
|
34
|
+
const PASSKEY_VERIFY_IN_FLIGHT_GLOBAL = 8;
|
|
35
|
+
const LOGIN_BUCKET_CAP = 1_024;
|
|
36
|
+
// Client-derived password buckets always start `pw:ip:`, which cannot equal
|
|
37
|
+
// the fixed `pw:global` key for any client-controlled key suffix. Keeping these
|
|
38
|
+
// namespaces disjoint prevents a per-IP saturated write from clamping the
|
|
39
|
+
// authoritative global failure counter to the smaller per-IP limit.
|
|
40
|
+
const PASSWORD_IP_BUCKET_PREFIX = "pw:ip:";
|
|
41
|
+
const PASSWORD_GLOBAL_BUCKET = "pw:global";
|
|
15
42
|
export function resolveAuthMode(auth, log) {
|
|
16
43
|
if (auth.mode)
|
|
17
44
|
return auth.mode;
|
|
@@ -89,7 +116,7 @@ export function assertAuthConfig(mode, auth, log) {
|
|
|
89
116
|
});
|
|
90
117
|
}
|
|
91
118
|
/** Middleware guarding /api/* according to the resolved mode. */
|
|
92
|
-
export function authGuard(mode, auth) {
|
|
119
|
+
export function authGuard(mode, auth, db) {
|
|
93
120
|
switch (mode) {
|
|
94
121
|
case "tailscale":
|
|
95
122
|
return async (c, next) => {
|
|
@@ -111,7 +138,7 @@ export function authGuard(mode, auth) {
|
|
|
111
138
|
};
|
|
112
139
|
case "password":
|
|
113
140
|
return async (c, next) => {
|
|
114
|
-
if (await hasValidSession(c, auth)) {
|
|
141
|
+
if (await hasValidSession(c, auth, db)) {
|
|
115
142
|
await next();
|
|
116
143
|
}
|
|
117
144
|
else {
|
|
@@ -131,7 +158,7 @@ export function authGuard(mode, auth) {
|
|
|
131
158
|
* middleware may sit on the WS route (immutable-header errors). Mirrors
|
|
132
159
|
* {@link authGuard} without emitting a response.
|
|
133
160
|
*/
|
|
134
|
-
export async function isWsAuthorized(c, mode, auth) {
|
|
161
|
+
export async function isWsAuthorized(c, mode, auth, db) {
|
|
135
162
|
switch (mode) {
|
|
136
163
|
case "none":
|
|
137
164
|
return true;
|
|
@@ -140,7 +167,7 @@ export async function isWsAuthorized(c, mode, auth) {
|
|
|
140
167
|
case "proxy":
|
|
141
168
|
return hasProxyAuth(c, auth);
|
|
142
169
|
case "password":
|
|
143
|
-
return hasValidSession(c, auth);
|
|
170
|
+
return hasValidSession(c, auth, db);
|
|
144
171
|
}
|
|
145
172
|
}
|
|
146
173
|
// --- password mode helpers ---
|
|
@@ -149,9 +176,10 @@ export async function isWsAuthorized(c, mode, auth) {
|
|
|
149
176
|
* both password login and passkey login (middleware/passkeys.ts) call this, so
|
|
150
177
|
* authGuard / isWsAuthorized / TTL semantics stay identical across methods.
|
|
151
178
|
*/
|
|
152
|
-
export async function issueSessionCookie(c, auth) {
|
|
179
|
+
export async function issueSessionCookie(c, auth, db) {
|
|
153
180
|
const secret = auth.cookieSecret ?? "";
|
|
154
|
-
|
|
181
|
+
const epoch = sessionsEpoch(db);
|
|
182
|
+
await setSignedCookie(c, COOKIE_NAME, `${Date.now()}.${epoch}`, secret, {
|
|
155
183
|
httpOnly: true,
|
|
156
184
|
sameSite: "Strict",
|
|
157
185
|
// Always Secure — every real deployment serves over HTTPS, and we do not
|
|
@@ -162,26 +190,69 @@ export async function issueSessionCookie(c, auth) {
|
|
|
162
190
|
maxAge: SESSION_TTL_SECONDS,
|
|
163
191
|
});
|
|
164
192
|
}
|
|
165
|
-
async function hasValidSession(c, auth) {
|
|
193
|
+
async function hasValidSession(c, auth, db) {
|
|
166
194
|
const secret = auth.cookieSecret ?? "";
|
|
167
195
|
if (!secret)
|
|
168
196
|
return false;
|
|
197
|
+
let value;
|
|
169
198
|
try {
|
|
170
|
-
|
|
171
|
-
if (typeof value !== "string" || value.length === 0)
|
|
172
|
-
return false;
|
|
173
|
-
// The cookie value is the issue timestamp. Validate its age server-side:
|
|
174
|
-
// Max-Age is client-discardable, so the signature alone does not bound a
|
|
175
|
-
// session's lifetime — this does.
|
|
176
|
-
const issuedAt = Number(value);
|
|
177
|
-
if (!Number.isFinite(issuedAt))
|
|
178
|
-
return false;
|
|
179
|
-
const ageSeconds = (Date.now() - issuedAt) / 1000;
|
|
180
|
-
return ageSeconds >= 0 && ageSeconds < SESSION_TTL_SECONDS;
|
|
199
|
+
value = await getSignedCookie(c, secret, COOKIE_NAME);
|
|
181
200
|
}
|
|
182
201
|
catch {
|
|
183
202
|
return false;
|
|
184
203
|
}
|
|
204
|
+
if (typeof value !== "string" || value.length === 0)
|
|
205
|
+
return false;
|
|
206
|
+
// Both fields are decimal integers. Requiring the exact shape rejects every
|
|
207
|
+
// pre-epoch cookie instead of accidentally interpreting its timestamp as a
|
|
208
|
+
// current session.
|
|
209
|
+
const match = /^(\d+)\.(\d+)$/.exec(value);
|
|
210
|
+
if (!match)
|
|
211
|
+
return false;
|
|
212
|
+
const issuedAt = Number(match[1]);
|
|
213
|
+
const cookieEpoch = Number(match[2]);
|
|
214
|
+
if (!Number.isSafeInteger(issuedAt) || !Number.isSafeInteger(cookieEpoch)) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
const ageSeconds = (Date.now() - issuedAt) / 1000;
|
|
218
|
+
if (ageSeconds < 0 || ageSeconds >= SESSION_TTL_SECONDS)
|
|
219
|
+
return false;
|
|
220
|
+
// Deliberately outside the cookie-parser catch: corrupt authoritative auth
|
|
221
|
+
// state refuses loudly and must never degrade to epoch zero.
|
|
222
|
+
return cookieEpoch === sessionsEpoch(db);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Read authoritative session state. A missing row is first-run epoch zero;
|
|
226
|
+
* any present row that is not a non-negative safe integer is corruption.
|
|
227
|
+
*/
|
|
228
|
+
function sessionsEpoch(db) {
|
|
229
|
+
const row = db
|
|
230
|
+
.query("SELECT value FROM settings WHERE key = ?")
|
|
231
|
+
.get(SESSIONS_EPOCH_KEY);
|
|
232
|
+
if (!row)
|
|
233
|
+
return 0;
|
|
234
|
+
let value;
|
|
235
|
+
try {
|
|
236
|
+
value = JSON.parse(row.value);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
throw new Error(`Corrupt ${SESSIONS_EPOCH_KEY}: expected a JSON integer`);
|
|
240
|
+
}
|
|
241
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
242
|
+
throw new Error(`Corrupt ${SESSIONS_EPOCH_KEY}: expected a non-negative integer`);
|
|
243
|
+
}
|
|
244
|
+
return value;
|
|
245
|
+
}
|
|
246
|
+
/** Invalidate every issued session and disconnect every attached client. */
|
|
247
|
+
export function bumpSessionsEpoch(db, clients) {
|
|
248
|
+
const current = sessionsEpoch(db);
|
|
249
|
+
if (current === Number.MAX_SAFE_INTEGER) {
|
|
250
|
+
throw new Error(`${SESSIONS_EPOCH_KEY} cannot be advanced safely`);
|
|
251
|
+
}
|
|
252
|
+
const next = current + 1;
|
|
253
|
+
setSetting(db, SESSIONS_EPOCH_KEY, next);
|
|
254
|
+
clients.closeAll(SESSION_REVOKED_CLOSE_CODE, SESSION_REVOKED_CLOSE_REASON);
|
|
255
|
+
return next;
|
|
185
256
|
}
|
|
186
257
|
// --- proxy mode helpers ---
|
|
187
258
|
function hasProxyAuth(c, auth) {
|
|
@@ -195,63 +266,190 @@ function hasProxyAuth(c, auth) {
|
|
|
195
266
|
return !!user && user.trim().length > 0;
|
|
196
267
|
}
|
|
197
268
|
const loginBuckets = new Map();
|
|
269
|
+
function pruneExpiredBuckets(now) {
|
|
270
|
+
for (const [key, bucket] of loginBuckets) {
|
|
271
|
+
if (now >= bucket.resetAt)
|
|
272
|
+
loginBuckets.delete(key);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function makeBucketRoom() {
|
|
276
|
+
while (loginBuckets.size >= LOGIN_BUCKET_CAP) {
|
|
277
|
+
// Keep the global password bucket authoritative. The cap is larger than
|
|
278
|
+
// its maximum number of per-IP contributors in one window, so ordinary
|
|
279
|
+
// password traffic never needs to evict an active per-IP failure record.
|
|
280
|
+
const oldest = [...loginBuckets.keys()].find((key) => key !== PASSWORD_GLOBAL_BUCKET);
|
|
281
|
+
if (oldest === undefined)
|
|
282
|
+
break;
|
|
283
|
+
loginBuckets.delete(oldest);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function bucketForWrite(key, now) {
|
|
287
|
+
pruneExpiredBuckets(now);
|
|
288
|
+
const existing = loginBuckets.get(key);
|
|
289
|
+
if (existing)
|
|
290
|
+
return existing;
|
|
291
|
+
makeBucketRoom();
|
|
292
|
+
const bucket = { failures: 0, resetAt: now + LOGIN_RATE_WINDOW_MS };
|
|
293
|
+
loginBuckets.set(key, bucket);
|
|
294
|
+
return bucket;
|
|
295
|
+
}
|
|
296
|
+
/** Record one genuine authentication failure in a fixed one-minute window. */
|
|
297
|
+
export function recordLoginFailure(key, limit) {
|
|
298
|
+
const bucket = bucketForWrite(key, Date.now());
|
|
299
|
+
// Saturate: callers only care whether the limit was reached, and this avoids
|
|
300
|
+
// an unbounded counter if a test or future caller records after blocking.
|
|
301
|
+
bucket.failures = Math.min(limit, bucket.failures + 1);
|
|
302
|
+
}
|
|
303
|
+
/** Read without allocating: junk requests cannot grow the failure map. */
|
|
304
|
+
export function isLoginBlocked(key, limit) {
|
|
305
|
+
const now = Date.now();
|
|
306
|
+
const bucket = loginBuckets.get(key);
|
|
307
|
+
if (!bucket)
|
|
308
|
+
return false;
|
|
309
|
+
if (now >= bucket.resetAt) {
|
|
310
|
+
loginBuckets.delete(key);
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
return bucket.failures >= limit;
|
|
314
|
+
}
|
|
315
|
+
function createVerificationReservations(perIpLimit, globalLimit) {
|
|
316
|
+
const buckets = new Map();
|
|
317
|
+
let totalInFlight = 0;
|
|
318
|
+
function prune(now) {
|
|
319
|
+
for (const [key, bucket] of buckets) {
|
|
320
|
+
if (bucket.count === 0 && now >= bucket.expiresAt)
|
|
321
|
+
buckets.delete(key);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
acquire(ip) {
|
|
326
|
+
const now = Date.now();
|
|
327
|
+
prune(now);
|
|
328
|
+
if (totalInFlight >= globalLimit)
|
|
329
|
+
return false;
|
|
330
|
+
let bucket = buckets.get(ip);
|
|
331
|
+
if (bucket && bucket.count >= perIpLimit)
|
|
332
|
+
return false;
|
|
333
|
+
if (!bucket) {
|
|
334
|
+
while (buckets.size >= LOGIN_BUCKET_CAP) {
|
|
335
|
+
const idle = [...buckets].find(([, entry]) => entry.count === 0);
|
|
336
|
+
if (!idle)
|
|
337
|
+
return false;
|
|
338
|
+
buckets.delete(idle[0]);
|
|
339
|
+
}
|
|
340
|
+
bucket = { count: 0, expiresAt: now + LOGIN_RATE_WINDOW_MS };
|
|
341
|
+
buckets.set(ip, bucket);
|
|
342
|
+
}
|
|
343
|
+
bucket.count++;
|
|
344
|
+
bucket.expiresAt = now + LOGIN_RATE_WINDOW_MS;
|
|
345
|
+
totalInFlight++;
|
|
346
|
+
return true;
|
|
347
|
+
},
|
|
348
|
+
release(ip) {
|
|
349
|
+
const bucket = buckets.get(ip);
|
|
350
|
+
if (!bucket || bucket.count === 0)
|
|
351
|
+
return;
|
|
352
|
+
bucket.count--;
|
|
353
|
+
bucket.expiresAt = Date.now() + LOGIN_RATE_WINDOW_MS;
|
|
354
|
+
totalInFlight--;
|
|
355
|
+
},
|
|
356
|
+
reset() {
|
|
357
|
+
buckets.clear();
|
|
358
|
+
totalInFlight = 0;
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
const passwordVerifications = createVerificationReservations(PASSWORD_VERIFY_IN_FLIGHT_PER_IP, PASSWORD_VERIFY_IN_FLIGHT_GLOBAL);
|
|
363
|
+
const passkeyVerifications = createVerificationReservations(PASSKEY_VERIFY_IN_FLIGHT_PER_IP, PASSKEY_VERIFY_IN_FLIGHT_GLOBAL);
|
|
364
|
+
function acquirePasswordVerification(ip) {
|
|
365
|
+
return passwordVerifications.acquire(ip);
|
|
366
|
+
}
|
|
367
|
+
function releasePasswordVerification(ip) {
|
|
368
|
+
passwordVerifications.release(ip);
|
|
369
|
+
}
|
|
370
|
+
/** Internal middleware coordination; not exported from the package root. */
|
|
371
|
+
export function acquirePasskeyVerification(ip) {
|
|
372
|
+
return passkeyVerifications.acquire(ip);
|
|
373
|
+
}
|
|
374
|
+
/** Internal middleware coordination; not exported from the package root. */
|
|
375
|
+
export function releasePasskeyVerification(ip) {
|
|
376
|
+
passkeyVerifications.release(ip);
|
|
377
|
+
}
|
|
198
378
|
/** Test-only: clear all rate-limit buckets (they are module-global state). */
|
|
199
379
|
export function resetLoginRateLimiter() {
|
|
200
380
|
loginBuckets.clear();
|
|
381
|
+
passwordVerifications.reset();
|
|
382
|
+
passkeyVerifications.reset();
|
|
201
383
|
}
|
|
384
|
+
/** Attempt-counting bucket retained for passkey option generation. */
|
|
202
385
|
export function consumeLoginToken(key, limit) {
|
|
203
|
-
|
|
204
|
-
let bucket = loginBuckets.get(key);
|
|
205
|
-
if (!bucket || now >= bucket.resetAt) {
|
|
206
|
-
bucket = { tokens: limit, resetAt: now + LOGIN_RATE_WINDOW_MS };
|
|
207
|
-
loginBuckets.set(key, bucket);
|
|
208
|
-
}
|
|
209
|
-
if (bucket.tokens <= 0)
|
|
386
|
+
if (isLoginBlocked(key, limit))
|
|
210
387
|
return false;
|
|
211
|
-
|
|
388
|
+
recordLoginFailure(key, limit);
|
|
212
389
|
return true;
|
|
213
390
|
}
|
|
214
391
|
/** Login/logout routes. Only functional in `password` mode. */
|
|
215
|
-
export function authRoutes(mode, auth, deps
|
|
392
|
+
export function authRoutes(mode, auth, deps) {
|
|
216
393
|
const app = new Hono();
|
|
217
394
|
const { log, failures } = deps;
|
|
218
|
-
|
|
395
|
+
const verifyPassword = deps.verifyPassword ?? Bun.password.verify;
|
|
396
|
+
let warnedUntrustedForwardedFor = false;
|
|
397
|
+
app.post("/auth/login", requireJson(), async (c) => {
|
|
219
398
|
if (mode !== "password") {
|
|
220
399
|
return c.json({ error: "Password login is not enabled" }, 400);
|
|
221
400
|
}
|
|
401
|
+
if (!auth.trustProxy &&
|
|
402
|
+
!warnedUntrustedForwardedFor &&
|
|
403
|
+
c.req.header("x-forwarded-for")) {
|
|
404
|
+
warnedUntrustedForwardedFor = true;
|
|
405
|
+
log?.emit({
|
|
406
|
+
severityText: "WARN",
|
|
407
|
+
body: "X-Forwarded-For ignored in password mode",
|
|
408
|
+
attributes: { "auth.mode": "password", "auth.trust_proxy": false },
|
|
409
|
+
});
|
|
410
|
+
}
|
|
222
411
|
const key = clientIp(c, auth.trustProxy, auth.trustProxyHops) || "unknown";
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
412
|
+
const perIpBucket = `${PASSWORD_IP_BUCKET_PREFIX}${key}`;
|
|
413
|
+
if (deps.passwordDisabled?.(c)) {
|
|
414
|
+
return c.json({ error: "Password login is disabled — sign in with a passkey." }, 403);
|
|
415
|
+
}
|
|
416
|
+
// Refuse a blocked client before reading its body: admission control is
|
|
417
|
+
// cheapest when it costs no parsing.
|
|
418
|
+
const perIpBlocked = isLoginBlocked(perIpBucket, LOGIN_RATE_LIMIT);
|
|
419
|
+
const globalBlocked = isLoginBlocked(PASSWORD_GLOBAL_BUCKET, GLOBAL_LOGIN_RATE_LIMIT);
|
|
420
|
+
if (perIpBlocked || globalBlocked) {
|
|
226
421
|
failures?.add(1, { reason: "rate_limited", method: "password" });
|
|
227
422
|
log?.emit({
|
|
228
423
|
severityText: "WARN",
|
|
229
424
|
body: "login rate limited",
|
|
230
|
-
attributes: { ip: key, limit:
|
|
425
|
+
attributes: { ip: key, limit: perIpBlocked ? "ip" : "global" },
|
|
231
426
|
});
|
|
232
427
|
return c.json({ error: "Too many attempts. Try again in a minute." }, 429);
|
|
233
428
|
}
|
|
234
|
-
if (deps.passwordDisabled?.(c)) {
|
|
235
|
-
return c.json({ error: "Password login is disabled — sign in with a passkey." }, 403);
|
|
236
|
-
}
|
|
237
429
|
const hash = auth.passwordHash ?? "";
|
|
238
430
|
const secret = auth.cookieSecret ?? "";
|
|
239
431
|
let body;
|
|
240
432
|
try {
|
|
241
|
-
|
|
433
|
+
const result = await readJsonBody(c);
|
|
434
|
+
if (result instanceof Response)
|
|
435
|
+
return result;
|
|
436
|
+
body = result;
|
|
242
437
|
}
|
|
243
438
|
catch {
|
|
244
439
|
return c.json({ error: "Invalid request body" }, 400);
|
|
245
440
|
}
|
|
246
441
|
const password = typeof body.password === "string" ? body.password : "";
|
|
247
442
|
if (!password || !hash || !secret) {
|
|
248
|
-
|
|
443
|
+
return c.json({ error: "Invalid credentials" }, 401);
|
|
444
|
+
}
|
|
445
|
+
if (!acquirePasswordVerification(key)) {
|
|
446
|
+
failures?.add(1, { reason: "in_flight_limited", method: "password" });
|
|
249
447
|
log?.emit({
|
|
250
448
|
severityText: "WARN",
|
|
251
|
-
body: "
|
|
449
|
+
body: "password verification capacity reached",
|
|
252
450
|
attributes: { ip: key },
|
|
253
451
|
});
|
|
254
|
-
return c.json({ error: "
|
|
452
|
+
return c.json({ error: "Too many login verifications in progress." }, 429);
|
|
255
453
|
}
|
|
256
454
|
// A verify that THROWS is not a wrong password — it is a hash Bun cannot
|
|
257
455
|
// parse (a corrupt BRAIN_UI_PASSWORD_HASH locks the owner out of every
|
|
@@ -259,11 +457,14 @@ export function authRoutes(mode, auth, deps = {}) {
|
|
|
259
457
|
let ok = false;
|
|
260
458
|
let verifyError = null;
|
|
261
459
|
try {
|
|
262
|
-
ok = await
|
|
460
|
+
ok = await verifyPassword(password, hash);
|
|
263
461
|
}
|
|
264
462
|
catch (err) {
|
|
265
463
|
verifyError = err;
|
|
266
464
|
}
|
|
465
|
+
finally {
|
|
466
|
+
releasePasswordVerification(key);
|
|
467
|
+
}
|
|
267
468
|
if (verifyError) {
|
|
268
469
|
failures?.add(1, { reason: "verify_error", method: "password" });
|
|
269
470
|
log?.emit({
|
|
@@ -276,6 +477,8 @@ export function authRoutes(mode, auth, deps = {}) {
|
|
|
276
477
|
return c.json({ error: "Invalid credentials" }, 401);
|
|
277
478
|
}
|
|
278
479
|
if (!ok) {
|
|
480
|
+
recordLoginFailure(perIpBucket, LOGIN_RATE_LIMIT);
|
|
481
|
+
recordLoginFailure(PASSWORD_GLOBAL_BUCKET, GLOBAL_LOGIN_RATE_LIMIT);
|
|
279
482
|
failures?.add(1, { reason: "invalid_password", method: "password" });
|
|
280
483
|
log?.emit({
|
|
281
484
|
severityText: "WARN",
|
|
@@ -284,7 +487,7 @@ export function authRoutes(mode, auth, deps = {}) {
|
|
|
284
487
|
});
|
|
285
488
|
return c.json({ error: "Invalid credentials" }, 401);
|
|
286
489
|
}
|
|
287
|
-
await issueSessionCookie(c, auth);
|
|
490
|
+
await issueSessionCookie(c, auth, deps.db);
|
|
288
491
|
log?.emit({
|
|
289
492
|
severityText: "INFO",
|
|
290
493
|
body: "login succeeded",
|
|
@@ -292,7 +495,12 @@ export function authRoutes(mode, auth, deps = {}) {
|
|
|
292
495
|
});
|
|
293
496
|
return c.json({ ok: true });
|
|
294
497
|
});
|
|
295
|
-
app.post("/auth/logout", (c) => {
|
|
498
|
+
app.post("/auth/logout", async (c) => {
|
|
499
|
+
if (mode === "password" && !(await hasValidSession(c, auth, deps.db))) {
|
|
500
|
+
return c.json({ error: "Authentication required", authRequired: true }, 401);
|
|
501
|
+
}
|
|
502
|
+
if (mode === "password")
|
|
503
|
+
bumpSessionsEpoch(deps.db, deps.clients);
|
|
296
504
|
deleteCookie(c, COOKIE_NAME, { path: "/" });
|
|
297
505
|
return c.json({ ok: true });
|
|
298
506
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAmC9D,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,UAAU;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,CAAC,qCAAqC;AACxE,MAAM,oBAAoB,GAAG,MAAM,CAAC,CAAC,aAAa;AAClD,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,qDAAqD;AACrD,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC,CAAC,wCAAwC;AAEnF,MAAM,UAAU,eAAe,CAAC,IAAiB,EAAE,GAAY;IAC7D,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAChC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,GAAG,EAAE,IAAI,CAAC;YACR,YAAY,EAAE,MAAM;YACpB,IAAI,EAAE,2CAA2C;YACjD,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,YAAY;QAAE,OAAO,UAAU,CAAC;IACzC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,IAAiB,EAAE,GAAY;IAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,CAAC;IAEhF,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,0EAA0E;gBACxE,kFAAkF,CACrF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,0EAA0E;gBACxE,sEAAsE,CACzE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,uEAAuE;IACvE,2BAA2B;IAC3B,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,wEAAwE;YACxE,wEAAwE;YACxE,sDAAsD;YACtD,GAAG,EAAE,IAAI,CAAC;gBACR,YAAY,EAAE,OAAO;gBACrB,IAAI,EACF,oDAAoD;oBACpD,oEAAoE;oBACpE,kEAAkE;gBACpE,UAAU,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE;aAC1C,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CACb,0DAA0D;gBACxD,cAAc,IAAI,sDAAsD;gBACxE,0EAA0E;gBAC1E,kEAAkE;gBAClE,iEAAiE;gBACjE,sCAAsC,CACzC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,yEAAyE;gBACvE,sEAAsE;gBACtE,8DAA8D,CACjE,CAAC;QACJ,CAAC;QACD,GAAG,EAAE,IAAI,CAAC;YACR,YAAY,EAAE,MAAM;YACpB,IAAI,EACF,yEAAyE;gBACzE,qCAAqC;YACvC,UAAU,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE;SACnE,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,GAAG,EAAE,IAAI,CAAC;QACR,YAAY,EAAE,MAAM;QACpB,IAAI,EAAE,oBAAoB;QAC1B,UAAU,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;KAClC,CAAC,CAAC;AACL,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,SAAS,CAAC,IAAc,EAAE,IAAiB;IACzD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW;YACd,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;gBACvB,IAAI,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;oBAChE,MAAM,IAAI,EAAE,CAAC;gBACf,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC,CAAC;QACJ,KAAK,OAAO;YACV,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;gBACvB,IAAI,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;oBAC1B,MAAM,IAAI,EAAE,CAAC;gBACf,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,yBAAyB,EAAE,YAAY,EAAE,IAAI,EAAE,EACxD,GAAG,CACJ,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC;QACJ,KAAK,UAAU;YACb,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;gBACvB,IAAI,MAAM,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;oBACnC,MAAM,IAAI,EAAE,CAAC;gBACf,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,yBAAyB,EAAE,YAAY,EAAE,IAAI,EAAE,EACxD,GAAG,CACJ,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC;QACJ,KAAK,MAAM;YACT,OAAO,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;gBACxB,MAAM,IAAI,EAAE,CAAC;YACf,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,CAAU,EACV,IAAc,EACd,IAAiB;IAEjB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QACd,KAAK,WAAW;YACd,OAAO,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACrE,KAAK,OAAO;YACV,OAAO,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/B,KAAK,UAAU;YACb,OAAO,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED,gCAAgC;AAEhC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,CAAU,EAAE,IAAiB;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IACvC,MAAM,eAAe,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE;QAChE,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,QAAQ;QAClB,yEAAyE;QACzE,0EAA0E;QAC1E,qEAAqE;QACrE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,mBAAmB;KAC5B,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,CAAU,EAAE,IAAiB;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAClE,yEAAyE;QACzE,yEAAyE;QACzE,kCAAkC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7C,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;QAClD,OAAO,UAAU,IAAI,CAAC,IAAI,UAAU,GAAG,mBAAmB,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,6BAA6B;AAE7B,SAAS,YAAY,CAAC,CAAU,EAAE,IAAiB;IACjD,+EAA+E;IAC/E,6EAA6E;IAC7E,0EAA0E;IAC1E,4EAA4E;IAC5E,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAChD,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1C,CAAC;AAQD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE/C,8EAA8E;AAC9E,MAAM,UAAU,qBAAqB;IACnC,YAAY,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,KAAa;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,GAAG,oBAAoB,EAAE,CAAC;QAChE,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,CAAC,MAAM,EAAE,CAAC;IAChB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,UAAU,CACxB,IAAc,EACd,IAAiB,EACjB,OAYI,EAAE;IAEN,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE/B,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAClC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;QAC3E,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,QAAQ,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACjE,GAAG,EAAE,IAAI,CAAC;gBACR,YAAY,EAAE,MAAM;gBACpB,IAAI,EAAE,oBAAoB;gBAC1B,UAAU,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE;aAC1D,CAAC,CAAC;YACH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2CAA2C,EAAE,EAAE,GAAG,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,sDAAsD,EAAE,EACjE,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QACvC,IAAI,IAA4B,CAAC;QACjC,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,QAAQ,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACrE,GAAG,EAAE,IAAI,CAAC;gBACR,YAAY,EAAE,MAAM;gBACpB,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE;aACxB,CAAC,CAAC;YACH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC;QACvD,CAAC;QAED,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,IAAI,EAAE,GAAG,KAAK,CAAC;QACf,IAAI,WAAW,GAAY,IAAI,CAAC;QAChC,IAAI,CAAC;YACH,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,GAAG,GAAG,CAAC;QACpB,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YAChB,QAAQ,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACjE,GAAG,EAAE,IAAI,CAAC;gBACR,YAAY,EAAE,OAAO;gBACrB,IAAI,EAAE,8DAA8D;gBACpE,UAAU,EAAE;oBACV,KAAK,EAAE,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;iBAChF;aACF,CAAC,CAAC;YACH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,QAAQ,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACrE,GAAG,EAAE,IAAI,CAAC;gBACR,YAAY,EAAE,MAAM;gBACpB,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE;aACxB,CAAC,CAAC;YACH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAClC,GAAG,EAAE,IAAI,CAAC;YACR,YAAY,EAAE,MAAM;YACpB,IAAI,EAAE,iBAAiB;YACvB,UAAU,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE;SACxB,CAAC,CAAC;QACH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE;QAC7B,YAAY,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
|