@lastshotlabs/bunshot 0.0.25 → 0.0.27
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/dist/adapters/localStorage.js +20 -5
- package/dist/adapters/memoryAuth.d.ts +6 -0
- package/dist/adapters/memoryAuth.js +117 -2
- package/dist/adapters/mongoAuth.js +97 -1
- package/dist/adapters/sqliteAuth.d.ts +23 -0
- package/dist/adapters/sqliteAuth.js +153 -2
- package/dist/app.d.ts +105 -2
- package/dist/app.js +112 -9
- package/dist/index.d.ts +23 -4
- package/dist/index.js +13 -2
- package/dist/lib/HttpError.d.ts +2 -1
- package/dist/lib/HttpError.js +3 -1
- package/dist/lib/appConfig.d.ts +113 -0
- package/dist/lib/appConfig.js +38 -0
- package/dist/lib/auditLog.d.ts +6 -0
- package/dist/lib/auditLog.js +17 -0
- package/dist/lib/authAdapter.d.ts +71 -1
- package/dist/lib/authRateLimit.js +36 -0
- package/dist/lib/breachedPassword.d.ts +13 -0
- package/dist/lib/breachedPassword.js +48 -0
- package/dist/lib/captcha.d.ts +25 -0
- package/dist/lib/captcha.js +37 -0
- package/dist/lib/context.d.ts +5 -0
- package/dist/lib/credentialStuffing.d.ts +31 -0
- package/dist/lib/credentialStuffing.js +77 -0
- package/dist/lib/emailVerification.d.ts +6 -0
- package/dist/lib/emailVerification.js +46 -3
- package/dist/lib/jwks.d.ts +25 -0
- package/dist/lib/jwks.js +51 -0
- package/dist/lib/jwt.d.ts +15 -2
- package/dist/lib/jwt.js +92 -5
- package/dist/lib/logger.d.ts +2 -0
- package/dist/lib/logger.js +6 -0
- package/dist/lib/m2m.d.ts +29 -0
- package/dist/lib/m2m.js +48 -0
- package/dist/lib/mfaChallenge.d.ts +14 -1
- package/dist/lib/mfaChallenge.js +111 -6
- package/dist/lib/mongo.js +1 -1
- package/dist/lib/oauthCode.js +23 -18
- package/dist/lib/resetPassword.js +3 -1
- package/dist/lib/saml.d.ts +25 -0
- package/dist/lib/saml.js +64 -0
- package/dist/lib/scim.d.ts +44 -0
- package/dist/lib/scim.js +54 -0
- package/dist/lib/securityEvents.d.ts +28 -0
- package/dist/lib/securityEvents.js +26 -0
- package/dist/lib/session.d.ts +10 -0
- package/dist/lib/session.js +67 -5
- package/dist/lib/signing.js +5 -2
- package/dist/lib/suspension.d.ts +13 -0
- package/dist/lib/suspension.js +23 -0
- package/dist/lib/upload.d.ts +4 -0
- package/dist/lib/upload.js +26 -1
- package/dist/lib/uploadRegistry.d.ts +18 -0
- package/dist/lib/uploadRegistry.js +83 -0
- package/dist/lib/ws.js +7 -0
- package/dist/middleware/bearerAuth.js +1 -1
- package/dist/middleware/captcha.d.ts +10 -0
- package/dist/middleware/captcha.js +36 -0
- package/dist/middleware/csrf.js +8 -4
- package/dist/middleware/errorHandler.js +4 -1
- package/dist/middleware/identify.js +40 -13
- package/dist/middleware/requestSigning.js +6 -5
- package/dist/middleware/requireMfaSetup.js +2 -1
- package/dist/middleware/requireScope.d.ts +10 -0
- package/dist/middleware/requireScope.js +25 -0
- package/dist/middleware/requireStepUp.d.ts +18 -0
- package/dist/middleware/requireStepUp.js +29 -0
- package/dist/middleware/scimAuth.d.ts +8 -0
- package/dist/middleware/scimAuth.js +29 -0
- package/dist/middleware/webhookAuth.d.ts +1 -1
- package/dist/middleware/webhookAuth.js +6 -5
- package/dist/models/AuthUser.d.ts +7 -0
- package/dist/models/AuthUser.js +7 -0
- package/dist/models/M2MClient.d.ts +18 -0
- package/dist/models/M2MClient.js +18 -0
- package/dist/routes/auth.d.ts +3 -2
- package/dist/routes/auth.js +155 -16
- package/dist/routes/jobs.js +21 -3
- package/dist/routes/m2m.d.ts +2 -0
- package/dist/routes/m2m.js +72 -0
- package/dist/routes/metrics.d.ts +1 -0
- package/dist/routes/metrics.js +3 -0
- package/dist/routes/mfa.js +9 -1
- package/dist/routes/oauth.js +6 -0
- package/dist/routes/oidc.d.ts +2 -0
- package/dist/routes/oidc.js +29 -0
- package/dist/routes/passkey.d.ts +1 -0
- package/dist/routes/passkey.js +157 -0
- package/dist/routes/saml.d.ts +2 -0
- package/dist/routes/saml.js +86 -0
- package/dist/routes/scim.d.ts +2 -0
- package/dist/routes/scim.js +255 -0
- package/dist/routes/uploads.d.ts +13 -1
- package/dist/routes/uploads.js +98 -6
- package/dist/services/auth.d.ts +2 -0
- package/dist/services/auth.js +101 -22
- package/dist/services/mfa.js +2 -2
- package/dist/ws/index.js +2 -1
- package/docs/sections/auth-flow/full.md +790 -779
- package/docs/sections/auth-security-examples/full.md +23 -0
- package/docs/sections/metrics/full.md +6 -2
- package/docs/sections/passkey-login/full.md +90 -0
- package/docs/sections/passkey-login/overview.md +1 -0
- package/docs/sections/uploads/full.md +11 -2
- package/docs/sections/webhook-auth/full.md +1 -1
- package/docs/sections/websocket/full.md +12 -0
- package/package.json +3 -2
package/dist/app.d.ts
CHANGED
|
@@ -2,10 +2,12 @@ import { OpenAPIHono } from "@hono/zod-openapi";
|
|
|
2
2
|
import type { MiddlewareHandler } from "hono";
|
|
3
3
|
import type { AppEnv, ValidationErrorFormatter } from "./lib/context";
|
|
4
4
|
import type { RequestLogEntry, LogLevel } from "./middleware/requestLogger";
|
|
5
|
-
import type { PrimaryField, EmailVerificationConfig, PasswordResetConfig, PasswordPolicyConfig, RefreshTokenConfig, MfaConfig, MfaEmailOtpConfig, MfaWebAuthnConfig, SigningConfig } from "./lib/appConfig";
|
|
5
|
+
import type { PrimaryField, EmailVerificationConfig, PasswordResetConfig, PasswordPolicyConfig, RefreshTokenConfig, MfaConfig, MfaEmailOtpConfig, MfaWebAuthnConfig, SigningConfig, JwtConfig, BreachedPasswordConfig, StepUpConfig, M2MConfig, OidcConfig, SamlConfig, ScimConfig } from "./lib/appConfig";
|
|
6
|
+
import type { CaptchaConfig } from "./lib/captcha";
|
|
6
7
|
import type { AuthAdapter } from "./lib/authAdapter";
|
|
7
8
|
import type { OAuthProviderConfig } from "./lib/oauth";
|
|
8
9
|
type StoreType = "redis" | "mongo" | "sqlite" | "memory";
|
|
10
|
+
export type { BreachedPasswordConfig } from "./lib/appConfig";
|
|
9
11
|
export interface DbConfig {
|
|
10
12
|
/**
|
|
11
13
|
* Absolute path to the SQLite database file.
|
|
@@ -117,6 +119,22 @@ export interface AuthRateLimitConfig {
|
|
|
117
119
|
* Use "redis" for multi-instance deployments so limits are shared across servers.
|
|
118
120
|
*/
|
|
119
121
|
store?: "memory" | "redis";
|
|
122
|
+
/** Credential stuffing detection. Tracks distinct accounts per IP and IPs per account. */
|
|
123
|
+
credentialStuffing?: {
|
|
124
|
+
maxAccountsPerIp?: {
|
|
125
|
+
count: number;
|
|
126
|
+
windowMs: number;
|
|
127
|
+
};
|
|
128
|
+
maxIpsPerAccount?: {
|
|
129
|
+
count: number;
|
|
130
|
+
windowMs: number;
|
|
131
|
+
};
|
|
132
|
+
onDetected?: (signal: {
|
|
133
|
+
type: "ip" | "account";
|
|
134
|
+
key: string;
|
|
135
|
+
count: number;
|
|
136
|
+
}) => void;
|
|
137
|
+
};
|
|
120
138
|
}
|
|
121
139
|
export interface AuthConfig {
|
|
122
140
|
/** Set false to skip mounting /auth/* routes. Defaults to true */
|
|
@@ -173,6 +191,49 @@ export interface AuthConfig {
|
|
|
173
191
|
* OAuth logins skip MFA (the OAuth provider is treated as the second factor).
|
|
174
192
|
*/
|
|
175
193
|
mfa?: MfaConfig;
|
|
194
|
+
/**
|
|
195
|
+
* JWT claims configuration. When set, `iss`, `aud`, and `iat` are included in all tokens.
|
|
196
|
+
* Tokens with a non-matching issuer or audience will fail verification.
|
|
197
|
+
*
|
|
198
|
+
* - **`iss`** (issuer) and **`aud`** (audience) are validated on every token verification when
|
|
199
|
+
* configured. A token issued for a different issuer or intended for a different audience is
|
|
200
|
+
* rejected outright.
|
|
201
|
+
* - **`iat`** (issued-at) is always included in tokens once this config is set. Use it to detect
|
|
202
|
+
* token reuse or implement absolute expiry windows independent of `exp`.
|
|
203
|
+
*
|
|
204
|
+
* Recommended for fintech and multi-service deployments where tokens from one service should
|
|
205
|
+
* never be accepted by another.
|
|
206
|
+
* Use `algorithm: "RS256"` to enable OIDC mode.
|
|
207
|
+
*/
|
|
208
|
+
jwt?: JwtConfig;
|
|
209
|
+
/**
|
|
210
|
+
* When true, suspension status is checked on every authenticated request (via identify middleware).
|
|
211
|
+
* This adds one adapter call per request. Default: false.
|
|
212
|
+
* Suspension is always enforced at login time regardless of this setting.
|
|
213
|
+
*/
|
|
214
|
+
checkSuspensionOnIdentify?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Breached password detection using the HaveIBeenPwned k-Anonymity API.
|
|
217
|
+
* Checks passwords at registration and reset. No full hash leaves the server.
|
|
218
|
+
*/
|
|
219
|
+
breachedPasswordCheck?: BreachedPasswordConfig;
|
|
220
|
+
/**
|
|
221
|
+
* Step-up MFA configuration. When set, the requireStepUp() middleware and
|
|
222
|
+
* POST /auth/step-up endpoint are available. Requires auth.mfa to be configured.
|
|
223
|
+
*/
|
|
224
|
+
stepUp?: StepUpConfig;
|
|
225
|
+
/** M2M client credentials configuration. Enables POST /oauth/token with client_credentials grant. */
|
|
226
|
+
m2m?: M2MConfig;
|
|
227
|
+
/**
|
|
228
|
+
* OIDC discovery and RS256 JWT signing configuration.
|
|
229
|
+
* When set, mounts /.well-known/openid-configuration and /.well-known/jwks.json.
|
|
230
|
+
* Auto-generates an RSA-2048 key pair on startup if signingKey is not provided.
|
|
231
|
+
*/
|
|
232
|
+
oidc?: OidcConfig;
|
|
233
|
+
/** SAML 2.0 SSO configuration. Enables /auth/saml/* routes. Requires samlify peer dependency. */
|
|
234
|
+
saml?: SamlConfig;
|
|
235
|
+
/** SCIM 2.0 user provisioning. Enables /scim/v2/* endpoints with its own bearer token. */
|
|
236
|
+
scim?: ScimConfig;
|
|
176
237
|
}
|
|
177
238
|
export interface AccountDeletionConfig {
|
|
178
239
|
/** Called before deletion. Throw to abort (e.g., active subscription check). */
|
|
@@ -205,7 +266,8 @@ export interface AuthSessionPolicyConfig {
|
|
|
205
266
|
*/
|
|
206
267
|
trackLastActive?: boolean;
|
|
207
268
|
}
|
|
208
|
-
export type { PrimaryField, EmailVerificationConfig, PasswordResetConfig, RefreshTokenConfig, MfaConfig, MfaEmailOtpConfig, MfaWebAuthnConfig, SigningConfig };
|
|
269
|
+
export type { PrimaryField, EmailVerificationConfig, PasswordResetConfig, RefreshTokenConfig, MfaConfig, MfaEmailOtpConfig, MfaWebAuthnConfig, SigningConfig, JwtConfig, StepUpConfig, OidcConfig, SamlConfig, ScimConfig };
|
|
270
|
+
export type { CaptchaConfig, CaptchaProvider } from "./lib/captcha";
|
|
209
271
|
export interface BotProtectionConfig {
|
|
210
272
|
/**
|
|
211
273
|
* List of IPv4 CIDRs (e.g. "198.51.100.0/24"), IPv4 addresses, or IPv6 addresses to block outright.
|
|
@@ -273,6 +335,11 @@ export interface SecurityConfig {
|
|
|
273
335
|
* idempotency key hashing, and session binding. All features are opt-in.
|
|
274
336
|
*/
|
|
275
337
|
signing?: SigningConfig;
|
|
338
|
+
/**
|
|
339
|
+
* Global CAPTCHA configuration. When set, use requireCaptcha() middleware on specific routes,
|
|
340
|
+
* or enable adaptive mode to auto-require CAPTCHA after rate limit thresholds.
|
|
341
|
+
*/
|
|
342
|
+
captcha?: CaptchaConfig;
|
|
276
343
|
}
|
|
277
344
|
export interface ModelSchemasConfig {
|
|
278
345
|
/**
|
|
@@ -315,6 +382,12 @@ export interface JobsConfig {
|
|
|
315
382
|
allowedQueues?: string[];
|
|
316
383
|
/** When using userAuth, restrict job visibility to the user who created it. Default: false. */
|
|
317
384
|
scopeToUser?: boolean;
|
|
385
|
+
/**
|
|
386
|
+
* Explicitly acknowledge that jobs endpoint is public in production.
|
|
387
|
+
* Set to true only when auth is "none" and you understand the risk.
|
|
388
|
+
* Without this, createApp throws in production when auth is "none".
|
|
389
|
+
*/
|
|
390
|
+
unsafePublic?: boolean;
|
|
318
391
|
}
|
|
319
392
|
export interface TenantConfig {
|
|
320
393
|
[key: string]: unknown;
|
|
@@ -368,6 +441,12 @@ export interface MetricsConfig {
|
|
|
368
441
|
normalizePath?: (path: string) => string;
|
|
369
442
|
/** BullMQ queue names to report depth gauges for. */
|
|
370
443
|
queues?: string[];
|
|
444
|
+
/**
|
|
445
|
+
* Explicitly acknowledge that metrics endpoint is public in production.
|
|
446
|
+
* Set to true only when auth is "none" and you understand the risk.
|
|
447
|
+
* Without this, createApp throws in production when auth is "none".
|
|
448
|
+
*/
|
|
449
|
+
unsafePublic?: boolean;
|
|
371
450
|
}
|
|
372
451
|
export interface ValidationConfig {
|
|
373
452
|
/** Custom formatter for Zod validation errors. Receives issues + requestId, returns the JSON body. */
|
|
@@ -407,6 +486,24 @@ export interface UploadConfig {
|
|
|
407
486
|
}) => string;
|
|
408
487
|
tenantScopedKeys?: boolean;
|
|
409
488
|
presignedUrls?: boolean | PresignedUrlConfig;
|
|
489
|
+
/**
|
|
490
|
+
* Authorization callback for upload read/delete operations.
|
|
491
|
+
* Called when registry ownership check fails or key is not in registry.
|
|
492
|
+
*/
|
|
493
|
+
authorization?: {
|
|
494
|
+
authorize?: (input: {
|
|
495
|
+
action: "read" | "delete";
|
|
496
|
+
key: string;
|
|
497
|
+
userId?: string;
|
|
498
|
+
tenantId?: string;
|
|
499
|
+
}) => boolean | Promise<boolean>;
|
|
500
|
+
};
|
|
501
|
+
/**
|
|
502
|
+
* Allow operations on keys not in the upload registry.
|
|
503
|
+
* When false (default), operations on unknown keys return 404.
|
|
504
|
+
* When true, requires an authorize callback — denies if absent.
|
|
505
|
+
*/
|
|
506
|
+
allowExternalKeys?: boolean;
|
|
410
507
|
}
|
|
411
508
|
export interface CreateAppConfig {
|
|
412
509
|
/** Absolute path to the service's routes directory (use import.meta.dir + "/routes") */
|
|
@@ -452,5 +549,11 @@ export interface CreateAppConfig {
|
|
|
452
549
|
* `/{version}/docs`. Root `/docs` becomes a version selector.
|
|
453
550
|
*/
|
|
454
551
|
versioning?: VersioningConfig;
|
|
552
|
+
/**
|
|
553
|
+
* Security event streaming (SIEM integration). When set, auth and security events
|
|
554
|
+
* are emitted to the provided onEvent callback. Non-blocking — errors are swallowed.
|
|
555
|
+
* Use include/exclude to filter event types.
|
|
556
|
+
*/
|
|
557
|
+
securityEvents?: import("./lib/securityEvents").SecurityEventConfig;
|
|
455
558
|
}
|
|
456
559
|
export declare const createApp: (config: CreateAppConfig) => Promise<OpenAPIHono<AppEnv>>;
|
package/dist/app.js
CHANGED
|
@@ -10,7 +10,7 @@ import { defaultValidationErrorFormatter } from "./lib/context";
|
|
|
10
10
|
import { HEADER_USER_TOKEN, HEADER_REFRESH_TOKEN, HEADER_CSRF_TOKEN, HEADER_REQUEST_ID } from "./lib/constants";
|
|
11
11
|
import { requestId } from "./middleware/requestId";
|
|
12
12
|
import { requestLogger } from "./middleware/requestLogger";
|
|
13
|
-
import { setAppName, setAppRoles, setDefaultRole, setPrimaryField, setEmailVerificationConfig, setPasswordResetConfig, setPasswordPolicy, setMaxSessions, setPersistSessionMetadata, setIncludeInactiveSessions, setTrackLastActive, setRefreshTokenConfig, setMfaConfig, setCsrfEnabled, setSigningConfig } from "./lib/appConfig";
|
|
13
|
+
import { setAppName, setAppRoles, setDefaultRole, setPrimaryField, setEmailVerificationConfig, setPasswordResetConfig, setPasswordPolicy, setMaxSessions, setPersistSessionMetadata, setIncludeInactiveSessions, setTrackLastActive, setRefreshTokenConfig, setMfaConfig, setCsrfEnabled, setSigningConfig, setJwtConfig, setCheckSuspensionOnIdentify, setBreachedPasswordConfig, setCaptchaConfig, setStepUpConfig, setM2MConfig, setOidcConfig, setSamlConfig, setScimConfig } from "./lib/appConfig";
|
|
14
14
|
import { setEmailVerificationStore } from "./lib/emailVerification";
|
|
15
15
|
import { setPasswordResetStore } from "./lib/resetPassword";
|
|
16
16
|
import { setAuthRateLimitStore } from "./lib/authRateLimit";
|
|
@@ -25,10 +25,17 @@ import { setSessionStore } from "./lib/session";
|
|
|
25
25
|
import { setCacheStore } from "./middleware/cacheResponse";
|
|
26
26
|
import { maybeAutoRegister } from "./lib/createRoute";
|
|
27
27
|
import { setStorageAdapter, setUploadConfig } from "./lib/upload";
|
|
28
|
+
import { validateJwtSecrets } from "./lib/jwt";
|
|
28
29
|
export const createApp = async (config) => {
|
|
29
30
|
const { routesDir, app: appConfig = {}, auth: authConfig = {}, security: securityConfig = {}, middleware = [], db = {}, } = config;
|
|
31
|
+
if (config.securityEvents) {
|
|
32
|
+
const { setSecurityEventConfig } = await import("./lib/securityEvents");
|
|
33
|
+
setSecurityEventConfig(config.securityEvents);
|
|
34
|
+
}
|
|
30
35
|
const appName = appConfig.name ?? "Bun Core API";
|
|
31
36
|
const openApiVersion = appConfig.version ?? "1.0.0";
|
|
37
|
+
// Validate JWT secrets eagerly so misconfiguration is caught at startup
|
|
38
|
+
validateJwtSecrets();
|
|
32
39
|
// Trust-proxy for IP extraction
|
|
33
40
|
const { setTrustProxy } = await import("./lib/clientIp");
|
|
34
41
|
setTrustProxy(securityConfig.trustProxy ?? false);
|
|
@@ -36,6 +43,13 @@ export const createApp = async (config) => {
|
|
|
36
43
|
if (corsOrigins === "*" && process.env.NODE_ENV === "production") {
|
|
37
44
|
console.warn("[security] CORS is set to wildcard (*) in production. Configure security.cors with specific origins to restrict cross-origin access.");
|
|
38
45
|
}
|
|
46
|
+
if (securityConfig.csrf?.enabled && corsOrigins === "*") {
|
|
47
|
+
if (process.env.NODE_ENV === "production") {
|
|
48
|
+
throw new Error("[security] CSRF protection with wildcard CORS (*) is unsafe. " +
|
|
49
|
+
"Set security.cors to specific origins when using CSRF.");
|
|
50
|
+
}
|
|
51
|
+
console.warn("[security] CSRF is enabled with wildcard CORS. This will be rejected in production.");
|
|
52
|
+
}
|
|
39
53
|
const rlConfig = securityConfig.rateLimit ?? { windowMs: 60_000, max: 100 };
|
|
40
54
|
const botCfg = securityConfig.botProtection ?? {};
|
|
41
55
|
const enableBearerAuth = securityConfig.bearerAuth !== false;
|
|
@@ -142,12 +156,45 @@ export const createApp = async (config) => {
|
|
|
142
156
|
const { setDeletionCancelTokenStore } = await import("./lib/deletionCancelToken");
|
|
143
157
|
setDeletionCancelTokenStore(sessions);
|
|
144
158
|
setAuthRateLimitStore(authRateLimit?.store ?? (enableRedis ? "redis" : "memory"));
|
|
159
|
+
if (authRateLimit?.credentialStuffing) {
|
|
160
|
+
const { setCredentialStuffingConfig } = await import("./lib/credentialStuffing");
|
|
161
|
+
setCredentialStuffingConfig(authRateLimit.credentialStuffing);
|
|
162
|
+
}
|
|
145
163
|
setMaxSessions(sessionPolicy.maxSessions ?? 6);
|
|
146
164
|
setPersistSessionMetadata(sessionPolicy.persistSessionMetadata ?? true);
|
|
147
165
|
setIncludeInactiveSessions(sessionPolicy.includeInactiveSessions ?? false);
|
|
148
166
|
setTrackLastActive(sessionPolicy.trackLastActive ?? false);
|
|
149
167
|
setRefreshTokenConfig(authConfig.refreshTokens ?? null);
|
|
150
168
|
setMfaConfig(authConfig.mfa ?? null);
|
|
169
|
+
if (authConfig.jwt)
|
|
170
|
+
setJwtConfig(authConfig.jwt);
|
|
171
|
+
if (authConfig.checkSuspensionOnIdentify)
|
|
172
|
+
setCheckSuspensionOnIdentify(true);
|
|
173
|
+
if (authConfig.breachedPasswordCheck)
|
|
174
|
+
setBreachedPasswordConfig(authConfig.breachedPasswordCheck);
|
|
175
|
+
if (authConfig.stepUp)
|
|
176
|
+
setStepUpConfig(authConfig.stepUp);
|
|
177
|
+
// JWT config
|
|
178
|
+
if (authConfig.jwt)
|
|
179
|
+
setJwtConfig(authConfig.jwt);
|
|
180
|
+
// OIDC: load keys, set RS256, mount discovery routes
|
|
181
|
+
if (authConfig.oidc) {
|
|
182
|
+
setOidcConfig(authConfig.oidc);
|
|
183
|
+
// Override JWT config with OIDC issuer and RS256
|
|
184
|
+
setJwtConfig({ ...(authConfig.jwt ?? {}), issuer: authConfig.oidc.issuer, algorithm: "RS256" });
|
|
185
|
+
const { loadJwksKey, generateAndLoadKeyPair, loadPreviousKey } = await import("./lib/jwks");
|
|
186
|
+
const { _setAlgorithm } = await import("./lib/jwt");
|
|
187
|
+
if (authConfig.oidc.signingKey) {
|
|
188
|
+
await loadJwksKey(authConfig.oidc.signingKey);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
await generateAndLoadKeyPair();
|
|
192
|
+
}
|
|
193
|
+
for (const prev of authConfig.oidc.previousKeys ?? []) {
|
|
194
|
+
await loadPreviousKey(prev);
|
|
195
|
+
}
|
|
196
|
+
_setAlgorithm("RS256");
|
|
197
|
+
}
|
|
151
198
|
if (oauthProviders)
|
|
152
199
|
initOAuthProviders(oauthProviders);
|
|
153
200
|
const configuredOAuth = getConfiguredOAuthProviders();
|
|
@@ -183,7 +230,7 @@ export const createApp = async (config) => {
|
|
|
183
230
|
`/auth/${p}/callback`,
|
|
184
231
|
`/auth/${p}/link`,
|
|
185
232
|
]);
|
|
186
|
-
const DEFAULT_BYPASS = ["/docs", "/openapi.json", "/sw.js", "/health", "/", "/metrics"];
|
|
233
|
+
const DEFAULT_BYPASS = ["/docs", "/openapi.json", "/sw.js", "/health", "/", "/metrics", "/oauth/token", "/.well-known/openid-configuration", "/.well-known/jwks.json", "/auth/saml/*", "/scim/v2/*"];
|
|
187
234
|
// Add per-version docs/spec paths when versioning is configured
|
|
188
235
|
const versionBypass = config.versioning
|
|
189
236
|
? config.versioning.versions.flatMap((v) => [`/${v}/docs`, `/${v}/openapi.json`])
|
|
@@ -199,10 +246,12 @@ export const createApp = async (config) => {
|
|
|
199
246
|
});
|
|
200
247
|
// Metrics collection middleware (before requestLogger so it captures all requests)
|
|
201
248
|
if (config.metrics?.enabled) {
|
|
202
|
-
|
|
249
|
+
const metricsAuth = config.metrics.auth ?? "none";
|
|
250
|
+
if (metricsAuth === "none" && !config.metrics.unsafePublic) {
|
|
203
251
|
if (process.env.NODE_ENV === "production") {
|
|
204
|
-
|
|
252
|
+
throw new Error("[security] metrics.auth is required in production. Set metrics.auth or explicitly set unsafePublic: true with auth: \"none\".");
|
|
205
253
|
}
|
|
254
|
+
console.warn("[security] /metrics is enabled without auth. Configure metrics.auth for production.");
|
|
206
255
|
}
|
|
207
256
|
const { metricsCollector } = await import("./middleware/metrics");
|
|
208
257
|
app.use(metricsCollector({
|
|
@@ -247,7 +296,8 @@ export const createApp = async (config) => {
|
|
|
247
296
|
if (enableBearerAuth) {
|
|
248
297
|
app.use(async (c, next) => {
|
|
249
298
|
const path = c.req.path;
|
|
250
|
-
|
|
299
|
+
const bypassed = bearerAuthBypass.some((entry) => entry.endsWith("*") ? path.startsWith(entry.slice(0, -1)) : path === entry);
|
|
300
|
+
if (bypassed) {
|
|
251
301
|
return next();
|
|
252
302
|
}
|
|
253
303
|
return bearerAuth(c, next);
|
|
@@ -258,6 +308,10 @@ export const createApp = async (config) => {
|
|
|
258
308
|
if (securityConfig.signing) {
|
|
259
309
|
setSigningConfig(securityConfig.signing);
|
|
260
310
|
}
|
|
311
|
+
// CAPTCHA config — store globally so requireCaptcha() can read it without explicit param
|
|
312
|
+
if (securityConfig.captcha) {
|
|
313
|
+
setCaptchaConfig(securityConfig.captcha);
|
|
314
|
+
}
|
|
261
315
|
// CSRF protection (after identify so we can check for auth cookie presence)
|
|
262
316
|
if (securityConfig.csrf?.enabled) {
|
|
263
317
|
setCsrfEnabled(true);
|
|
@@ -343,13 +397,15 @@ export const createApp = async (config) => {
|
|
|
343
397
|
continue; // mounted separately below when mfa is configured
|
|
344
398
|
if (file === "jobs.ts")
|
|
345
399
|
continue; // mounted separately below when jobs.statusEndpoint is true
|
|
400
|
+
if (file === "oidc.ts")
|
|
401
|
+
continue; // mounted separately below when oidc is configured
|
|
346
402
|
const mod = await import(`${coreRoutesDir}/${file}`);
|
|
347
403
|
if (mod.router)
|
|
348
404
|
app.route("/", mod.router);
|
|
349
405
|
}
|
|
350
406
|
if (enableAuthRoutes) {
|
|
351
407
|
const { createAuthRouter } = await import(`${coreRoutesDir}/auth`);
|
|
352
|
-
app.route("/", createAuthRouter({ primaryField, emailVerification, passwordReset, rateLimit: authRateLimit, accountDeletion: authConfig.accountDeletion, refreshTokens: authConfig.refreshTokens }));
|
|
408
|
+
app.route("/", createAuthRouter({ primaryField, emailVerification, passwordReset, rateLimit: authRateLimit, accountDeletion: authConfig.accountDeletion, refreshTokens: authConfig.refreshTokens, stepUp: authConfig.stepUp }));
|
|
353
409
|
}
|
|
354
410
|
if (configuredOAuth.length > 0) {
|
|
355
411
|
const { createOAuthRouter } = await import(`${coreRoutesDir}/oauth`);
|
|
@@ -365,6 +421,26 @@ export const createApp = async (config) => {
|
|
|
365
421
|
const { createMfaRouter } = await import(`${coreRoutesDir}/mfa`);
|
|
366
422
|
app.route("/", createMfaRouter({ rateLimit: authRateLimit }));
|
|
367
423
|
}
|
|
424
|
+
if (authConfig.mfa?.webauthn?.allowPasswordlessLogin && enableAuthRoutes) {
|
|
425
|
+
const { assertWebAuthnDependency } = await import("./services/mfa");
|
|
426
|
+
await assertWebAuthnDependency();
|
|
427
|
+
const { createPasskeyRouter } = await import(`${coreRoutesDir}/passkey`);
|
|
428
|
+
app.route("/", createPasskeyRouter());
|
|
429
|
+
}
|
|
430
|
+
if (authConfig.m2m?.enabled !== false && authConfig.m2m) {
|
|
431
|
+
setM2MConfig(authConfig.m2m);
|
|
432
|
+
const { createM2MRouter } = await import(`${coreRoutesDir}/m2m`);
|
|
433
|
+
app.route("/", createM2MRouter());
|
|
434
|
+
}
|
|
435
|
+
if (config.jobs?.statusEndpoint) {
|
|
436
|
+
const jobsAuth = config.jobs.auth ?? "none";
|
|
437
|
+
if (jobsAuth === "none" && !config.jobs.unsafePublic) {
|
|
438
|
+
if (process.env.NODE_ENV === "production") {
|
|
439
|
+
throw new Error("[security] jobs.auth is required in production. Set jobs.auth or explicitly set unsafePublic: true with auth: \"none\".");
|
|
440
|
+
}
|
|
441
|
+
console.warn("[security] /jobs is enabled without auth. Configure jobs.auth for production.");
|
|
442
|
+
}
|
|
443
|
+
}
|
|
368
444
|
if (config.jobs?.statusEndpoint) {
|
|
369
445
|
const { createJobsRouter } = await import(`${coreRoutesDir}/jobs`);
|
|
370
446
|
app.route("/", createJobsRouter(config.jobs));
|
|
@@ -374,20 +450,44 @@ export const createApp = async (config) => {
|
|
|
374
450
|
app.route("/", createMetricsRouter({
|
|
375
451
|
auth: config.metrics.auth,
|
|
376
452
|
queues: config.metrics.queues,
|
|
453
|
+
unsafePublic: config.metrics.unsafePublic,
|
|
377
454
|
}));
|
|
378
455
|
}
|
|
379
456
|
if (config.groups?.managementRoutes) {
|
|
380
457
|
const { createGroupsRouter } = await import(`${coreRoutesDir}/groups`);
|
|
381
458
|
app.route("/", createGroupsRouter(config.groups));
|
|
382
459
|
}
|
|
460
|
+
if (authConfig.oidc) {
|
|
461
|
+
const { createOidcRouter } = await import(`${coreRoutesDir}/oidc`);
|
|
462
|
+
app.route("/", createOidcRouter());
|
|
463
|
+
}
|
|
464
|
+
if (authConfig.saml) {
|
|
465
|
+
setSamlConfig(authConfig.saml);
|
|
466
|
+
const { createSamlRouter } = await import(`${coreRoutesDir}/saml`);
|
|
467
|
+
app.route("/", createSamlRouter());
|
|
468
|
+
}
|
|
469
|
+
if (authConfig.scim) {
|
|
470
|
+
const { setScimTokens } = await import("./middleware/scimAuth");
|
|
471
|
+
setScimConfig(authConfig.scim);
|
|
472
|
+
setScimTokens(authConfig.scim.bearerTokens);
|
|
473
|
+
const { createScimRouter } = await import(`${coreRoutesDir}/scim`);
|
|
474
|
+
app.route("/", createScimRouter());
|
|
475
|
+
}
|
|
383
476
|
if (config.upload) {
|
|
384
|
-
const { storage, presignedUrls, ...uploadOpts } = config.upload;
|
|
477
|
+
const { storage, presignedUrls, authorization, allowExternalKeys, ...uploadOpts } = config.upload;
|
|
385
478
|
setStorageAdapter(storage);
|
|
386
479
|
setUploadConfig(uploadOpts);
|
|
480
|
+
// Wire upload registry store to match session store backend
|
|
481
|
+
const { setUploadRegistryStore } = await import("./lib/uploadRegistry");
|
|
482
|
+
setUploadRegistryStore(sessions);
|
|
387
483
|
if (presignedUrls) {
|
|
388
484
|
const { createUploadsRouter } = await import(`${coreRoutesDir}/uploads`);
|
|
389
485
|
const presignConfig = presignedUrls === true ? {} : presignedUrls;
|
|
390
|
-
app.route("/", createUploadsRouter(
|
|
486
|
+
app.route("/", createUploadsRouter({
|
|
487
|
+
...presignConfig,
|
|
488
|
+
authorization,
|
|
489
|
+
allowExternalKeys,
|
|
490
|
+
}));
|
|
391
491
|
}
|
|
392
492
|
}
|
|
393
493
|
// Helper to register standard security schemes on an OpenAPI registry
|
|
@@ -537,7 +637,10 @@ export const createApp = async (config) => {
|
|
|
537
637
|
}
|
|
538
638
|
}
|
|
539
639
|
if (err instanceof HttpError) {
|
|
540
|
-
|
|
640
|
+
const body = { error: err.message, requestId: reqId };
|
|
641
|
+
if (err.code !== undefined)
|
|
642
|
+
body.code = err.code;
|
|
643
|
+
return c.json(body, err.status);
|
|
541
644
|
}
|
|
542
645
|
console.error(err);
|
|
543
646
|
return c.json({ error: "Internal Server Error", requestId: reqId }, 500);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export { createApp } from "./app";
|
|
2
2
|
export { createServer } from "./server";
|
|
3
|
-
export type {
|
|
3
|
+
export type { SecurityEvent, SecurityEventType, SecurityEventConfig } from "./lib/securityEvents";
|
|
4
|
+
export { emitSecurityEvent, setSecurityEventConfig, getSecurityEventConfig } from "./lib/securityEvents";
|
|
5
|
+
export type { CreateAppConfig, ModelSchemasConfig, DbConfig, AppMeta, AuthConfig, AuthRateLimitConfig, AccountDeletionConfig, OAuthConfig, SecurityConfig, CsrfConfig, BotProtectionConfig, PrimaryField, EmailVerificationConfig, PasswordResetConfig, RefreshTokenConfig, MfaConfig, MfaEmailOtpConfig, MfaWebAuthnConfig, JobsConfig, TenancyConfig, TenantConfig, LoggingConfig, MetricsConfig, ValidationConfig, VersioningConfig, SigningConfig, JwtConfig, BreachedPasswordConfig, StepUpConfig, OidcConfig, SamlConfig, ScimConfig } from "./app";
|
|
6
|
+
export { setScimTokens } from "./middleware/scimAuth";
|
|
4
7
|
export type { PasswordPolicyConfig } from "./lib/appConfig";
|
|
8
|
+
export type { SamlProfile } from "./lib/saml";
|
|
5
9
|
export type { CreateServerConfig, WsConfig } from "./server";
|
|
6
10
|
export { appConnection, authConnection, mongoose, connectMongo, connectAuthMongo, connectAppMongo, disconnectMongo } from "./lib/mongo";
|
|
7
11
|
export { connectRedis, disconnectRedis, getRedis } from "./lib/redis";
|
|
@@ -18,6 +22,7 @@ export type { DtoMapperConfig } from "./lib/createDtoMapper";
|
|
|
18
22
|
export type { AppEnv, AppVariables, ValidationErrorFormatter, DefaultValidationErrorBody, ValidationErrorDetail } from "./lib/context";
|
|
19
23
|
export { defaultValidationErrorFormatter } from "./lib/context";
|
|
20
24
|
export { signToken, verifyToken } from "./lib/jwt";
|
|
25
|
+
export { getJwks, loadJwksKey, generateAndLoadKeyPair, isJwksLoaded } from "./lib/jwks";
|
|
21
26
|
export { log } from "./lib/logger";
|
|
22
27
|
export { createResetToken, consumeResetToken, setPasswordResetStore } from "./lib/resetPassword";
|
|
23
28
|
export { createDeletionCancelToken, consumeDeletionCancelToken, setDeletionCancelTokenStore } from "./lib/deletionCancelToken";
|
|
@@ -28,13 +33,15 @@ export type { IdempotencyOptions } from "./lib/idempotency";
|
|
|
28
33
|
export { getClientIp, setTrustProxy } from "./lib/clientIp";
|
|
29
34
|
export { storeOAuthCode, consumeOAuthCode, setOAuthCodeStore } from "./lib/oauthCode";
|
|
30
35
|
export type { OAuthCodePayload } from "./lib/oauthCode";
|
|
31
|
-
export { createSession, getSession, deleteSession, getUserSessions, getActiveSessionCount, evictOldestSession, updateSessionLastActive, setSessionStore, deleteUserSessions, setRefreshToken, getSessionByRefreshToken, rotateRefreshToken, getSessionFingerprint, setSessionFingerprint } from "./lib/session";
|
|
36
|
+
export { createSession, getSession, deleteSession, getUserSessions, getActiveSessionCount, evictOldestSession, updateSessionLastActive, setSessionStore, deleteUserSessions, setRefreshToken, getSessionByRefreshToken, rotateRefreshToken, getSessionFingerprint, setSessionFingerprint, setMfaVerifiedAt, getMfaVerifiedAt } from "./lib/session";
|
|
32
37
|
export type { SessionMetadata, SessionInfo, RefreshResult } from "./lib/session";
|
|
33
38
|
export { createVerificationToken, getVerificationToken, deleteVerificationToken } from "./lib/emailVerification";
|
|
34
39
|
export { createMfaChallenge, consumeMfaChallenge, replaceMfaChallengeOtp, setMfaChallengeStore, createWebAuthnRegistrationChallenge, consumeWebAuthnRegistrationChallenge, clearMemoryMfaChallenges } from "./lib/mfaChallenge";
|
|
35
40
|
export type { MfaChallengeData, MfaChallengeOptions, MfaChallengePurpose } from "./lib/mfaChallenge";
|
|
36
41
|
export { bustAuthLimit, trackAttempt, isLimited, clearMemoryRateLimitStore } from "./lib/authRateLimit";
|
|
37
42
|
export type { LimitOpts } from "./lib/authRateLimit";
|
|
43
|
+
export { trackFailedLogin, isStuffingBlocked, setCredentialStuffingConfig, clearCredentialStuffingStore } from "./lib/credentialStuffing";
|
|
44
|
+
export type { CredentialStuffingConfig } from "./lib/credentialStuffing";
|
|
38
45
|
export { validate } from "./lib/validate";
|
|
39
46
|
export { bearerAuth } from "./middleware/bearerAuth";
|
|
40
47
|
export { botProtection } from "./middleware/botProtection";
|
|
@@ -46,6 +53,8 @@ export { userAuth } from "./middleware/userAuth";
|
|
|
46
53
|
export { requireRole } from "./middleware/requireRole";
|
|
47
54
|
export { requireVerifiedEmail } from "./middleware/requireVerifiedEmail";
|
|
48
55
|
export { requireMfaSetup } from "./middleware/requireMfaSetup";
|
|
56
|
+
export { requireStepUp } from "./middleware/requireStepUp";
|
|
57
|
+
export type { StepUpOptions } from "./middleware/requireStepUp";
|
|
49
58
|
export { csrfProtection, refreshCsrfToken, clearCsrfToken } from "./middleware/csrf";
|
|
50
59
|
export type { CsrfMiddlewareOptions } from "./middleware/csrf";
|
|
51
60
|
export { cacheResponse, bustCache, bustCachePattern, setCacheStore, getCacheModel } from "./middleware/cacheResponse";
|
|
@@ -60,6 +69,13 @@ export { requestLogger } from "./middleware/requestLogger";
|
|
|
60
69
|
export type { RequestLogEntry, RequestLoggerOptions, LogLevel } from "./middleware/requestLogger";
|
|
61
70
|
export { metricsCollector } from "./middleware/metrics";
|
|
62
71
|
export type { MetricsMiddlewareOptions } from "./middleware/metrics";
|
|
72
|
+
export { requireCaptcha } from "./middleware/captcha";
|
|
73
|
+
export type { CaptchaConfig, CaptchaProvider } from "./lib/captcha";
|
|
74
|
+
export { verifyCaptcha } from "./lib/captcha";
|
|
75
|
+
export { requireScope } from "./middleware/requireScope";
|
|
76
|
+
export { createM2MClient, deleteM2MClient, listM2MClients, getM2MClient } from "./lib/m2m";
|
|
77
|
+
export type { M2MClientRecord } from "./lib/authAdapter";
|
|
78
|
+
export type { M2MConfig } from "./lib/appConfig";
|
|
63
79
|
export { buildFingerprint } from "./lib/fingerprint";
|
|
64
80
|
export { logAuditEntry, getAuditLogs, clearAuditLogMemoryStore } from "./lib/auditLog";
|
|
65
81
|
export { resetMetrics, incrementCounter, observeHistogram, registerGaugeCallback, serializeMetrics, closeMetricsQueues } from "./lib/metrics";
|
|
@@ -67,7 +83,8 @@ export type { AuditLogEntry, AuditLogOptions, AuditLogQuery } from "./lib/auditL
|
|
|
67
83
|
export { sqliteAuthAdapter, setSqliteDb, startSqliteCleanup } from "./adapters/sqliteAuth";
|
|
68
84
|
export { memoryAuthAdapter, clearMemoryStore } from "./adapters/memoryAuth";
|
|
69
85
|
export { setUserRoles, addUserRole, removeUserRole, getTenantRoles, setTenantRoles, addTenantRole, removeTenantRole } from "./lib/roles";
|
|
70
|
-
export
|
|
86
|
+
export { setSuspended, getSuspended } from "./lib/suspension";
|
|
87
|
+
export type { AuthAdapter, OAuthProfile, IdentityProfile, UserRecord, UserQuery, WebAuthnCredential } from "./lib/authAdapter";
|
|
71
88
|
export type { OAuthProviderConfig } from "./lib/oauth";
|
|
72
89
|
export { websocket, createWsUpgradeHandler } from "./ws/index";
|
|
73
90
|
export type { SocketData } from "./ws/index";
|
|
@@ -87,8 +104,10 @@ export { offsetParams, parseOffsetParams, paginatedResponse, cursorParams, parse
|
|
|
87
104
|
export type { OffsetParamDefaults, ParsedOffsetParams, CursorParamDefaults, ParsedCursorParams, CursorResult, } from "./lib/pagination";
|
|
88
105
|
export { handleUpload } from "./middleware/upload";
|
|
89
106
|
export type { UploadMiddlewareOptions } from "./middleware/upload";
|
|
90
|
-
export { parseUpload, setStorageAdapter, getStorageAdapter, setUploadConfig, getUploadConfig } from "./lib/upload";
|
|
107
|
+
export { parseUpload, setStorageAdapter, getStorageAdapter, setUploadConfig, getUploadConfig, generateUploadKeyFromFilename } from "./lib/upload";
|
|
91
108
|
export type { UploadOpts } from "./lib/upload";
|
|
109
|
+
export { setUploadRegistryStore, clearUploadRegistry, registerUpload, getUploadRecord, deleteUploadRecord } from "./lib/uploadRegistry";
|
|
110
|
+
export type { UploadRecord } from "./lib/uploadRegistry";
|
|
92
111
|
export type { StorageAdapter, UploadResult } from "./lib/storageAdapter";
|
|
93
112
|
export type { UploadConfig, PresignedUrlConfig } from "./app";
|
|
94
113
|
export { memoryStorage, clearMemoryUploadStore } from "./adapters/memoryStorage";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// App factory
|
|
2
2
|
export { createApp } from "./app";
|
|
3
3
|
export { createServer } from "./server";
|
|
4
|
+
export { emitSecurityEvent, setSecurityEventConfig, getSecurityEventConfig } from "./lib/securityEvents";
|
|
5
|
+
export { setScimTokens } from "./middleware/scimAuth";
|
|
4
6
|
// Database
|
|
5
7
|
export { appConnection, authConnection, mongoose, connectMongo, connectAuthMongo, connectAppMongo, disconnectMongo } from "./lib/mongo";
|
|
6
8
|
export { connectRedis, disconnectRedis, getRedis } from "./lib/redis";
|
|
@@ -15,6 +17,7 @@ export { zodToMongoose } from "./lib/zodToMongoose";
|
|
|
15
17
|
export { createDtoMapper } from "./lib/createDtoMapper";
|
|
16
18
|
export { defaultValidationErrorFormatter } from "./lib/context";
|
|
17
19
|
export { signToken, verifyToken } from "./lib/jwt";
|
|
20
|
+
export { getJwks, loadJwksKey, generateAndLoadKeyPair, isJwksLoaded } from "./lib/jwks";
|
|
18
21
|
export { log } from "./lib/logger";
|
|
19
22
|
export { createResetToken, consumeResetToken, setPasswordResetStore } from "./lib/resetPassword";
|
|
20
23
|
export { createDeletionCancelToken, consumeDeletionCancelToken, setDeletionCancelTokenStore } from "./lib/deletionCancelToken";
|
|
@@ -23,10 +26,11 @@ export { hmacSign, hmacVerify, signCookieValue, verifyCookieValue, signCursor, v
|
|
|
23
26
|
export { idempotent, setIdempotencyStore, clearIdempotencyMemoryStore } from "./lib/idempotency";
|
|
24
27
|
export { getClientIp, setTrustProxy } from "./lib/clientIp";
|
|
25
28
|
export { storeOAuthCode, consumeOAuthCode, setOAuthCodeStore } from "./lib/oauthCode";
|
|
26
|
-
export { createSession, getSession, deleteSession, getUserSessions, getActiveSessionCount, evictOldestSession, updateSessionLastActive, setSessionStore, deleteUserSessions, setRefreshToken, getSessionByRefreshToken, rotateRefreshToken, getSessionFingerprint, setSessionFingerprint } from "./lib/session";
|
|
29
|
+
export { createSession, getSession, deleteSession, getUserSessions, getActiveSessionCount, evictOldestSession, updateSessionLastActive, setSessionStore, deleteUserSessions, setRefreshToken, getSessionByRefreshToken, rotateRefreshToken, getSessionFingerprint, setSessionFingerprint, setMfaVerifiedAt, getMfaVerifiedAt } from "./lib/session";
|
|
27
30
|
export { createVerificationToken, getVerificationToken, deleteVerificationToken } from "./lib/emailVerification";
|
|
28
31
|
export { createMfaChallenge, consumeMfaChallenge, replaceMfaChallengeOtp, setMfaChallengeStore, createWebAuthnRegistrationChallenge, consumeWebAuthnRegistrationChallenge, clearMemoryMfaChallenges } from "./lib/mfaChallenge";
|
|
29
32
|
export { bustAuthLimit, trackAttempt, isLimited, clearMemoryRateLimitStore } from "./lib/authRateLimit";
|
|
33
|
+
export { trackFailedLogin, isStuffingBlocked, setCredentialStuffingConfig, clearCredentialStuffingStore } from "./lib/credentialStuffing";
|
|
30
34
|
export { validate } from "./lib/validate";
|
|
31
35
|
// Middleware
|
|
32
36
|
export { bearerAuth } from "./middleware/bearerAuth";
|
|
@@ -37,6 +41,7 @@ export { userAuth } from "./middleware/userAuth";
|
|
|
37
41
|
export { requireRole } from "./middleware/requireRole";
|
|
38
42
|
export { requireVerifiedEmail } from "./middleware/requireVerifiedEmail";
|
|
39
43
|
export { requireMfaSetup } from "./middleware/requireMfaSetup";
|
|
44
|
+
export { requireStepUp } from "./middleware/requireStepUp";
|
|
40
45
|
export { csrfProtection, refreshCsrfToken, clearCsrfToken } from "./middleware/csrf";
|
|
41
46
|
export { cacheResponse, bustCache, bustCachePattern, setCacheStore, getCacheModel } from "./middleware/cacheResponse";
|
|
42
47
|
export { webhookAuth } from "./middleware/webhookAuth";
|
|
@@ -45,6 +50,10 @@ export { auditLog } from "./middleware/auditLog";
|
|
|
45
50
|
export { requestId } from "./middleware/requestId";
|
|
46
51
|
export { requestLogger } from "./middleware/requestLogger";
|
|
47
52
|
export { metricsCollector } from "./middleware/metrics";
|
|
53
|
+
export { requireCaptcha } from "./middleware/captcha";
|
|
54
|
+
export { verifyCaptcha } from "./lib/captcha";
|
|
55
|
+
export { requireScope } from "./middleware/requireScope";
|
|
56
|
+
export { createM2MClient, deleteM2MClient, listM2MClients, getM2MClient } from "./lib/m2m";
|
|
48
57
|
// Lib utilities (bot protection)
|
|
49
58
|
export { buildFingerprint } from "./lib/fingerprint";
|
|
50
59
|
export { logAuditEntry, getAuditLogs, clearAuditLogMemoryStore } from "./lib/auditLog";
|
|
@@ -53,6 +62,7 @@ export { resetMetrics, incrementCounter, observeHistogram, registerGaugeCallback
|
|
|
53
62
|
export { sqliteAuthAdapter, setSqliteDb, startSqliteCleanup } from "./adapters/sqliteAuth";
|
|
54
63
|
export { memoryAuthAdapter, clearMemoryStore } from "./adapters/memoryAuth";
|
|
55
64
|
export { setUserRoles, addUserRole, removeUserRole, getTenantRoles, setTenantRoles, addTenantRole, removeTenantRole } from "./lib/roles";
|
|
65
|
+
export { setSuspended, getSuspended } from "./lib/suspension";
|
|
56
66
|
// WebSocket
|
|
57
67
|
export { websocket, createWsUpgradeHandler } from "./ws/index";
|
|
58
68
|
export { publish, subscribe, unsubscribe, getSubscriptions, handleRoomActions, getRooms, getRoomSubscribers, setPresenceEnabled } from "./lib/ws";
|
|
@@ -71,7 +81,8 @@ export { createGroup, deleteGroup, getGroup, listGroups, updateGroup, addGroupMe
|
|
|
71
81
|
export { offsetParams, parseOffsetParams, paginatedResponse, cursorParams, parseCursorParams, cursorResponse, maybeSignCursor, } from "./lib/pagination";
|
|
72
82
|
// Upload
|
|
73
83
|
export { handleUpload } from "./middleware/upload";
|
|
74
|
-
export { parseUpload, setStorageAdapter, getStorageAdapter, setUploadConfig, getUploadConfig } from "./lib/upload";
|
|
84
|
+
export { parseUpload, setStorageAdapter, getStorageAdapter, setUploadConfig, getUploadConfig, generateUploadKeyFromFilename } from "./lib/upload";
|
|
85
|
+
export { setUploadRegistryStore, clearUploadRegistry, registerUpload, getUploadRecord, deleteUploadRecord } from "./lib/uploadRegistry";
|
|
75
86
|
export { memoryStorage, clearMemoryUploadStore } from "./adapters/memoryStorage";
|
|
76
87
|
export { localStorage } from "./adapters/localStorage";
|
|
77
88
|
export { s3Storage } from "./adapters/s3Storage";
|
package/dist/lib/HttpError.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare class HttpError extends Error {
|
|
2
2
|
status: number;
|
|
3
|
-
|
|
3
|
+
code?: string | undefined;
|
|
4
|
+
constructor(status: number, message: string, code?: string | undefined);
|
|
4
5
|
}
|
|
5
6
|
import type { ZodIssue } from "zod";
|
|
6
7
|
export declare class ValidationError extends HttpError {
|
package/dist/lib/HttpError.js
CHANGED