@cosmicdrift/kumiko-framework 0.383.1 → 0.385.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.
Files changed (82) hide show
  1. package/agents/examples/custom-fields-basic.md +13 -3
  2. package/agents/examples/designer-demo.md +6 -2
  3. package/agents/examples/i18n.md +36 -1
  4. package/agents/features.md +4 -0
  5. package/dist/api/auth-rate-limiters.d.ts +8 -0
  6. package/dist/api/auth-rate-limiters.js +105 -0
  7. package/dist/api/auth-routes-context.d.ts +34 -0
  8. package/dist/api/auth-routes-context.js +192 -0
  9. package/dist/api/auth-routes-invite.d.ts +2 -0
  10. package/dist/api/auth-routes-invite.js +171 -0
  11. package/dist/api/auth-routes-login.d.ts +2 -0
  12. package/dist/api/auth-routes-login.js +103 -0
  13. package/dist/api/auth-routes-mfa.d.ts +4 -0
  14. package/dist/api/auth-routes-mfa.js +211 -0
  15. package/dist/api/auth-routes-session.d.ts +2 -0
  16. package/dist/api/auth-routes-session.js +144 -0
  17. package/dist/api/auth-routes-shared.d.ts +33 -0
  18. package/dist/api/auth-routes-shared.js +81 -0
  19. package/dist/api/auth-routes-signup.d.ts +2 -0
  20. package/dist/api/auth-routes-signup.js +75 -0
  21. package/dist/api/auth-routes-token-flows.d.ts +4 -0
  22. package/dist/api/auth-routes-token-flows.js +91 -0
  23. package/dist/api/auth-routes-types.d.ts +76 -0
  24. package/dist/api/auth-routes-types.js +1 -0
  25. package/dist/api/auth-routes.d.ts +5 -85
  26. package/dist/api/auth-routes.js +20 -1095
  27. package/dist/config/index.d.ts +1 -1
  28. package/dist/crypto/pii-ciphertext-format.js +1 -1
  29. package/dist/db/blind-index-cleanup.js +1 -1
  30. package/dist/db/dialect.js +1 -1
  31. package/dist/db/distinct-on.d.ts +9 -0
  32. package/dist/db/distinct-on.js +28 -0
  33. package/dist/db/event-store-executor-write.js +2 -2
  34. package/dist/db/migrate-runner.js +4 -4
  35. package/dist/db/pg-error.js +0 -12
  36. package/dist/db/queries/event-consumer.js +3 -3
  37. package/dist/db/queries/postgres-array-literal.js +2 -2
  38. package/dist/db/query.js +48 -20
  39. package/dist/db/tenant-db.js +1 -1
  40. package/dist/engine/boot-validator/i18n-keys.d.ts +2 -0
  41. package/dist/engine/boot-validator/i18n-keys.js +15 -1
  42. package/dist/engine/boot-validator/index.d.ts +4 -0
  43. package/dist/engine/boot-validator/index.js +3 -1
  44. package/dist/engine/boot-validator/pii-retention.js +6 -7
  45. package/dist/engine/boot-validator/screens-actions.d.ts +67 -0
  46. package/dist/engine/boot-validator/screens-actions.js +488 -0
  47. package/dist/engine/boot-validator/screens-dashboard.d.ts +15 -0
  48. package/dist/engine/boot-validator/screens-dashboard.js +467 -0
  49. package/dist/engine/boot-validator/screens-forms.d.ts +24 -0
  50. package/dist/engine/boot-validator/screens-forms.js +516 -0
  51. package/dist/engine/boot-validator/screens-lists.d.ts +47 -0
  52. package/dist/engine/boot-validator/screens-lists.js +319 -0
  53. package/dist/engine/boot-validator/screens.d.ts +4 -21
  54. package/dist/engine/boot-validator/screens.js +26 -1799
  55. package/dist/engine/build-app-schema.js +1 -1
  56. package/dist/engine/factories.d.ts +3 -3
  57. package/dist/engine/steps/read-find-one.js +1 -1
  58. package/dist/engine/types/index.d.ts +1 -1
  59. package/dist/event-store/provenance-append.js +1 -1
  60. package/dist/files/file-ref-entity.d.ts +6 -126
  61. package/dist/files/file-ref-table.d.ts +6 -126
  62. package/dist/files/file-routes.js +39 -16
  63. package/dist/i18n/required-surface-keys.d.ts +22 -2
  64. package/dist/i18n/required-surface-keys.js +91 -3
  65. package/dist/jobs/job-runner-helpers.d.ts +45 -0
  66. package/dist/jobs/job-runner-helpers.js +281 -0
  67. package/dist/jobs/job-runner-schedulers.d.ts +23 -0
  68. package/dist/jobs/job-runner-schedulers.js +106 -0
  69. package/dist/jobs/job-runner-types.d.ts +65 -0
  70. package/dist/jobs/job-runner-types.js +2 -0
  71. package/dist/jobs/job-runner.d.ts +4 -75
  72. package/dist/jobs/job-runner.js +7 -384
  73. package/dist/pipeline/dispatch-shared.js +2 -2
  74. package/dist/pipeline/event-dispatcher-admin.d.ts +15 -8
  75. package/dist/pipeline/event-dispatcher-admin.js +28 -7
  76. package/dist/pipeline/event-dispatcher.d.ts +2 -2
  77. package/dist/pipeline/event-dispatcher.js +3 -4
  78. package/dist/pipeline/index.d.ts +2 -2
  79. package/dist/pipeline/index.js +1 -1
  80. package/dist/schema-cli.js +5 -0
  81. package/package.json +3 -3
  82. package/src/changes.json +39 -0
@@ -0,0 +1,33 @@
1
+ import type { Context, Hono } from "hono";
2
+ import * as z from "zod";
3
+ import type { Dispatcher } from "../pipeline/dispatcher.ts";
4
+ export type PublicAuthErrorStatus = 400 | 401 | 403 | 422 | 429 | 500;
5
+ export declare const SignupRequestBody: z.ZodObject<{
6
+ email: z.ZodEmail;
7
+ handover: z.ZodOptional<z.ZodObject<{
8
+ entityType: z.ZodString;
9
+ token: z.ZodString;
10
+ }, z.core.$strip>>;
11
+ }, z.core.$strip>;
12
+ export declare function isUnknownHandlerError(e: unknown): boolean;
13
+ export type PendingMfaStep = {
14
+ kind: "mfa-challenge";
15
+ challengeToken: string;
16
+ } | {
17
+ kind: "mfa-setup-required";
18
+ preauthSetupToken: string;
19
+ };
20
+ export declare function pendingMfaStepResponse(c: Context, step: PendingMfaStep, landing?: {
21
+ readonly landingPath?: string;
22
+ }): Response;
23
+ export declare function registerTokenRequestRoute(opts: {
24
+ api: Hono;
25
+ dispatcher: Dispatcher;
26
+ path: string;
27
+ requestHandler: string;
28
+ schema?: typeof RequestTokenBody | typeof SignupRequestBody;
29
+ }): void;
30
+ declare const RequestTokenBody: z.ZodObject<{
31
+ email: z.ZodEmail;
32
+ }, z.core.$strip>;
33
+ export {};
@@ -0,0 +1,81 @@
1
+ import * as z from "zod";
2
+ import { createAnonymousUser } from "../engine/system-user.js";
3
+ import { SYSTEM_TENANT_ID } from "../engine/types/index.js";
4
+ import { NotFoundError } from "../errors/index.js";
5
+ // Cross-device try-first handover (kumiko-framework#3035 follow-up,
6
+ // offlot-app#454): an optional tenant-handover grant the signup-request
7
+ // route forwards to the handler for server-side verification and binding —
8
+ // the grant itself never appears anywhere else (URL, mail, log, response).
9
+ export const SignupRequestBody = z.object({
10
+ email: z.email(),
11
+ handover: z
12
+ .object({
13
+ entityType: z.string().min(1).max(200),
14
+ token: z.string().min(1).max(4096),
15
+ })
16
+ .optional(),
17
+ });
18
+ // Shape guard for "handler not registered" — the only legitimate reason to
19
+ // fall back to a single-tenant reply on /auth/tenants or /auth/switch-tenant.
20
+ // Every other error (DB down, revoker throws, access denied, …) has to
21
+ // propagate — otherwise we'd silently paper over outages.
22
+ export function isUnknownHandlerError(e) {
23
+ if (!(e instanceof NotFoundError))
24
+ return false;
25
+ // @cast-boundary error-details — KumikoError.details shape is per-error
26
+ const details = e.details;
27
+ return details?.entity === "handler";
28
+ }
29
+ export function pendingMfaStepResponse(c, step, landing = {}) {
30
+ if (step.kind === "mfa-setup-required") {
31
+ return c.json({
32
+ isSuccess: true,
33
+ mfaSetupRequired: true,
34
+ preauthSetupToken: step.preauthSetupToken,
35
+ ...landing,
36
+ });
37
+ }
38
+ return c.json({
39
+ isSuccess: true,
40
+ mfaRequired: true,
41
+ challengeToken: step.challengeToken,
42
+ ...landing,
43
+ });
44
+ }
45
+ // --- shared route builders for token flows ---------------------------------
46
+ // Password-reset, email-verification and signup share the exact same request
47
+ // HTTP-shape: parse body → dispatch the request handler → always-200 (no
48
+ // enumeration). The handler mints the token AND dispatches the magic-link mail
49
+ // via delivery (ctx.notify); the route never sees the token. confirm-route
50
+ // validates the token + does the state change → typed failure or 200. Keeping
51
+ // the silent-success invariant in one place means changing how the framework
52
+ // handles "invalid_body" on a public token endpoint is one edit, not three.
53
+ export function registerTokenRequestRoute(opts) {
54
+ const body = opts.schema ?? RequestTokenBody;
55
+ opts.api.post(opts.path, async (c) => {
56
+ const raw = await c.req.json().catch(() => null);
57
+ const parsed = body.safeParse(raw);
58
+ // Malformed body → silent success. A probing client mustn't learn
59
+ // anything from the shape of their input.
60
+ if (!parsed.success)
61
+ return c.json({ isSuccess: true });
62
+ // The handler dispatches the magic-link mail via delivery before returning.
63
+ // Handler-level failures (misconfiguration, e.g. no RateLimitResolver) stay
64
+ // out of the response so it is uniform for unknown vs. known emails, but
65
+ // they are logged — otherwise the mail silently never goes out. No email in
66
+ // the log line (PII).
67
+ const result = await opts.dispatcher.write(opts.requestHandler, parsed.data, createAnonymousUser(SYSTEM_TENANT_ID));
68
+ // rate_limited is an expected, attacker-triggerable outcome; logging it
69
+ // would flood the sink and bury real misconfiguration errors.
70
+ if (!result.isSuccess && result.error.code !== "rate_limited") {
71
+ console.error(`[kumiko] token request handler "${opts.requestHandler}" failed: ${result.error.code}`);
72
+ }
73
+ return c.json({ isSuccess: true });
74
+ });
75
+ }
76
+ // Shared request-body shape for request-password-reset + request-email-
77
+ // verification. Extracted so the two flows stay in sync when the schema
78
+ // gains optional fields (locale, deviceId, …).
79
+ const RequestTokenBody = z.object({
80
+ email: z.email(),
81
+ });
@@ -0,0 +1,2 @@
1
+ import type { AuthRouteContext } from "./auth-routes-context.ts";
2
+ export declare function registerSignupRoutes(ctx: AuthRouteContext): void;
@@ -0,0 +1,75 @@
1
+ import * as z from "zod";
2
+ import { createAnonymousUser } from "../engine/system-user.js";
3
+ import { SYSTEM_TENANT_ID } from "../engine/types/index.js";
4
+ import { Routes } from "./api-constants.js";
5
+ import { pendingMfaStepResponse, registerTokenRequestRoute, SignupRequestBody, } from "./auth-routes-shared.js";
6
+ const SignupConfirmBody = z.object({
7
+ token: z.string().min(1),
8
+ password: z.string().min(8).max(200),
9
+ });
10
+ export function registerSignupRoutes(ctx) {
11
+ const { api, dispatcher, config, mintSessionAndRespond, landingPathFragment } = ctx;
12
+ // Signup confirm mints the session (auto-login) unless the MFA gate applies;
13
+ // then it answers with the MFA step only, no session or cookies.
14
+ if (config.signup) {
15
+ const sg = config.signup;
16
+ registerTokenRequestRoute({
17
+ api,
18
+ dispatcher,
19
+ path: Routes.authSignupRequest,
20
+ requestHandler: sg.requestHandler,
21
+ schema: SignupRequestBody,
22
+ });
23
+ api.post(Routes.authSignupConfirm, async (c) => {
24
+ const raw = await c.req.json().catch(() => null);
25
+ const parsed = SignupConfirmBody.safeParse(raw);
26
+ if (!parsed.success) {
27
+ return c.json({ isSuccess: false, error: "invalid_body" }, 400);
28
+ }
29
+ const result = await dispatcher.write(sg.confirmHandler, parsed.data, createAnonymousUser(SYSTEM_TENANT_ID));
30
+ if (!result.isSuccess) {
31
+ // 422 for invalid_signup_token (handler-level UnprocessableError).
32
+ // @cast-boundary engine-payload — KumikoError.httpStatus narrows to the http-status union
33
+ const status = result.error.httpStatus;
34
+ return c.json({ isSuccess: false, error: result.error }, status);
35
+ }
36
+ // @cast-boundary engine-payload — generic dispatcher.write result for signup-confirm
37
+ const data = result.data;
38
+ if (data.kind !== "auth-session") {
39
+ // No session yet, but the account and a claimed handover exist: hand
40
+ // the signup landing to the client so the login that follows lands
41
+ // where a signup without the MFA gate would have.
42
+ return pendingMfaStepResponse(c, data, landingPathFragment({ flow: "signup", ...data.signup }));
43
+ }
44
+ // Session creation + JWT sign + cookies — see mintSessionAndRespond.
45
+ const token = await mintSessionAndRespond(c, data.session);
46
+ const signupOutcome = {
47
+ roles: data.session.roles,
48
+ tenantId: data.session.tenantId,
49
+ tenantKey: data.tenantKey,
50
+ ...(data.handover !== undefined && { handover: data.handover }),
51
+ };
52
+ const landingPath = landingPathFragment({ flow: "signup", ...signupOutcome });
53
+ return c.json({
54
+ isSuccess: true,
55
+ token,
56
+ user: {
57
+ id: data.session.id,
58
+ tenantId: data.session.tenantId,
59
+ roles: data.session.roles,
60
+ },
61
+ // tenantKey for the post-signup redirect to /<tenantKey>/. Unlike the
62
+ // login response, which only needs `tenants[]` (the user picks in the
63
+ // switcher), signup knows exactly ONE membership — the frontend UI uses
64
+ // it directly as the redirect target.
65
+ tenantKey: data.tenantKey,
66
+ // Cross-device try-first handover (kumiko-framework#3035 follow-up):
67
+ // present only when signup-confirm actually claimed a bound grant —
68
+ // absent, not null, so a client that doesn't know the field sees
69
+ // nothing unusual.
70
+ ...(data.handover !== undefined && { handover: data.handover }),
71
+ ...landingPath,
72
+ });
73
+ });
74
+ }
75
+ }
@@ -0,0 +1,4 @@
1
+ import type { AuthRouteContext } from "./auth-routes-context.ts";
2
+ export declare function registerPasswordResetRoutes(ctx: AuthRouteContext): void;
3
+ export declare function registerEmailVerificationRoutes(ctx: AuthRouteContext): void;
4
+ export declare function registerAccountUnlockRoutes(ctx: AuthRouteContext): void;
@@ -0,0 +1,91 @@
1
+ import * as z from "zod";
2
+ import { createAnonymousUser } from "../engine/system-user.js";
3
+ import { SYSTEM_TENANT_ID } from "../engine/types/index.js";
4
+ import { Routes } from "./api-constants.js";
5
+ import { registerTokenRequestRoute } from "./auth-routes-shared.js";
6
+ const ResetPasswordBody = z.object({
7
+ token: z.string().min(1),
8
+ newPassword: z.string().min(8).max(200),
9
+ });
10
+ const VerifyEmailBody = z.object({
11
+ token: z.string().min(1),
12
+ });
13
+ function registerTokenConfirmRoute(opts) {
14
+ opts.api.post(opts.path, async (c) => {
15
+ const raw = await c.req.json().catch(() => null);
16
+ const parsed = opts.schema.safeParse(raw);
17
+ if (!parsed.success) {
18
+ return c.json({ isSuccess: false, error: "invalid_body" }, 400);
19
+ }
20
+ const result = await opts.dispatcher.write(opts.confirmHandler, parsed.data, createAnonymousUser(SYSTEM_TENANT_ID));
21
+ if (!result.isSuccess) {
22
+ const status = result.error.httpStatus; // @cast-boundary engine-payload
23
+ return c.json({ isSuccess: false, error: result.error }, status);
24
+ }
25
+ return c.json({ isSuccess: true });
26
+ });
27
+ }
28
+ export function registerPasswordResetRoutes(ctx) {
29
+ const { api, dispatcher, config } = ctx;
30
+ // POST /auth/request-password-reset + /auth/reset-password — public.
31
+ // Silent-success on request (no enumeration), typed failure on confirm.
32
+ // Rate-limit covered via config.rateLimit.auth (Sprint G.5 L2, /auth/*).
33
+ if (config.passwordReset) {
34
+ const pr = config.passwordReset;
35
+ registerTokenRequestRoute({
36
+ api,
37
+ dispatcher,
38
+ path: Routes.authRequestPasswordReset,
39
+ requestHandler: pr.requestHandler,
40
+ });
41
+ registerTokenConfirmRoute({
42
+ api,
43
+ dispatcher,
44
+ path: Routes.authResetPassword,
45
+ confirmHandler: pr.confirmHandler,
46
+ schema: ResetPasswordBody,
47
+ });
48
+ }
49
+ }
50
+ export function registerEmailVerificationRoutes(ctx) {
51
+ const { api, dispatcher, config } = ctx;
52
+ // Email-verification mirrors password-reset.
53
+ if (config.emailVerification) {
54
+ const ev = config.emailVerification;
55
+ registerTokenRequestRoute({
56
+ api,
57
+ dispatcher,
58
+ path: Routes.authRequestEmailVerification,
59
+ requestHandler: ev.requestHandler,
60
+ });
61
+ registerTokenConfirmRoute({
62
+ api,
63
+ dispatcher,
64
+ path: Routes.authVerifyEmail,
65
+ confirmHandler: ev.confirmHandler,
66
+ schema: VerifyEmailBody,
67
+ });
68
+ }
69
+ }
70
+ export function registerAccountUnlockRoutes(ctx) {
71
+ const { api, dispatcher, config } = ctx;
72
+ // Account-unlock mirrors email-verification (token-only confirm body) —
73
+ // clears the Redis lockout state instead of an entity field, see
74
+ // confirm-account-unlock.write.ts.
75
+ if (config.accountUnlock) {
76
+ const au = config.accountUnlock;
77
+ registerTokenRequestRoute({
78
+ api,
79
+ dispatcher,
80
+ path: Routes.authRequestAccountUnlock,
81
+ requestHandler: au.requestHandler,
82
+ });
83
+ registerTokenConfirmRoute({
84
+ api,
85
+ dispatcher,
86
+ path: Routes.authConfirmAccountUnlock,
87
+ confirmHandler: au.confirmHandler,
88
+ schema: VerifyEmailBody,
89
+ });
90
+ }
91
+ }
@@ -0,0 +1,76 @@
1
+ import type { SessionUser } from "../engine/types/index.ts";
2
+ import type { AuthSessionChecker, TokenVerifier } from "./auth-middleware.ts";
3
+ import type { ClientIpResolver } from "./client-ip.ts";
4
+ import type { PostAuthLandingResolver } from "./post-auth-landing.ts";
5
+ export type LoginRateLimiter = {
6
+ check(key: string): Promise<boolean>;
7
+ reset(key: string): Promise<void>;
8
+ };
9
+ export type SessionMetadata = {
10
+ readonly ip: string;
11
+ readonly userAgent: string;
12
+ };
13
+ export type SessionCreator = (user: SessionUser, meta: SessionMetadata) => Promise<string>;
14
+ export type SessionRevoker = (sid: string) => Promise<void>;
15
+ export type SessionMassRevoker = (userId: string) => Promise<number>;
16
+ export type SessionChecker = AuthSessionChecker;
17
+ export type AuthRoutesConfig = {
18
+ membershipQuery: string;
19
+ userQuery?: string;
20
+ loginHandler?: string;
21
+ loginErrorStatusMap?: Readonly<Record<string, number>>;
22
+ loginRateLimit?: LoginRateLimiter | null;
23
+ mfaVerifyHandler?: string;
24
+ switchTenantMfaGateHandler?: string;
25
+ mfaVerifyErrorStatusMap?: Readonly<Record<string, number>>;
26
+ mfaVerifyRateLimit?: LoginRateLimiter | null;
27
+ mfaPreauthEnableStartHandler?: string;
28
+ mfaPreauthEnableStartErrorStatusMap?: Readonly<Record<string, number>>;
29
+ mfaPreauthEnableStartRateLimit?: LoginRateLimiter | null;
30
+ mfaPreauthConfirmHandler?: string;
31
+ mfaPreauthConfirmErrorStatusMap?: Readonly<Record<string, number>>;
32
+ mfaPreauthConfirmRateLimit?: LoginRateLimiter | null;
33
+ sessionCreator?: SessionCreator;
34
+ sessionRevoker?: SessionRevoker;
35
+ sessionChecker?: SessionChecker;
36
+ tokenVerifier?: TokenVerifier;
37
+ patRateLimiter?: LoginRateLimiter;
38
+ resolveTenantLifecycleStatus?: import("./auth-middleware.ts").TenantLifecycleStatusResolver;
39
+ passwordReset?: PasswordResetConfig;
40
+ emailVerification?: EmailVerificationConfig;
41
+ accountUnlock?: AccountUnlockConfig;
42
+ signup?: SignupConfig;
43
+ invite?: InviteConfig;
44
+ cookieSameSite?: "lax" | "strict";
45
+ cookieDomain?: string;
46
+ secureCookies?: boolean;
47
+ retiredCookieDomains?: readonly string[];
48
+ allowedOrigins?: readonly string[];
49
+ publicOrigin?: string;
50
+ unsafeSkipOriginCheck?: boolean;
51
+ trustedProxyHops?: number;
52
+ postAuthLanding?: PostAuthLandingResolver;
53
+ resolver?: ClientIpResolver;
54
+ };
55
+ export type PasswordResetConfig = {
56
+ requestHandler: string;
57
+ confirmHandler: string;
58
+ };
59
+ export type EmailVerificationConfig = {
60
+ requestHandler: string;
61
+ confirmHandler: string;
62
+ };
63
+ export type AccountUnlockConfig = {
64
+ requestHandler: string;
65
+ confirmHandler: string;
66
+ };
67
+ export type InviteConfig = {
68
+ readonly acceptHandler: string;
69
+ readonly acceptWithLoginHandler: string;
70
+ readonly signupCompleteHandler: string;
71
+ readonly infoHandler?: string;
72
+ };
73
+ export type SignupConfig = {
74
+ requestHandler: string;
75
+ confirmHandler: string;
76
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,89 +1,9 @@
1
- import { Hono } from "hono";
2
- import type { Redis } from "ioredis";
3
- import { type SessionUser } from "../engine/types/index.ts";
1
+ import type { Hono } from "hono";
4
2
  import type { Dispatcher } from "../pipeline/dispatcher.ts";
5
- import { type AuthSessionChecker, type AuthSessionStatus, type TokenVerifier } from "./auth-middleware.ts";
6
- import { type ClientIpResolver } from "./client-ip.ts";
3
+ import type { AuthRoutesConfig } from "./auth-routes-types.ts";
7
4
  import type { JwtHelper } from "./jwt.ts";
8
- import type { PostAuthLandingResolver } from "./post-auth-landing.ts";
9
- export type LoginRateLimiter = {
10
- check(key: string): Promise<boolean>;
11
- reset(key: string): Promise<void>;
12
- };
13
- export type SessionMetadata = {
14
- readonly ip: string;
15
- readonly userAgent: string;
16
- };
17
- export type SessionCreator = (user: SessionUser, meta: SessionMetadata) => Promise<string>;
18
- export type SessionRevoker = (sid: string) => Promise<void>;
19
- export type SessionMassRevoker = (userId: string) => Promise<number>;
20
- export type SessionChecker = AuthSessionChecker;
21
- export type { AuthSessionStatus };
5
+ export type { AuthSessionStatus } from "./auth-middleware.ts";
6
+ export { createInMemoryLoginRateLimiter, createRedisLoginRateLimiter, inMemoryLoginRateLimiterFallback, } from "./auth-rate-limiters.ts";
7
+ export type { AccountUnlockConfig, AuthRoutesConfig, EmailVerificationConfig, InviteConfig, LoginRateLimiter, PasswordResetConfig, SessionChecker, SessionCreator, SessionMassRevoker, SessionMetadata, SessionRevoker, SignupConfig, } from "./auth-routes-types.ts";
22
8
  export declare function assertSessionCallbacksPaired(auth: Pick<AuthRoutesConfig, "sessionCreator" | "sessionRevoker" | "sessionChecker"> | undefined): void;
23
- export type AuthRoutesConfig = {
24
- membershipQuery: string;
25
- userQuery?: string;
26
- loginHandler?: string;
27
- loginErrorStatusMap?: Readonly<Record<string, number>>;
28
- loginRateLimit?: LoginRateLimiter | null;
29
- mfaVerifyHandler?: string;
30
- switchTenantMfaGateHandler?: string;
31
- mfaVerifyErrorStatusMap?: Readonly<Record<string, number>>;
32
- mfaVerifyRateLimit?: LoginRateLimiter | null;
33
- mfaPreauthEnableStartHandler?: string;
34
- mfaPreauthEnableStartErrorStatusMap?: Readonly<Record<string, number>>;
35
- mfaPreauthEnableStartRateLimit?: LoginRateLimiter | null;
36
- mfaPreauthConfirmHandler?: string;
37
- mfaPreauthConfirmErrorStatusMap?: Readonly<Record<string, number>>;
38
- mfaPreauthConfirmRateLimit?: LoginRateLimiter | null;
39
- sessionCreator?: SessionCreator;
40
- sessionRevoker?: SessionRevoker;
41
- sessionChecker?: SessionChecker;
42
- tokenVerifier?: TokenVerifier;
43
- patRateLimiter?: LoginRateLimiter;
44
- resolveTenantLifecycleStatus?: import("./auth-middleware.ts").TenantLifecycleStatusResolver;
45
- passwordReset?: PasswordResetConfig;
46
- emailVerification?: EmailVerificationConfig;
47
- accountUnlock?: AccountUnlockConfig;
48
- signup?: SignupConfig;
49
- invite?: InviteConfig;
50
- cookieSameSite?: "lax" | "strict";
51
- cookieDomain?: string;
52
- secureCookies?: boolean;
53
- retiredCookieDomains?: readonly string[];
54
- allowedOrigins?: readonly string[];
55
- publicOrigin?: string;
56
- unsafeSkipOriginCheck?: boolean;
57
- trustedProxyHops?: number;
58
- postAuthLanding?: PostAuthLandingResolver;
59
- resolver?: ClientIpResolver;
60
- };
61
- export type PasswordResetConfig = {
62
- requestHandler: string;
63
- confirmHandler: string;
64
- };
65
- export type EmailVerificationConfig = {
66
- requestHandler: string;
67
- confirmHandler: string;
68
- };
69
- export type AccountUnlockConfig = {
70
- requestHandler: string;
71
- confirmHandler: string;
72
- };
73
- export type InviteConfig = {
74
- readonly acceptHandler: string;
75
- readonly acceptWithLoginHandler: string;
76
- readonly signupCompleteHandler: string;
77
- readonly infoHandler?: string;
78
- };
79
- export type SignupConfig = {
80
- requestHandler: string;
81
- confirmHandler: string;
82
- };
83
- export declare function inMemoryLoginRateLimiterFallback(): LoginRateLimiter;
84
- export declare function createInMemoryLoginRateLimiter(maxAttempts?: number, windowMs?: number, { maxEntries, sweepThreshold, }?: {
85
- maxEntries?: number;
86
- sweepThreshold?: number;
87
- }): LoginRateLimiter;
88
- export declare function createRedisLoginRateLimiter(redis: Redis, maxAttempts?: number, windowMs?: number, namespace?: string): LoginRateLimiter;
89
9
  export declare function createAuthRoutes(dispatcher: Dispatcher, jwt: JwtHelper, config: AuthRoutesConfig): Hono;