@crowi/api-contract 2.0.0-alpha.11 → 2.0.0-alpha.13

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/index.mjs CHANGED
@@ -105,8 +105,12 @@ var ERROR_CODES = [
105
105
  "INVALID_CREDENTIALS",
106
106
  "REFRESH_TOKEN_REQUIRED",
107
107
  "REGISTRATION_CLOSED",
108
+ // --- federated sign-in (RFC-0014) ---
109
+ "FEDERATED_HANDOFF_INVALID",
110
+ "FEDERATED_HANDOFF_CONSUMED",
108
111
  // --- admin subsystems ---
109
112
  "ENCRYPTION_NOT_CONFIGURED",
113
+ "MAIL_FROM_NOT_CONFIGURED",
110
114
  "MAIL_TEST_FAILED",
111
115
  "PLUGIN_NOT_FOUND",
112
116
  "PLUGIN_CONFIG_VALIDATION_FAILED"
@@ -387,10 +391,16 @@ var SendTestMailResponseSchema = z5.object({
387
391
  to: z5.string()
388
392
  });
389
393
  var SendTestMailErrorSchema = z5.object({
390
- error: z5.object({
391
- code: z5.literal("MAIL_TEST_FAILED"),
392
- message: z5.string()
393
- })
394
+ error: z5.discriminatedUnion("code", [
395
+ z5.object({
396
+ code: z5.literal("MAIL_FROM_NOT_CONFIGURED"),
397
+ message: z5.literal("The mail sender address is not configured.")
398
+ }),
399
+ z5.object({
400
+ code: z5.literal("MAIL_TEST_FAILED"),
401
+ message: z5.enum(["Failed to send the test email. Check the active mail sender configuration.", "No email address on the calling user"])
402
+ })
403
+ ])
394
404
  });
395
405
  var MailSettingsValidationErrorSchema = z5.object({
396
406
  bodyResult: z5.object({
@@ -503,7 +513,7 @@ var sendTestMailRoute = createRoute3({
503
513
  content: { "application/json": { schema: AdminRequiredErrorSchema } }
504
514
  },
505
515
  502: {
506
- description: "Test mail dispatch failed (SMTP error)",
516
+ description: "Test mail dispatch failed (mail dispatch failure \u2014 e.g. sender/transport error, or the mail sender address is not configured)",
507
517
  content: { "application/json": { schema: SendTestMailErrorSchema } }
508
518
  }
509
519
  }
@@ -649,6 +659,21 @@ var ClearRenderCacheResponseSchema = z6.object({
649
659
  /** Number of cache rows removed. */
650
660
  removedCount: z6.number().int().min(0)
651
661
  });
662
+ var PluginReadinessFieldSchema = z6.object({
663
+ name: z6.string(),
664
+ configured: z6.literal(false)
665
+ });
666
+ var ConfigReadinessIssueSchema = z6.object({
667
+ /** Stable id — `plugin:<name>` or a core declaration id (e.g. `core:mail`). */
668
+ id: z6.string(),
669
+ source: z6.enum(["plugin", "core"]),
670
+ label: z6.string(),
671
+ href: z6.string(),
672
+ fields: z6.array(PluginReadinessFieldSchema)
673
+ });
674
+ var ConfigReadinessResponseSchema = z6.object({
675
+ issues: z6.array(ConfigReadinessIssueSchema)
676
+ });
652
677
 
653
678
  // src/contracts/admin/plugins.ts
654
679
  var PluginNameQuerySchema = z7.object({ name: z7.string() });
@@ -780,6 +805,27 @@ var clearRenderCacheAllRoute = createRoute4({
780
805
  }
781
806
  }
782
807
  });
808
+ var getPluginReadinessRoute = createRoute4({
809
+ method: "get",
810
+ path: "/admin/plugins/readiness",
811
+ tags: ["admin.plugins"],
812
+ security: [{ bearerAuth: [] }],
813
+ summary: "List active plugins and core config missing required readiness fields",
814
+ responses: {
815
+ 200: {
816
+ description: "Readiness issues for active plugins and core config (empty when everything is configured)",
817
+ content: { "application/json": { schema: ConfigReadinessResponseSchema } }
818
+ },
819
+ 401: {
820
+ description: "Authentication required",
821
+ content: { "application/json": { schema: AuthenticationRequiredErrorSchema } }
822
+ },
823
+ 403: {
824
+ description: "Admin permission required",
825
+ content: { "application/json": { schema: AdminRequiredErrorSchema } }
826
+ }
827
+ }
828
+ });
783
829
  var clearRenderCachePluginRoute = createRoute4({
784
830
  method: "post",
785
831
  path: "/admin/plugins/render-cache/clear-plugin",
@@ -819,6 +865,7 @@ var adminPluginsRoutes = {
819
865
  listPluginsRoute,
820
866
  getPluginConfigRoute,
821
867
  updatePluginConfigRoute,
868
+ getPluginReadinessRoute,
822
869
  clearRenderCacheAllRoute,
823
870
  clearRenderCachePluginRoute
824
871
  };
@@ -3374,22 +3421,28 @@ var draftRoutes = {
3374
3421
  import { createRoute as createRoute16 } from "@hono/zod-openapi";
3375
3422
 
3376
3423
  // src/schemas/installer.ts
3424
+ import { z as z30 } from "@hono/zod-openapi";
3425
+
3426
+ // src/schemas/username.ts
3377
3427
  import { z as z29 } from "@hono/zod-openapi";
3378
- var InstallerStatusResponseSchema = z29.object({
3379
- status: z29.enum(["installer_required", "already_installed"])
3380
- });
3381
- var CreateAdminRequestSchema = z29.object({
3382
- registerForm: z29.object({
3383
- username: z29.string().min(1).regex(/^[\da-zA-Z\-_.]+$/, "username may only contain letters, digits, hyphens, underscores, and dots"),
3384
- name: z29.string().min(1),
3385
- email: z29.string().email(),
3386
- password: z29.string().min(6).regex(/^[\x20-\x7F]{6,}$/, "password must be 6+ printable ASCII characters")
3428
+ var UsernameSchema = z29.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/, "username may only contain letters, digits, hyphens, and underscores");
3429
+
3430
+ // src/schemas/installer.ts
3431
+ var InstallerStatusResponseSchema = z30.object({
3432
+ status: z30.enum(["installer_required", "already_installed"])
3433
+ });
3434
+ var CreateAdminRequestSchema = z30.object({
3435
+ registerForm: z30.object({
3436
+ username: UsernameSchema,
3437
+ name: z30.string().min(1),
3438
+ email: z30.string().email(),
3439
+ password: z30.string().min(6).regex(/^[\x20-\x7F]{6,}$/, "password must be 6+ printable ASCII characters")
3387
3440
  })
3388
3441
  });
3389
- var CreateAdminResponseSchema = z29.object({
3390
- status: z29.enum(["ok", "error"]),
3391
- message: z29.string().optional(),
3392
- errors: z29.array(z29.string()).optional()
3442
+ var CreateAdminResponseSchema = z30.object({
3443
+ status: z30.enum(["ok", "error"]),
3444
+ message: z30.string().optional(),
3445
+ errors: z30.array(z30.string()).optional()
3393
3446
  });
3394
3447
 
3395
3448
  // src/contracts/installer.ts
@@ -3461,84 +3514,97 @@ var createAdminRoute = createRoute16({
3461
3514
  var installerRoutes = { getInstallerStatusRoute, createAdminRoute };
3462
3515
 
3463
3516
  // src/contracts/me.ts
3464
- import { createRoute as createRoute17, z as z31 } from "@hono/zod-openapi";
3517
+ import { createRoute as createRoute17, z as z32 } from "@hono/zod-openapi";
3465
3518
 
3466
3519
  // src/schemas/me.ts
3467
- import { z as z30 } from "@hono/zod-openapi";
3468
- var LanguageSchema = z30.enum(["en", "ja"]);
3469
- var ThemeSchema = z30.enum(["system", "light", "dark"]);
3470
- var UserProfileResponseSchema = z30.object({
3471
- id: z30.string(),
3472
- username: z30.string(),
3473
- name: z30.string(),
3474
- email: z30.string().email(),
3520
+ import { z as z31 } from "@hono/zod-openapi";
3521
+ var LanguageSchema = z31.enum(["en", "ja"]);
3522
+ var ThemeSchema = z31.enum(["system", "light", "dark"]);
3523
+ var UserProfileResponseSchema = z31.object({
3524
+ id: z31.string(),
3525
+ username: z31.string(),
3526
+ name: z31.string(),
3527
+ email: z31.string().email(),
3475
3528
  lang: LanguageSchema,
3476
3529
  theme: ThemeSchema,
3477
- image: z30.string().nullable(),
3478
- introduction: z30.string().optional(),
3479
- hasPassword: z30.boolean(),
3480
- createdAt: z30.string(),
3530
+ image: z31.string().nullable(),
3531
+ introduction: z31.string().optional(),
3532
+ hasPassword: z31.boolean(),
3533
+ createdAt: z31.string(),
3534
+ /**
3535
+ * True when the account has at least one linked federated identity
3536
+ * (`UserIdentity` row). The email address on a federated account is
3537
+ * fixed to the value the identity provider verified — `PUT /me`
3538
+ * refuses a change and returns `EMAIL_LOCKED_BY_FEDERATED_IDENTITY`
3539
+ * when this is true and a different email is submitted. The web uses
3540
+ * this to disable the email field and point to the Security tab.
3541
+ *
3542
+ * Always reflects the account's current state — on `GET /me` and on
3543
+ * every 200 from `PUT /me`, including a `PUT` that changed only name /
3544
+ * lang.
3545
+ */
3546
+ federated: z31.boolean(),
3481
3547
  /**
3482
3548
  * True when the profile update requested a new email that is awaiting
3483
3549
  * confirmation: the stored `email` is unchanged and a confirmation
3484
3550
  * link was sent to the new address.
3485
3551
  */
3486
- emailChangePending: z30.boolean().optional()
3552
+ emailChangePending: z31.boolean().optional()
3487
3553
  });
3488
- var UpdateProfileRequestSchema = z30.object({
3489
- userForm: z30.object({
3490
- name: z30.string().min(1, "Name is required"),
3491
- email: z30.string().email("Invalid email format"),
3554
+ var UpdateProfileRequestSchema = z31.object({
3555
+ userForm: z31.object({
3556
+ name: z31.string().min(1, "Name is required"),
3557
+ email: z31.string().email("Invalid email format"),
3492
3558
  lang: LanguageSchema
3493
3559
  })
3494
3560
  });
3495
- var UpdateThemeRequestSchema = z30.object({
3561
+ var UpdateThemeRequestSchema = z31.object({
3496
3562
  theme: ThemeSchema
3497
3563
  });
3498
- var ThemeUpdateResponseSchema = z30.object({
3499
- status: z30.literal("ok"),
3564
+ var ThemeUpdateResponseSchema = z31.object({
3565
+ status: z31.literal("ok"),
3500
3566
  theme: ThemeSchema
3501
3567
  });
3502
- var PictureUploadResponseSchema = z30.object({
3503
- status: z30.boolean(),
3504
- url: z30.string().optional(),
3505
- message: z30.string().optional()
3568
+ var PictureUploadResponseSchema = z31.object({
3569
+ status: z31.boolean(),
3570
+ url: z31.string().optional(),
3571
+ message: z31.string().optional()
3506
3572
  });
3507
- var SuccessResponseSchema = z30.object({
3508
- status: z30.literal("ok"),
3509
- message: z30.string().optional()
3573
+ var SuccessResponseSchema = z31.object({
3574
+ status: z31.literal("ok"),
3575
+ message: z31.string().optional()
3510
3576
  });
3511
- var ProfileErrorResponseSchema = z30.object({
3512
- status: z30.literal("error"),
3577
+ var ProfileErrorResponseSchema = z31.object({
3578
+ status: z31.literal("error"),
3513
3579
  /** Stable code so the web can localize the message (e.g. EMAIL_TAKEN). */
3514
- code: z30.string().optional(),
3515
- message: z30.string().optional(),
3516
- errors: z30.array(z30.string()).optional()
3580
+ code: z31.string().optional(),
3581
+ message: z31.string().optional(),
3582
+ errors: z31.array(z31.string()).optional()
3517
3583
  });
3518
3584
  var PASSWORD_REGEX = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?`~])[a-zA-Z\d!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?`~]+$/;
3519
- var UpdatePasswordRequestSchema = z30.object({
3520
- oldPassword: z30.string().optional(),
3521
- newPassword: z30.string().min(8, "Password must be at least 8 characters").max(100, "Password must be at most 100 characters").regex(PASSWORD_REGEX, "Password must contain at least one letter, one digit, and one special character"),
3522
- newPasswordConfirm: z30.string()
3585
+ var UpdatePasswordRequestSchema = z31.object({
3586
+ oldPassword: z31.string().optional(),
3587
+ newPassword: z31.string().min(8, "Password must be at least 8 characters").max(100, "Password must be at most 100 characters").regex(PASSWORD_REGEX, "Password must contain at least one letter, one digit, and one special character"),
3588
+ newPasswordConfirm: z31.string()
3523
3589
  }).refine((data) => data.newPassword === data.newPasswordConfirm, {
3524
3590
  message: "Passwords do not match",
3525
3591
  path: ["newPasswordConfirm"]
3526
3592
  });
3527
- var PasswordUpdateSuccessSchema = z30.object({
3528
- status: z30.literal("ok"),
3529
- message: z30.string(),
3530
- accessToken: z30.string(),
3531
- refreshToken: z30.string(),
3593
+ var PasswordUpdateSuccessSchema = z31.object({
3594
+ status: z31.literal("ok"),
3595
+ message: z31.string(),
3596
+ accessToken: z31.string(),
3597
+ refreshToken: z31.string(),
3532
3598
  /** Access-token lifetime in seconds. */
3533
- expiresIn: z30.number()
3599
+ expiresIn: z31.number()
3534
3600
  });
3535
- var PasswordErrorResponseSchema = z30.object({
3536
- status: z30.literal("error"),
3537
- message: z30.string(),
3538
- errors: z30.array(z30.string()).optional()
3601
+ var PasswordErrorResponseSchema = z31.object({
3602
+ status: z31.literal("error"),
3603
+ message: z31.string(),
3604
+ errors: z31.array(z31.string()).optional()
3539
3605
  });
3540
- var RecentlyViewedPagesResponseSchema = z30.object({
3541
- pages: z30.array(PageSchema)
3606
+ var RecentlyViewedPagesResponseSchema = z31.object({
3607
+ pages: z31.array(PageSchema)
3542
3608
  });
3543
3609
 
3544
3610
  // src/contracts/me.ts
@@ -3621,8 +3687,8 @@ var uploadPictureRoute = createRoute17({
3621
3687
  body: {
3622
3688
  content: {
3623
3689
  "multipart/form-data": {
3624
- schema: z31.object({
3625
- file: z31.any().optional().describe("Profile picture file")
3690
+ schema: z32.object({
3691
+ file: z32.any().optional().describe("Profile picture file")
3626
3692
  })
3627
3693
  }
3628
3694
  }
@@ -3722,37 +3788,37 @@ var meRoutes = {
3722
3788
  };
3723
3789
 
3724
3790
  // src/contracts/access-token.ts
3725
- import { createRoute as createRoute18, z as z33 } from "@hono/zod-openapi";
3791
+ import { createRoute as createRoute18, z as z34 } from "@hono/zod-openapi";
3726
3792
 
3727
3793
  // src/schemas/access-token.ts
3728
- import { z as z32 } from "@hono/zod-openapi";
3729
- var AccessTokenSchema = z32.object({
3730
- id: z32.string(),
3731
- name: z32.string(),
3732
- scopes: z32.array(z32.string()),
3794
+ import { z as z33 } from "@hono/zod-openapi";
3795
+ var AccessTokenSchema = z33.object({
3796
+ id: z33.string(),
3797
+ name: z33.string(),
3798
+ scopes: z33.array(z33.string()),
3733
3799
  /** ISO-8601 expiry, or `null` for a non-expiring token. */
3734
- expiresAt: z32.string().nullable(),
3800
+ expiresAt: z33.string().nullable(),
3735
3801
  /** ISO-8601 of last successful use, or `null` if never used. */
3736
- lastUsedAt: z32.string().nullable(),
3737
- createdAt: z32.string()
3802
+ lastUsedAt: z33.string().nullable(),
3803
+ createdAt: z33.string()
3738
3804
  });
3739
- var ListAccessTokensResponseSchema = z32.object({
3740
- accessTokens: z32.array(AccessTokenSchema)
3805
+ var ListAccessTokensResponseSchema = z33.object({
3806
+ accessTokens: z33.array(AccessTokenSchema)
3741
3807
  });
3742
- var CreateAccessTokenRequestSchema = z32.object({
3743
- name: z32.string().min(1, "Name is required").max(200),
3744
- scopes: z32.array(z32.string()).min(1, "At least one scope is required"),
3745
- expiresAt: z32.string().datetime().nullable().optional()
3808
+ var CreateAccessTokenRequestSchema = z33.object({
3809
+ name: z33.string().min(1, "Name is required").max(200),
3810
+ scopes: z33.array(z33.string()).min(1, "At least one scope is required"),
3811
+ expiresAt: z33.string().datetime().nullable().optional()
3746
3812
  });
3747
3813
  var CreateAccessTokenResponseSchema = AccessTokenSchema.extend({
3748
- token: z32.string()
3749
- });
3750
- var InvalidScopeErrorSchema = z32.object({
3751
- error: z32.object({
3752
- code: z32.literal("INVALID_SCOPE"),
3753
- message: z32.string(),
3754
- details: z32.object({
3755
- invalidScopes: z32.array(z32.string())
3814
+ token: z33.string()
3815
+ });
3816
+ var InvalidScopeErrorSchema = z33.object({
3817
+ error: z33.object({
3818
+ code: z33.literal("INVALID_SCOPE"),
3819
+ message: z33.string(),
3820
+ details: z33.object({
3821
+ invalidScopes: z33.array(z33.string())
3756
3822
  }).optional()
3757
3823
  })
3758
3824
  });
@@ -3824,7 +3890,7 @@ var deleteAccessTokenRoute = createRoute18({
3824
3890
  security: [{ bearerAuth: [] }],
3825
3891
  summary: "Revoke a personal access token",
3826
3892
  request: {
3827
- params: z33.object({ id: z33.string() })
3893
+ params: z34.object({ id: z34.string() })
3828
3894
  },
3829
3895
  responses: {
3830
3896
  200: {
@@ -3856,13 +3922,13 @@ var accessTokenRoutes = {
3856
3922
  };
3857
3923
 
3858
3924
  // src/contracts/oauth.ts
3859
- import { createRoute as createRoute19, z as z36 } from "@hono/zod-openapi";
3925
+ import { createRoute as createRoute19, z as z37 } from "@hono/zod-openapi";
3860
3926
 
3861
3927
  // src/schemas/oauth-endpoints.ts
3862
- import { z as z35 } from "@hono/zod-openapi";
3928
+ import { z as z36 } from "@hono/zod-openapi";
3863
3929
 
3864
3930
  // src/schemas/oauth.ts
3865
- import { z as z34 } from "@hono/zod-openapi";
3931
+ import { z as z35 } from "@hono/zod-openapi";
3866
3932
  var SCOPES = [
3867
3933
  // umbrella
3868
3934
  "read",
@@ -3930,11 +3996,11 @@ function scopeSatisfies(required, granted) {
3930
3996
  return false;
3931
3997
  }
3932
3998
  var InsufficientScopeErrorSchema = ApiErrorSchema.extend({
3933
- error: z34.object({
3934
- code: z34.literal("INSUFFICIENT_SCOPE"),
3935
- message: z34.string(),
3936
- details: z34.object({
3937
- requiredScope: z34.string()
3999
+ error: z35.object({
4000
+ code: z35.literal("INSUFFICIENT_SCOPE"),
4001
+ message: z35.string(),
4002
+ details: z35.object({
4003
+ requiredScope: z35.string()
3938
4004
  }).optional()
3939
4005
  })
3940
4006
  });
@@ -3953,97 +4019,97 @@ var OAUTH_ERROR_CODES = [
3953
4019
  "slow_down",
3954
4020
  "expired_token"
3955
4021
  ];
3956
- var OAuthErrorSchema = z35.object({
3957
- error: z35.enum(OAUTH_ERROR_CODES),
3958
- error_description: z35.string().optional()
3959
- });
3960
- var AuthorizeRequestSchema = z35.object({
3961
- client_id: z35.string().min(1),
3962
- redirect_uri: z35.string().min(1),
3963
- scope: z35.string().min(1),
3964
- code_challenge: z35.string().min(1),
3965
- code_challenge_method: z35.literal("S256"),
3966
- state: z35.string().optional()
3967
- });
3968
- var AuthorizeResponseSchema = z35.object({
3969
- redirectUri: z35.string()
3970
- });
3971
- var TokenRequestSchema = z35.discriminatedUnion("grant_type", [
3972
- z35.object({
3973
- grant_type: z35.literal("authorization_code"),
3974
- code: z35.string().min(1),
3975
- code_verifier: z35.string().min(1),
3976
- redirect_uri: z35.string().min(1),
3977
- client_id: z35.string().min(1)
4022
+ var OAuthErrorSchema = z36.object({
4023
+ error: z36.enum(OAUTH_ERROR_CODES),
4024
+ error_description: z36.string().optional()
4025
+ });
4026
+ var AuthorizeRequestSchema = z36.object({
4027
+ client_id: z36.string().min(1),
4028
+ redirect_uri: z36.string().min(1),
4029
+ scope: z36.string().min(1),
4030
+ code_challenge: z36.string().min(1),
4031
+ code_challenge_method: z36.literal("S256"),
4032
+ state: z36.string().optional()
4033
+ });
4034
+ var AuthorizeResponseSchema = z36.object({
4035
+ redirectUri: z36.string()
4036
+ });
4037
+ var TokenRequestSchema = z36.discriminatedUnion("grant_type", [
4038
+ z36.object({
4039
+ grant_type: z36.literal("authorization_code"),
4040
+ code: z36.string().min(1),
4041
+ code_verifier: z36.string().min(1),
4042
+ redirect_uri: z36.string().min(1),
4043
+ client_id: z36.string().min(1)
3978
4044
  }),
3979
- z35.object({
3980
- grant_type: z35.literal("refresh_token"),
3981
- refresh_token: z35.string().min(1),
3982
- client_id: z35.string().min(1),
3983
- scope: z35.string().optional()
4045
+ z36.object({
4046
+ grant_type: z36.literal("refresh_token"),
4047
+ refresh_token: z36.string().min(1),
4048
+ client_id: z36.string().min(1),
4049
+ scope: z36.string().optional()
3984
4050
  }),
3985
4051
  // RFC 8628 §3.4 — device authorization grant. The client polls with the
3986
4052
  // opaque `device_code` returned by `/oauth/device/authorize`.
3987
- z35.object({
3988
- grant_type: z35.literal("urn:ietf:params:oauth:grant-type:device_code"),
3989
- device_code: z35.string().min(1),
3990
- client_id: z35.string().min(1)
4053
+ z36.object({
4054
+ grant_type: z36.literal("urn:ietf:params:oauth:grant-type:device_code"),
4055
+ device_code: z36.string().min(1),
4056
+ client_id: z36.string().min(1)
3991
4057
  })
3992
4058
  ]);
3993
4059
  var DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
3994
- var TokenResponseSchema = z35.object({
3995
- access_token: z35.string(),
3996
- token_type: z35.literal("Bearer"),
3997
- expires_in: z35.number(),
3998
- refresh_token: z35.string(),
3999
- scope: z35.string()
4000
- });
4001
- var RevokeRequestSchema = z35.object({
4002
- token: z35.string().min(1),
4003
- token_type_hint: z35.string().optional()
4004
- });
4005
- var RevokeResponseSchema = z35.object({});
4006
- var DeviceAuthorizeRequestSchema = z35.object({
4007
- client_id: z35.string().min(1),
4008
- scope: z35.string().min(1)
4009
- });
4010
- var DeviceAuthorizeResponseSchema = z35.object({
4011
- device_code: z35.string(),
4012
- user_code: z35.string(),
4013
- verification_uri: z35.string(),
4014
- verification_uri_complete: z35.string(),
4015
- expires_in: z35.number(),
4016
- interval: z35.number()
4017
- });
4018
- var DeviceVerifyRequestSchema = z35.object({
4019
- user_code: z35.string().min(1),
4020
- action: z35.enum(["approve", "deny"])
4021
- });
4022
- var DeviceVerifyResponseSchema = z35.object({
4023
- status: z35.enum(["approved", "denied"])
4024
- });
4025
- var DeviceInfoResponseSchema = z35.object({
4026
- client_id: z35.string(),
4027
- scopes: z35.array(z35.string())
4028
- });
4029
- var ClientInfoResponseSchema = z35.object({
4030
- clientId: z35.string(),
4031
- name: z35.string(),
4032
- firstParty: z35.boolean(),
4033
- trusted: z35.boolean()
4060
+ var TokenResponseSchema = z36.object({
4061
+ access_token: z36.string(),
4062
+ token_type: z36.literal("Bearer"),
4063
+ expires_in: z36.number(),
4064
+ refresh_token: z36.string(),
4065
+ scope: z36.string()
4066
+ });
4067
+ var RevokeRequestSchema = z36.object({
4068
+ token: z36.string().min(1),
4069
+ token_type_hint: z36.string().optional()
4070
+ });
4071
+ var RevokeResponseSchema = z36.object({});
4072
+ var DeviceAuthorizeRequestSchema = z36.object({
4073
+ client_id: z36.string().min(1),
4074
+ scope: z36.string().min(1)
4075
+ });
4076
+ var DeviceAuthorizeResponseSchema = z36.object({
4077
+ device_code: z36.string(),
4078
+ user_code: z36.string(),
4079
+ verification_uri: z36.string(),
4080
+ verification_uri_complete: z36.string(),
4081
+ expires_in: z36.number(),
4082
+ interval: z36.number()
4083
+ });
4084
+ var DeviceVerifyRequestSchema = z36.object({
4085
+ user_code: z36.string().min(1),
4086
+ action: z36.enum(["approve", "deny"])
4087
+ });
4088
+ var DeviceVerifyResponseSchema = z36.object({
4089
+ status: z36.enum(["approved", "denied"])
4090
+ });
4091
+ var DeviceInfoResponseSchema = z36.object({
4092
+ client_id: z36.string(),
4093
+ scopes: z36.array(z36.string())
4094
+ });
4095
+ var ClientInfoResponseSchema = z36.object({
4096
+ clientId: z36.string(),
4097
+ name: z36.string(),
4098
+ firstParty: z36.boolean(),
4099
+ trusted: z36.boolean()
4034
4100
  });
4035
4101
  var GRANT_TYPES_SUPPORTED = ["authorization_code", "refresh_token", DEVICE_CODE_GRANT_TYPE];
4036
- var DiscoveryResponseSchema = z35.object({
4037
- issuer: z35.string(),
4038
- authorization_endpoint: z35.string(),
4039
- token_endpoint: z35.string(),
4040
- revocation_endpoint: z35.string(),
4041
- device_authorization_endpoint: z35.string().optional(),
4042
- scopes_supported: z35.array(z35.string()),
4043
- response_types_supported: z35.array(z35.string()),
4044
- grant_types_supported: z35.array(z35.string()),
4045
- code_challenge_methods_supported: z35.array(z35.string()),
4046
- token_endpoint_auth_methods_supported: z35.array(z35.string())
4102
+ var DiscoveryResponseSchema = z36.object({
4103
+ issuer: z36.string(),
4104
+ authorization_endpoint: z36.string(),
4105
+ token_endpoint: z36.string(),
4106
+ revocation_endpoint: z36.string(),
4107
+ device_authorization_endpoint: z36.string().optional(),
4108
+ scopes_supported: z36.array(z36.string()),
4109
+ response_types_supported: z36.array(z36.string()),
4110
+ grant_types_supported: z36.array(z36.string()),
4111
+ code_challenge_methods_supported: z36.array(z36.string()),
4112
+ token_endpoint_auth_methods_supported: z36.array(z36.string())
4047
4113
  });
4048
4114
  var DISCOVERY_SCOPES_SUPPORTED = ISSUABLE_SCOPES;
4049
4115
 
@@ -4179,7 +4245,7 @@ var deviceInfoRoute = createRoute19({
4179
4245
  // scopes so the web consent screen can show them before approval. Reveals
4180
4246
  // no secret. Unknown / expired / non-pending → 404 (PHASE4-Q9 option A).
4181
4247
  request: {
4182
- query: z36.object({ user_code: z36.string().min(1) })
4248
+ query: z37.object({ user_code: z37.string().min(1) })
4183
4249
  },
4184
4250
  responses: {
4185
4251
  200: {
@@ -4233,7 +4299,7 @@ var clientInfoRoute = createRoute19({
4233
4299
  // no redirectUris/allowedScopes — mirroring deviceInfoRoute's own
4234
4300
  // non-secret-lookup shape. Unknown client_id → 404.
4235
4301
  request: {
4236
- query: z36.object({ client_id: z36.string().min(1) })
4302
+ query: z37.object({ client_id: z37.string().min(1) })
4237
4303
  },
4238
4304
  responses: {
4239
4305
  200: {
@@ -4258,24 +4324,24 @@ var oauthRoutes = {
4258
4324
  };
4259
4325
 
4260
4326
  // src/contracts/notification.ts
4261
- import { createRoute as createRoute20, z as z38 } from "@hono/zod-openapi";
4327
+ import { createRoute as createRoute20, z as z39 } from "@hono/zod-openapi";
4262
4328
 
4263
4329
  // src/schemas/notification.ts
4264
- import { z as z37 } from "@hono/zod-openapi";
4265
- var NotificationStatusSchema = z37.enum(["UNREAD", "UNOPENED", "OPENED"]);
4330
+ import { z as z38 } from "@hono/zod-openapi";
4331
+ var NotificationStatusSchema = z38.enum(["UNREAD", "UNOPENED", "OPENED"]);
4266
4332
  var NotificationStatusEnum = {
4267
4333
  UNREAD: "UNREAD",
4268
4334
  UNOPENED: "UNOPENED",
4269
4335
  OPENED: "OPENED"
4270
4336
  };
4271
- var NotificationActionSchema = z37.enum(["COMMENT", "LIKE", "MENTION", "UPDATE"]);
4337
+ var NotificationActionSchema = z38.enum(["COMMENT", "LIKE", "MENTION", "UPDATE"]);
4272
4338
  var NotificationActionEnum = {
4273
4339
  COMMENT: "COMMENT",
4274
4340
  LIKE: "LIKE",
4275
4341
  MENTION: "MENTION",
4276
4342
  UPDATE: "UPDATE"
4277
4343
  };
4278
- var NotificationTargetModelSchema = z37.enum(["Page"]);
4344
+ var NotificationTargetModelSchema = z38.enum(["Page"]);
4279
4345
  var NotificationTargetModelEnum = {
4280
4346
  PAGE: "Page"
4281
4347
  };
@@ -4284,68 +4350,68 @@ var PageRefSchema = PageSchema.pick({
4284
4350
  path: true,
4285
4351
  status: true
4286
4352
  });
4287
- var NotificationSchema = z37.object({
4288
- _id: z37.string(),
4289
- user: z37.string(),
4353
+ var NotificationSchema = z38.object({
4354
+ _id: z38.string(),
4355
+ user: z38.string(),
4290
4356
  targetModel: NotificationTargetModelSchema,
4291
4357
  target: PageRefSchema,
4292
4358
  action: NotificationActionSchema,
4293
4359
  status: NotificationStatusSchema,
4294
- actionUsers: z37.array(UserPublicSchema),
4295
- createdAt: z37.string()
4360
+ actionUsers: z38.array(UserPublicSchema),
4361
+ createdAt: z38.string()
4296
4362
  });
4297
- var ListNotificationsRequestSchema = z37.object({
4298
- limit: z37.coerce.number().optional().default(10),
4299
- offset: z37.coerce.number().optional().default(0)
4363
+ var ListNotificationsRequestSchema = z38.object({
4364
+ limit: z38.coerce.number().optional().default(10),
4365
+ offset: z38.coerce.number().optional().default(0)
4300
4366
  });
4301
- var ListNotificationsResponseSchema = z37.object({
4302
- notifications: z37.array(NotificationSchema),
4367
+ var ListNotificationsResponseSchema = z38.object({
4368
+ notifications: z38.array(NotificationSchema),
4303
4369
  pager: PagerSchema
4304
4370
  });
4305
- var MarkAllAsReadResponseSchema = z37.object({
4306
- ok: z37.literal(true)
4371
+ var MarkAllAsReadResponseSchema = z38.object({
4372
+ ok: z38.literal(true)
4307
4373
  });
4308
- var OpenNotificationParamSchema = z37.object({
4309
- id: z37.string()
4374
+ var OpenNotificationParamSchema = z38.object({
4375
+ id: z38.string()
4310
4376
  });
4311
- var OpenNotificationResponseSchema = z37.object({
4377
+ var OpenNotificationResponseSchema = z38.object({
4312
4378
  notification: NotificationSchema
4313
4379
  });
4314
- var NotificationStatusResponseSchema = z37.object({
4315
- count: z37.number()
4380
+ var NotificationStatusResponseSchema = z38.object({
4381
+ count: z38.number()
4316
4382
  });
4317
- var NotificationNotFoundErrorSchema = z37.object({
4318
- error: z37.object({
4319
- code: z37.literal("NOTIFICATION_NOT_FOUND"),
4320
- message: z37.literal("Notification not found")
4383
+ var NotificationNotFoundErrorSchema = z38.object({
4384
+ error: z38.object({
4385
+ code: z38.literal("NOTIFICATION_NOT_FOUND"),
4386
+ message: z38.literal("Notification not found")
4321
4387
  })
4322
4388
  });
4323
- var NotificationsTokenResponseSchema = z37.object({
4324
- token: z37.string(),
4325
- selfUserId: z37.string(),
4326
- expiresAt: z37.string()
4389
+ var NotificationsTokenResponseSchema = z38.object({
4390
+ token: z38.string(),
4391
+ selfUserId: z38.string(),
4392
+ expiresAt: z38.string()
4327
4393
  });
4328
- var NotificationsTokenPayloadSchema = z37.object({
4329
- selfUserId: z37.string(),
4394
+ var NotificationsTokenPayloadSchema = z38.object({
4395
+ selfUserId: z38.string(),
4330
4396
  // Random UUID mixed into every signed token so two tokens minted
4331
4397
  // within the same second still produce byte-different JWT strings.
4332
4398
  // The browser uses the token as a React effect dependency to drive
4333
4399
  // the WebSocket reconnect — without `jti`, the iat/exp pair is
4334
4400
  // identical at second granularity and the dep stays stable.
4335
- jti: z37.string().uuid(),
4336
- iat: z37.number().int(),
4337
- exp: z37.number().int()
4401
+ jti: z38.string().uuid(),
4402
+ iat: z38.number().int(),
4403
+ exp: z38.number().int()
4338
4404
  });
4339
- var NotificationsChangedMessageSchema = z37.object({
4340
- type: z37.literal("changed")
4405
+ var NotificationsChangedMessageSchema = z38.object({
4406
+ type: z38.literal("changed")
4341
4407
  });
4342
4408
  var NotificationsServerMessageSchema = NotificationsChangedMessageSchema;
4343
4409
 
4344
4410
  // src/contracts/notification.ts
4345
- var NotificationInvalidRequestErrorSchema = z38.object({
4346
- error: z38.object({
4347
- code: z38.literal("INVALID_REQUEST"),
4348
- message: z38.string()
4411
+ var NotificationInvalidRequestErrorSchema = z39.object({
4412
+ error: z39.object({
4413
+ code: z39.literal("INVALID_REQUEST"),
4414
+ message: z39.string()
4349
4415
  })
4350
4416
  });
4351
4417
  var listNotificationsRoute = createRoute20({
@@ -4481,9 +4547,9 @@ var notificationRoutes = {
4481
4547
  };
4482
4548
 
4483
4549
  // src/contracts/page-collab.ts
4484
- import { createRoute as createRoute21, z as z39 } from "@hono/zod-openapi";
4485
- var PageIdPathParamsSchema2 = z39.object({
4486
- id: z39.string().openapi({ description: "Page id (24-char hex ObjectId)", example: "507f1f77bcf86cd799439011" })
4550
+ import { createRoute as createRoute21, z as z40 } from "@hono/zod-openapi";
4551
+ var PageIdPathParamsSchema2 = z40.object({
4552
+ id: z40.string().openapi({ description: "Page id (24-char hex ObjectId)", example: "507f1f77bcf86cd799439011" })
4487
4553
  });
4488
4554
  var getYjsTokenRoute = createRoute21({
4489
4555
  method: "get",
@@ -4522,25 +4588,25 @@ var pageCollabRoutes = {
4522
4588
  };
4523
4589
 
4524
4590
  // src/contracts/page.ts
4525
- import { createRoute as createRoute22, z as z40 } from "@hono/zod-openapi";
4526
- var PageBadRequestErrorSchema = z40.object({
4527
- error: z40.object({
4528
- code: z40.string(),
4529
- message: z40.string()
4591
+ import { createRoute as createRoute22, z as z41 } from "@hono/zod-openapi";
4592
+ var PageBadRequestErrorSchema = z41.object({
4593
+ error: z41.object({
4594
+ code: z41.string(),
4595
+ message: z41.string()
4530
4596
  })
4531
4597
  });
4532
- var DeletePageRequestSchema = z40.object({
4533
- page_id: z40.string(),
4534
- revision_id: z40.string().optional(),
4535
- completely: z40.boolean().optional()
4598
+ var DeletePageRequestSchema = z41.object({
4599
+ page_id: z41.string(),
4600
+ revision_id: z41.string().optional(),
4601
+ completely: z41.boolean().optional()
4536
4602
  });
4537
- var RevertDeletedPageRequestSchema = z40.object({
4538
- page_id: z40.string()
4603
+ var RevertDeletedPageRequestSchema = z41.object({
4604
+ page_id: z41.string()
4539
4605
  });
4540
- var PageIdBodySchema = z40.object({
4541
- page_id: z40.string()
4606
+ var PageIdBodySchema = z41.object({
4607
+ page_id: z41.string()
4542
4608
  });
4543
- var PageResponseSchema = z40.object({ page: PageSchema });
4609
+ var PageResponseSchema = z41.object({ page: PageSchema });
4544
4610
  var getPageRoute = createRoute22({
4545
4611
  method: "get",
4546
4612
  path: "/pages",
@@ -4854,7 +4920,7 @@ var claimPageLinkAccessRoute = createRoute22({
4854
4920
  description: "The caller has no access to the page (isGrantedFor is false) or lacks scope / is a non-web session \u2014 403 is about the caller lacking access, never about the page grant type per se",
4855
4921
  content: {
4856
4922
  "application/json": {
4857
- schema: z40.union([PageNotGrantedErrorSchema, InsufficientScopeErrorSchema])
4923
+ schema: z41.union([PageNotGrantedErrorSchema, InsufficientScopeErrorSchema])
4858
4924
  }
4859
4925
  }
4860
4926
  },
@@ -5044,7 +5110,7 @@ var renamePageRoute = createRoute22({
5044
5110
  description: "PAGE_INVALID_NAME / PAGE_EXISTS / PAGE_RENAME_FAILED / PAGE_RENAME_TREE_FAILED",
5045
5111
  content: {
5046
5112
  "application/json": {
5047
- schema: z40.union([PageBadRequestErrorSchema, RenameTreeErrorSchema])
5113
+ schema: z41.union([PageBadRequestErrorSchema, RenameTreeErrorSchema])
5048
5114
  }
5049
5115
  }
5050
5116
  },
@@ -5082,7 +5148,7 @@ var renameSubtreeRoute = createRoute22({
5082
5148
  description: "PAGE_INVALID_NAME / PAGE_RENAME_TREE_FAILED (collisions, nothing to move, or partial failure)",
5083
5149
  content: {
5084
5150
  "application/json": {
5085
- schema: z40.union([PageBadRequestErrorSchema, RenameTreeErrorSchema])
5151
+ schema: z41.union([PageBadRequestErrorSchema, RenameTreeErrorSchema])
5086
5152
  }
5087
5153
  }
5088
5154
  },
@@ -5135,11 +5201,11 @@ var pageRoutes = {
5135
5201
  import { createRoute as createRoute23 } from "@hono/zod-openapi";
5136
5202
 
5137
5203
  // src/schemas/page-preview.ts
5138
- import { z as z41 } from "@hono/zod-openapi";
5139
- var PreviewPageRequestSchema = z41.object({
5140
- body: z41.string()
5204
+ import { z as z42 } from "@hono/zod-openapi";
5205
+ var PreviewPageRequestSchema = z42.object({
5206
+ body: z42.string()
5141
5207
  });
5142
- var PreviewPageResponseSchema = z41.object({
5208
+ var PreviewPageResponseSchema = z42.object({
5143
5209
  renderedAst: RenderedAstValueSchema.optional(),
5144
5210
  renderedAstArtifactKey: RenderedAstArtifactKeySchema.optional()
5145
5211
  });
@@ -5183,78 +5249,78 @@ var pagePreviewRoutes = {
5183
5249
  };
5184
5250
 
5185
5251
  // src/contracts/presence.ts
5186
- import { createRoute as createRoute24, z as z43 } from "@hono/zod-openapi";
5252
+ import { createRoute as createRoute24, z as z44 } from "@hono/zod-openapi";
5187
5253
 
5188
5254
  // src/schemas/presence.ts
5189
- import { z as z42 } from "@hono/zod-openapi";
5190
- var PresenceTokenResponseSchema = z42.object({
5191
- token: z42.string(),
5192
- pageId: z42.string(),
5193
- selfUserId: z42.string(),
5194
- expiresAt: z42.string()
5195
- });
5196
- var PresenceTokenPayloadSchema = z42.object({
5197
- userId: z42.string(),
5198
- pageId: z42.string(),
5199
- iat: z42.number().int(),
5200
- exp: z42.number().int()
5201
- });
5202
- var PresenceViewerSchema = z42.object({
5203
- userId: z42.string(),
5204
- username: z42.string(),
5205
- displayName: z42.string(),
5206
- avatarUrl: z42.string().nullable(),
5207
- isEditing: z42.boolean(),
5208
- joinedAt: z42.number().int()
5209
- });
5210
- var PresenceHeartbeatMessageSchema = z42.object({
5211
- type: z42.literal("heartbeat")
5255
+ import { z as z43 } from "@hono/zod-openapi";
5256
+ var PresenceTokenResponseSchema = z43.object({
5257
+ token: z43.string(),
5258
+ pageId: z43.string(),
5259
+ selfUserId: z43.string(),
5260
+ expiresAt: z43.string()
5261
+ });
5262
+ var PresenceTokenPayloadSchema = z43.object({
5263
+ userId: z43.string(),
5264
+ pageId: z43.string(),
5265
+ iat: z43.number().int(),
5266
+ exp: z43.number().int()
5267
+ });
5268
+ var PresenceViewerSchema = z43.object({
5269
+ userId: z43.string(),
5270
+ username: z43.string(),
5271
+ displayName: z43.string(),
5272
+ avatarUrl: z43.string().nullable(),
5273
+ isEditing: z43.boolean(),
5274
+ joinedAt: z43.number().int()
5275
+ });
5276
+ var PresenceHeartbeatMessageSchema = z43.object({
5277
+ type: z43.literal("heartbeat")
5212
5278
  });
5213
5279
  var PresenceClientMessageSchema = PresenceHeartbeatMessageSchema;
5214
- var PresenceViewersMessageSchema = z42.object({
5215
- type: z42.literal("viewers"),
5216
- viewers: z42.array(PresenceViewerSchema),
5217
- generation: z42.number().int()
5218
- });
5219
- var PresencePageUpdatedMessageSchema = z42.object({
5220
- type: z42.literal("page-updated"),
5221
- pageId: z42.string(),
5222
- revisionId: z42.string(),
5223
- editorUserId: z42.string(),
5224
- editorDisplayName: z42.string()
5225
- });
5226
- var PresenceCommentChangedMessageSchema = z42.object({
5227
- type: z42.literal("comment-changed"),
5228
- pageId: z42.string(),
5229
- changeType: z42.enum(["added", "removed"]),
5230
- commentId: z42.string(),
5231
- actorUserId: z42.string().optional()
5232
- });
5233
- var PresenceServerMessageSchema = z42.discriminatedUnion("type", [
5280
+ var PresenceViewersMessageSchema = z43.object({
5281
+ type: z43.literal("viewers"),
5282
+ viewers: z43.array(PresenceViewerSchema),
5283
+ generation: z43.number().int()
5284
+ });
5285
+ var PresencePageUpdatedMessageSchema = z43.object({
5286
+ type: z43.literal("page-updated"),
5287
+ pageId: z43.string(),
5288
+ revisionId: z43.string(),
5289
+ editorUserId: z43.string(),
5290
+ editorDisplayName: z43.string()
5291
+ });
5292
+ var PresenceCommentChangedMessageSchema = z43.object({
5293
+ type: z43.literal("comment-changed"),
5294
+ pageId: z43.string(),
5295
+ changeType: z43.enum(["added", "removed"]),
5296
+ commentId: z43.string(),
5297
+ actorUserId: z43.string().optional()
5298
+ });
5299
+ var PresenceServerMessageSchema = z43.discriminatedUnion("type", [
5234
5300
  PresenceViewersMessageSchema,
5235
5301
  PresencePageUpdatedMessageSchema,
5236
5302
  PresenceCommentChangedMessageSchema
5237
5303
  ]);
5238
- var LikerSchema = z42.object({
5239
- id: z42.string(),
5240
- username: z42.string(),
5241
- displayName: z42.string(),
5242
- avatarUrl: z42.string().nullable(),
5243
- likedAt: z42.string().nullable()
5244
- });
5245
- var LikersResponseSchema = z42.object({
5246
- users: z42.array(LikerSchema),
5247
- totalCount: z42.number().int().nonnegative()
5248
- });
5249
- var GetLikersRequestSchema = z42.object({
5304
+ var LikerSchema = z43.object({
5305
+ id: z43.string(),
5306
+ username: z43.string(),
5307
+ displayName: z43.string(),
5308
+ avatarUrl: z43.string().nullable(),
5309
+ likedAt: z43.string().nullable()
5310
+ });
5311
+ var LikersResponseSchema = z43.object({
5312
+ users: z43.array(LikerSchema),
5313
+ totalCount: z43.number().int().nonnegative()
5314
+ });
5315
+ var GetLikersRequestSchema = z43.object({
5250
5316
  // Optional cap on returned `users`. `totalCount` always reflects the
5251
5317
  // full count regardless of `limit`. Omit for the full list.
5252
- limit: z42.coerce.number().int().positive().optional()
5318
+ limit: z43.coerce.number().int().positive().optional()
5253
5319
  });
5254
5320
 
5255
5321
  // src/contracts/presence.ts
5256
- var PageIdPathParamsSchema3 = z43.object({
5257
- id: z43.string().openapi({ description: "Page id (24-char hex ObjectId)", example: "507f1f77bcf86cd799439011" })
5322
+ var PageIdPathParamsSchema3 = z44.object({
5323
+ id: z44.string().openapi({ description: "Page id (24-char hex ObjectId)", example: "507f1f77bcf86cd799439011" })
5258
5324
  });
5259
5325
  var getPresenceTokenRoute = createRoute24({
5260
5326
  method: "get",
@@ -5327,49 +5393,49 @@ var presenceRoutes = {
5327
5393
  };
5328
5394
 
5329
5395
  // src/contracts/revision.ts
5330
- import { createRoute as createRoute25, z as z45 } from "@hono/zod-openapi";
5396
+ import { createRoute as createRoute25, z as z46 } from "@hono/zod-openapi";
5331
5397
 
5332
5398
  // src/schemas/revision.ts
5333
- import { z as z44 } from "@hono/zod-openapi";
5334
- var RevisionMetaSchema = z44.object({
5335
- _id: z44.string(),
5336
- path: z44.string(),
5399
+ import { z as z45 } from "@hono/zod-openapi";
5400
+ var RevisionMetaSchema = z45.object({
5401
+ _id: z45.string(),
5402
+ path: z45.string(),
5337
5403
  author: PageUserSchema.nullable().optional(),
5338
5404
  savedBy: PageUserSchema.nullable().optional(),
5339
- contributors: z44.array(PageUserSchema).optional(),
5405
+ contributors: z45.array(PageUserSchema).optional(),
5340
5406
  // RFC-0010 — edit channel. `web` (browser / collab editor) vs the API
5341
5407
  // token paths (`oauth` / `pat`). Absent on pre-RFC-0010 revisions. The
5342
5408
  // history UI shows an "app" chip for the token paths.
5343
- editVia: z44.enum(["web", "oauth", "pat"]).optional(),
5344
- createdAt: z44.string()
5409
+ editVia: z45.enum(["web", "oauth", "pat"]).optional(),
5410
+ createdAt: z45.string()
5345
5411
  });
5346
- var ListRevisionsRequestSchema = z44.object({
5347
- limit: z44.coerce.number().int().positive().max(200).optional().default(50),
5348
- offset: z44.coerce.number().int().min(0).optional().default(0)
5412
+ var ListRevisionsRequestSchema = z45.object({
5413
+ limit: z45.coerce.number().int().positive().max(200).optional().default(50),
5414
+ offset: z45.coerce.number().int().min(0).optional().default(0)
5349
5415
  });
5350
- var ListRevisionsResponseSchema = z44.object({
5351
- revisions: z44.array(RevisionMetaSchema),
5416
+ var ListRevisionsResponseSchema = z45.object({
5417
+ revisions: z45.array(RevisionMetaSchema),
5352
5418
  pager: PagerSchema
5353
5419
  });
5354
- var GetRevisionResponseSchema = z44.object({
5420
+ var GetRevisionResponseSchema = z45.object({
5355
5421
  revision: RevisionSchema
5356
5422
  });
5357
- var GetRevisionsRequestSchema = z44.object({
5358
- ids: z44.string().min(1, "ids is required")
5423
+ var GetRevisionsRequestSchema = z45.object({
5424
+ ids: z45.string().min(1, "ids is required")
5359
5425
  });
5360
- var GetRevisionsResponseSchema = z44.object({
5361
- revisions: z44.array(RevisionSchema)
5426
+ var GetRevisionsResponseSchema = z45.object({
5427
+ revisions: z45.array(RevisionSchema)
5362
5428
  });
5363
- var RevisionInvalidRequestErrorSchema = z44.object({
5364
- error: z44.object({
5365
- code: z44.literal("INVALID_REQUEST"),
5366
- message: z44.string()
5429
+ var RevisionInvalidRequestErrorSchema = z45.object({
5430
+ error: z45.object({
5431
+ code: z45.literal("INVALID_REQUEST"),
5432
+ message: z45.string()
5367
5433
  })
5368
5434
  });
5369
5435
 
5370
5436
  // src/contracts/revision.ts
5371
- var PageIdParamSchema = z45.object({ page_id: z45.string() });
5372
- var RevisionIdParamSchema = z45.object({ id: z45.string() });
5437
+ var PageIdParamSchema = z46.object({ page_id: z46.string() });
5438
+ var RevisionIdParamSchema = z46.object({ id: z46.string() });
5373
5439
  var listRevisionsRoute = createRoute25({
5374
5440
  method: "get",
5375
5441
  path: "/pages/{page_id}/revisions",
@@ -5468,31 +5534,31 @@ var revisionRoutes = {
5468
5534
  import { createRoute as createRoute26 } from "@hono/zod-openapi";
5469
5535
 
5470
5536
  // src/schemas/admin-crypto.ts
5471
- import { z as z46 } from "@hono/zod-openapi";
5472
- var SensitiveConfigEntrySchema = z46.object({
5473
- ns: z46.string(),
5474
- key: z46.string(),
5475
- present: z46.boolean(),
5476
- encrypted: z46.boolean()
5477
- });
5478
- var CryptoStatusResponseSchema = z46.object({
5537
+ import { z as z47 } from "@hono/zod-openapi";
5538
+ var SensitiveConfigEntrySchema = z47.object({
5539
+ ns: z47.string(),
5540
+ key: z47.string(),
5541
+ present: z47.boolean(),
5542
+ encrypted: z47.boolean()
5543
+ });
5544
+ var CryptoStatusResponseSchema = z47.object({
5479
5545
  /** False when CROWI_ENCRYPTION_KEY is not configured — UI shows a setup hint. */
5480
- encryptionConfigured: z46.boolean(),
5481
- unencryptedCount: z46.number().int().min(0),
5482
- encryptedCount: z46.number().int().min(0),
5483
- entries: z46.array(SensitiveConfigEntrySchema)
5546
+ encryptionConfigured: z47.boolean(),
5547
+ unencryptedCount: z47.number().int().min(0),
5548
+ encryptedCount: z47.number().int().min(0),
5549
+ entries: z47.array(SensitiveConfigEntrySchema)
5484
5550
  });
5485
- var ReencryptResponseSchema = z46.object({
5486
- rewritten: z46.number().int().min(0),
5551
+ var ReencryptResponseSchema = z47.object({
5552
+ rewritten: z47.number().int().min(0),
5487
5553
  /** Already encrypted, skipped on this run. */
5488
- alreadyEncrypted: z46.number().int().min(0),
5554
+ alreadyEncrypted: z47.number().int().min(0),
5489
5555
  /** Sensitive registry entries that had no row in the DB at all. */
5490
- missing: z46.number().int().min(0)
5556
+ missing: z47.number().int().min(0)
5491
5557
  });
5492
- var EncryptionNotConfiguredErrorSchema = z46.object({
5493
- error: z46.object({
5494
- code: z46.literal("ENCRYPTION_NOT_CONFIGURED"),
5495
- message: z46.string()
5558
+ var EncryptionNotConfiguredErrorSchema = z47.object({
5559
+ error: z47.object({
5560
+ code: z47.literal("ENCRYPTION_NOT_CONFIGURED"),
5561
+ message: z47.string()
5496
5562
  })
5497
5563
  });
5498
5564
 
@@ -5560,30 +5626,30 @@ var adminCryptoRoutes = {
5560
5626
  import { createRoute as createRoute27 } from "@hono/zod-openapi";
5561
5627
 
5562
5628
  // src/schemas/search.ts
5563
- import { z as z48 } from "@hono/zod-openapi";
5564
- var SearchPageTypeSchema = z48.enum(["portal", "public", "user"]);
5565
- var SearchPagesRequestSchema = z48.object({
5566
- q: z48.string().min(1),
5567
- tree: z48.string().optional(),
5629
+ import { z as z49 } from "@hono/zod-openapi";
5630
+ var SearchPageTypeSchema = z49.enum(["portal", "public", "user"]);
5631
+ var SearchPagesRequestSchema = z49.object({
5632
+ q: z49.string().min(1),
5633
+ tree: z49.string().optional(),
5568
5634
  type: SearchPageTypeSchema.optional(),
5569
- page: z48.coerce.number().int().min(1).default(1),
5570
- limit: z48.coerce.number().int().min(1).max(100).default(50)
5571
- });
5572
- var SearchHitSchema = z48.object({
5573
- pageId: z48.string(),
5574
- path: z48.string(),
5575
- score: z48.number().optional(),
5576
- snippet: z48.string().optional(),
5577
- bookmarkCount: z48.number(),
5635
+ page: z49.coerce.number().int().min(1).default(1),
5636
+ limit: z49.coerce.number().int().min(1).max(100).default(50)
5637
+ });
5638
+ var SearchHitSchema = z49.object({
5639
+ pageId: z49.string(),
5640
+ path: z49.string(),
5641
+ score: z49.number().optional(),
5642
+ snippet: z49.string().optional(),
5643
+ bookmarkCount: z49.number(),
5578
5644
  page: PageSchema
5579
5645
  });
5580
- var SearchPagesResponseSchema = z48.object({
5581
- meta: z48.object({
5582
- took: z48.number().optional(),
5583
- total: z48.number(),
5584
- results: z48.number()
5646
+ var SearchPagesResponseSchema = z49.object({
5647
+ meta: z49.object({
5648
+ took: z49.number().optional(),
5649
+ total: z49.number(),
5650
+ results: z49.number()
5585
5651
  }),
5586
- data: z48.array(SearchHitSchema)
5652
+ data: z49.array(SearchHitSchema)
5587
5653
  });
5588
5654
 
5589
5655
  // src/contracts/search.ts
@@ -5624,53 +5690,53 @@ var searchRoutes = {
5624
5690
  };
5625
5691
 
5626
5692
  // src/contracts/token-auth.ts
5627
- import { createRoute as createRoute28, z as z50 } from "@hono/zod-openapi";
5693
+ import { createRoute as createRoute28, z as z51 } from "@hono/zod-openapi";
5628
5694
 
5629
5695
  // src/schemas/auth.ts
5630
- import { z as z49 } from "@hono/zod-openapi";
5631
- var TokenAuthLoginRequestSchema = z49.object({
5632
- email: z49.string().email(),
5633
- password: z49.string().min(6)
5634
- });
5635
- var TokenAuthResponseSchema = z49.object({
5636
- accessToken: z49.string(),
5637
- refreshToken: z49.string(),
5638
- expiresIn: z49.number(),
5696
+ import { z as z50 } from "@hono/zod-openapi";
5697
+ var TokenAuthLoginRequestSchema = z50.object({
5698
+ email: z50.string().email(),
5699
+ password: z50.string().min(6)
5700
+ });
5701
+ var TokenAuthResponseSchema = z50.object({
5702
+ accessToken: z50.string(),
5703
+ refreshToken: z50.string(),
5704
+ expiresIn: z50.number(),
5639
5705
  // seconds until expiration
5640
- user: z49.object({
5641
- id: z49.string(),
5642
- username: z49.string(),
5643
- email: z49.string().email(),
5644
- name: z49.string(),
5645
- image: z49.string().optional(),
5646
- admin: z49.boolean().optional()
5706
+ user: z50.object({
5707
+ id: z50.string(),
5708
+ username: z50.string(),
5709
+ email: z50.string().email(),
5710
+ name: z50.string(),
5711
+ image: z50.string().optional(),
5712
+ admin: z50.boolean().optional()
5647
5713
  })
5648
5714
  });
5649
- var RefreshTokenRequestSchema = z49.object({
5650
- refreshToken: z49.string()
5715
+ var RefreshTokenRequestSchema = z50.object({
5716
+ refreshToken: z50.string()
5651
5717
  });
5652
- var TokenAuthRegisterRequestSchema = z49.object({
5653
- username: z49.string(),
5654
- name: z49.string(),
5655
- email: z49.string().email(),
5656
- password: z49.string().min(6)
5718
+ var TokenAuthRegisterRequestSchema = z50.object({
5719
+ username: UsernameSchema,
5720
+ name: z50.string(),
5721
+ email: z50.string().email(),
5722
+ password: z50.string().min(6)
5657
5723
  });
5658
- var RegisterPendingResponseSchema = z49.object({
5659
- status: z49.enum(["confirmation_required", "approval_required"])
5724
+ var RegisterPendingResponseSchema = z50.object({
5725
+ status: z50.enum(["confirmation_required", "approval_required"])
5660
5726
  });
5661
5727
 
5662
5728
  // src/contracts/token-auth.ts
5663
- var TokenLogoutResponseSchema = z50.object({ message: z50.string() });
5664
- var TokenMeResponseSchema = z50.object({
5665
- user: z50.object({
5666
- id: z50.string(),
5667
- username: z50.string(),
5668
- email: z50.string().email(),
5669
- name: z50.string(),
5670
- image: z50.string().optional(),
5671
- status: z50.number(),
5672
- admin: z50.boolean().optional(),
5673
- createdAt: z50.string()
5729
+ var TokenLogoutResponseSchema = z51.object({ message: z51.string() });
5730
+ var TokenMeResponseSchema = z51.object({
5731
+ user: z51.object({
5732
+ id: z51.string(),
5733
+ username: z51.string(),
5734
+ email: z51.string().email(),
5735
+ name: z51.string(),
5736
+ image: z51.string().optional(),
5737
+ status: z51.number(),
5738
+ admin: z51.boolean().optional(),
5739
+ createdAt: z51.string()
5674
5740
  })
5675
5741
  });
5676
5742
  var tokenLoginRoute = createRoute28({
@@ -5798,7 +5864,7 @@ var tokenLogoutRoute = createRoute28({
5798
5864
  body: {
5799
5865
  content: {
5800
5866
  "application/json": {
5801
- schema: z50.object({ refreshToken: z50.string().optional() })
5867
+ schema: z51.object({ refreshToken: z51.string().optional() })
5802
5868
  }
5803
5869
  }
5804
5870
  }
@@ -5847,23 +5913,404 @@ var tokenAuthRoutes = {
5847
5913
  tokenMeRoute
5848
5914
  };
5849
5915
 
5916
+ // src/contracts/federated-auth.ts
5917
+ import { createRoute as createRoute29, z as z53 } from "@hono/zod-openapi";
5918
+
5919
+ // src/schemas/federated-auth.ts
5920
+ import { z as z52 } from "@hono/zod-openapi";
5921
+ var FederatedProviderSchema = z52.object({
5922
+ name: z52.string(),
5923
+ buttonLabel: z52.string(),
5924
+ iconUrl: z52.string().optional()
5925
+ });
5926
+ var ProviderListResponseSchema = z52.object({
5927
+ providers: z52.array(FederatedProviderSchema)
5928
+ });
5929
+ var SenderPublicJwkSchema = z52.object({
5930
+ kty: z52.literal("EC"),
5931
+ crv: z52.literal("P-256"),
5932
+ x: z52.string(),
5933
+ y: z52.string()
5934
+ });
5935
+ var SenderProofSchema = z52.object({
5936
+ publicJwk: SenderPublicJwkSchema,
5937
+ /** base64url ES256 signature over the canonical handoff message. */
5938
+ signature: z52.string()
5939
+ });
5940
+ var FederatedHandoffRequestSchema = z52.object({
5941
+ code: z52.string(),
5942
+ proof: SenderProofSchema
5943
+ });
5944
+ var FederatedHandoffResponseSchema = TokenAuthResponseSchema;
5945
+ var LinkedAuthProviderListResponseSchema = z52.object({
5946
+ identities: z52.array(z52.object({ provider: z52.string() }))
5947
+ });
5948
+ var CreateLinkGrantRequestSchema = z52.object({
5949
+ /** RFC 7638 thumbprint of the P-256 public key this browser will use at `/start` — binds the grant to this browser (AC-2). */
5950
+ handoffChallenge: z52.string().min(1)
5951
+ });
5952
+ var CreateLinkGrantResponseSchema = z52.object({
5953
+ linkGrant: z52.string()
5954
+ });
5955
+ var UnlinkAuthProviderErrorSchema = z52.object({
5956
+ error: z52.object({
5957
+ code: z52.enum(["FEDERATED_UNLINK_DISABLED", "PASSWORD_REQUIRED"]),
5958
+ message: z52.string()
5959
+ })
5960
+ });
5961
+
5962
+ // src/contracts/federated-auth.ts
5963
+ var ContinuePathSchema = z53.string().regex(/^\/(?!\/)[^\\\x00-\x1F\x7F]*$/, 'continue must be a local path starting with a single "/" and contain no backslash or control characters').max(2e3, "continue must be at most 2000 characters");
5964
+ var listFederatedProvidersRoute = createRoute29({
5965
+ method: "get",
5966
+ path: "/auth/providers",
5967
+ tags: ["federatedAuth"],
5968
+ summary: "List enabled OAuth2/OIDC federated sign-in providers",
5969
+ responses: {
5970
+ 200: {
5971
+ description: "Enabled providers, in name order",
5972
+ content: { "application/json": { schema: ProviderListResponseSchema } }
5973
+ },
5974
+ 500: {
5975
+ description: "Internal server error",
5976
+ content: { "application/json": { schema: InternalServerErrorSchema } }
5977
+ }
5978
+ }
5979
+ });
5980
+ var startFederatedProviderRoute = createRoute29({
5981
+ method: "get",
5982
+ path: "/auth/providers/{name}/start",
5983
+ tags: ["federatedAuth"],
5984
+ summary: "Top-level navigation that redirects the browser to the named provider",
5985
+ request: {
5986
+ params: z53.object({ name: z53.string() }),
5987
+ query: z53.object({
5988
+ continue: ContinuePathSchema,
5989
+ /** base64url(JSON) of the sender's P-256 public JWK. */
5990
+ handoff_jwk: z53.string().min(1),
5991
+ /** base64url ES256 signature over the start canonical message. */
5992
+ handoff_proof: z53.string().min(1),
5993
+ /**
5994
+ * RFC-0014 phase 3 — `'1'` switches this start into LINK mode: the
5995
+ * request must carry a web-session JWT, and the flow attaches the
5996
+ * resulting identity to that session's user instead of signing
5997
+ * anyone in. Absent (the ordinary sign-in start) the route stays
5998
+ * fully public.
5999
+ */
6000
+ link: z53.literal("1").optional(),
6001
+ /** The opaque id from `POST /auth/providers/{name}/link-grants`. Required when `link=1`, ignored otherwise. */
6002
+ link_grant: z53.string().min(1).optional()
6003
+ })
6004
+ },
6005
+ responses: {
6006
+ 302: { description: "Redirect to the provider authorization endpoint" },
6007
+ 400: {
6008
+ description: "Malformed continue / sender proof, or an invalid/expired/mismatched link grant",
6009
+ content: { "application/json": { schema: ApiErrorSchema } }
6010
+ },
6011
+ 401: {
6012
+ description: "link=1 without a web-session JWT \u2014 never downgraded to the public sign-in start",
6013
+ content: { "application/json": { schema: ApiErrorSchema } }
6014
+ },
6015
+ 403: {
6016
+ description: "link=1 with a non-web credential (PAT / OAuth access token)",
6017
+ content: { "application/json": { schema: ApiErrorSchema } }
6018
+ },
6019
+ 404: {
6020
+ description: "Unknown, unconfigured, or credential-kind provider",
6021
+ content: { "application/json": { schema: ApiErrorSchema } }
6022
+ },
6023
+ 500: {
6024
+ description: "Internal server error",
6025
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6026
+ }
6027
+ }
6028
+ });
6029
+ var listLinkedAuthProvidersRoute = createRoute29({
6030
+ method: "get",
6031
+ path: "/auth/providers/identities",
6032
+ tags: ["federatedAuth"],
6033
+ summary: "List the provider slugs the current user has linked",
6034
+ responses: {
6035
+ 200: {
6036
+ description: "Linked provider slugs, in name order",
6037
+ content: { "application/json": { schema: LinkedAuthProviderListResponseSchema } }
6038
+ },
6039
+ 401: {
6040
+ description: "Authentication required",
6041
+ content: { "application/json": { schema: AuthenticationRequiredErrorSchema } }
6042
+ },
6043
+ 500: {
6044
+ description: "Internal server error",
6045
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6046
+ }
6047
+ }
6048
+ });
6049
+ var createAuthProviderLinkGrantRoute = createRoute29({
6050
+ method: "post",
6051
+ path: "/auth/providers/{name}/link-grants",
6052
+ tags: ["federatedAuth"],
6053
+ summary: "Mint a short-lived, opaque grant that authorizes ONE link start for the current web session",
6054
+ request: {
6055
+ params: z53.object({ name: z53.string() }),
6056
+ body: { content: { "application/json": { schema: CreateLinkGrantRequestSchema } } }
6057
+ },
6058
+ responses: {
6059
+ 200: {
6060
+ description: "Opaque single-use grant id",
6061
+ content: { "application/json": { schema: CreateLinkGrantResponseSchema } }
6062
+ },
6063
+ 401: {
6064
+ description: "Authentication required",
6065
+ content: { "application/json": { schema: AuthenticationRequiredErrorSchema } }
6066
+ },
6067
+ 403: {
6068
+ description: "Non-web credential (PAT / OAuth access token)",
6069
+ content: { "application/json": { schema: ApiErrorSchema } }
6070
+ },
6071
+ 404: {
6072
+ description: "Unknown, unconfigured, or credential-kind provider",
6073
+ content: { "application/json": { schema: ApiErrorSchema } }
6074
+ },
6075
+ 500: {
6076
+ description: "Internal server error",
6077
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6078
+ }
6079
+ }
6080
+ });
6081
+ var unlinkAuthProviderRoute = createRoute29({
6082
+ method: "delete",
6083
+ path: "/auth/providers/{name}/identity",
6084
+ tags: ["federatedAuth"],
6085
+ summary: "Disconnect the current user's identity for this provider",
6086
+ request: {
6087
+ params: z53.object({ name: z53.string() })
6088
+ },
6089
+ responses: {
6090
+ 204: { description: "Identity removed" },
6091
+ 401: {
6092
+ description: "Authentication required",
6093
+ content: { "application/json": { schema: AuthenticationRequiredErrorSchema } }
6094
+ },
6095
+ 403: {
6096
+ description: "Non-web credential (PAT / OAuth access token)",
6097
+ content: { "application/json": { schema: ApiErrorSchema } }
6098
+ },
6099
+ 404: {
6100
+ description: "No identity linked for this provider",
6101
+ content: { "application/json": { schema: ApiErrorSchema } }
6102
+ },
6103
+ 409: {
6104
+ description: "Refused: password auth is disabled instance-wide, or this user has no password set",
6105
+ content: { "application/json": { schema: UnlinkAuthProviderErrorSchema } }
6106
+ },
6107
+ 500: {
6108
+ description: "Internal server error",
6109
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6110
+ }
6111
+ }
6112
+ });
6113
+ var callbackFederatedProviderRoute = createRoute29({
6114
+ method: "get",
6115
+ path: "/auth/providers/{name}/callback",
6116
+ tags: ["federatedAuth"],
6117
+ summary: "Provider redirect target; completes the OAuth2/OIDC exchange",
6118
+ request: {
6119
+ params: z53.object({ name: z53.string() }),
6120
+ query: z53.object({
6121
+ code: z53.string().optional(),
6122
+ state: z53.string().optional(),
6123
+ error: z53.string().optional()
6124
+ })
6125
+ },
6126
+ responses: {
6127
+ 302: {
6128
+ description: "Redirect to the trusted web login/complete page on success, or back to the trusted web /login on failure"
6129
+ },
6130
+ 404: {
6131
+ description: "Unknown or unconfigured provider (also used when trusted origins cannot be resolved)",
6132
+ content: { "application/json": { schema: ApiErrorSchema } }
6133
+ },
6134
+ 500: {
6135
+ description: "Internal server error",
6136
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6137
+ }
6138
+ }
6139
+ });
6140
+ var federatedHandoffRoute = createRoute29({
6141
+ method: "post",
6142
+ path: "/auth/handoff",
6143
+ tags: ["federatedAuth"],
6144
+ summary: "Exchange a sender-constrained federated handoff code for session tokens",
6145
+ request: {
6146
+ body: { content: { "application/json": { schema: FederatedHandoffRequestSchema } } }
6147
+ },
6148
+ responses: {
6149
+ 200: {
6150
+ description: "Session tokens \u2014 same shape as POST /auth/login",
6151
+ content: { "application/json": { schema: FederatedHandoffResponseSchema } }
6152
+ },
6153
+ 401: {
6154
+ description: "Invalid / expired handoff code, or sender proof did not verify",
6155
+ content: { "application/json": { schema: ApiErrorSchema } }
6156
+ },
6157
+ 409: {
6158
+ description: "Handoff code already consumed",
6159
+ content: { "application/json": { schema: ApiErrorSchema } }
6160
+ },
6161
+ 500: {
6162
+ description: "Internal server error",
6163
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6164
+ }
6165
+ }
6166
+ });
6167
+ var federatedAuthRoutes = {
6168
+ listFederatedProvidersRoute,
6169
+ startFederatedProviderRoute,
6170
+ callbackFederatedProviderRoute,
6171
+ federatedHandoffRoute,
6172
+ listLinkedAuthProvidersRoute,
6173
+ createAuthProviderLinkGrantRoute,
6174
+ unlinkAuthProviderRoute
6175
+ };
6176
+
6177
+ // src/contracts/federated-registration.ts
6178
+ import { createRoute as createRoute30, z as z55 } from "@hono/zod-openapi";
6179
+
6180
+ // src/schemas/federated-registration.ts
6181
+ import { z as z54 } from "@hono/zod-openapi";
6182
+ var FederatedRegistrationSnapshotSchema = z54.object({
6183
+ /** IdP-verified email, prefilled read-only on the registration screen. */
6184
+ email: z54.string().email(),
6185
+ /** Driver slug, e.g. `'google'`. */
6186
+ provider: z54.string(),
6187
+ /** Human-friendly provider name (the driver's `buttonLabel`), e.g. `'Google'`. */
6188
+ providerLabel: z54.string(),
6189
+ /**
6190
+ * This grant's registration has already been submitted and is waiting
6191
+ * for an administrator (Restricted mode). The screen must show that
6192
+ * state instead of the username form.
6193
+ *
6194
+ * Deliberately narrow: it is not a general status field, and it never
6195
+ * distinguishes unknown / expired / cancelled / completed grants (those
6196
+ * are all the same 404 — AC-2). It exists because a submitted
6197
+ * registration is still readable by its own grant, and re-offering an
6198
+ * editable username there invites a change that cannot be applied — the
6199
+ * second submit is refused and the typed value silently discarded.
6200
+ */
6201
+ approvalPending: z54.boolean()
6202
+ });
6203
+ var FederatedRegistrationSubmitRequestSchema = z54.object({
6204
+ username: UsernameSchema
6205
+ });
6206
+ var FederatedRegistrationActiveResultSchema = z54.object({
6207
+ status: z54.literal("active"),
6208
+ code: z54.string()
6209
+ });
6210
+ var FederatedRegistrationApprovalResultSchema = z54.object({
6211
+ status: z54.literal("approval_required")
6212
+ });
6213
+ var FederatedRegistrationResultSchema = z54.discriminatedUnion("status", [
6214
+ FederatedRegistrationActiveResultSchema,
6215
+ FederatedRegistrationApprovalResultSchema
6216
+ ]);
6217
+
6218
+ // src/contracts/federated-registration.ts
6219
+ var TokenParamSchema = z55.object({ token: z55.string().min(1) });
6220
+ var getFederatedRegistrationRoute = createRoute30({
6221
+ method: "get",
6222
+ path: "/auth/federated-registration/{token}",
6223
+ tags: ["federatedRegistration"],
6224
+ summary: "Read-only snapshot (email/provider/providerLabel) for a pending federated registration",
6225
+ request: {
6226
+ params: TokenParamSchema
6227
+ },
6228
+ responses: {
6229
+ 200: {
6230
+ description: "Pending registration snapshot",
6231
+ content: { "application/json": { schema: FederatedRegistrationSnapshotSchema } }
6232
+ },
6233
+ 404: {
6234
+ description: "Grant is unknown, expired, or cancelled",
6235
+ content: { "application/json": { schema: ApiErrorSchema } }
6236
+ },
6237
+ 500: {
6238
+ description: "Internal server error",
6239
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6240
+ }
6241
+ }
6242
+ });
6243
+ var submitFederatedRegistrationRoute = createRoute30({
6244
+ method: "post",
6245
+ path: "/auth/federated-registration/{token}",
6246
+ tags: ["federatedRegistration"],
6247
+ summary: "Submit the chosen username; provisions the User (JIT) and activates or queues approval",
6248
+ request: {
6249
+ params: TokenParamSchema,
6250
+ body: { content: { "application/json": { schema: FederatedRegistrationSubmitRequestSchema } } }
6251
+ },
6252
+ responses: {
6253
+ 200: {
6254
+ description: "Open: account is active \u2014 a Phase 1 handoff code, redeemed via POST /auth/handoff. Restricted: awaiting admin approval.",
6255
+ content: { "application/json": { schema: FederatedRegistrationResultSchema } }
6256
+ },
6257
+ 400: {
6258
+ description: "Username fails the shared username contract",
6259
+ content: { "application/json": { schema: ApiErrorSchema } }
6260
+ },
6261
+ 404: {
6262
+ description: "Grant is unknown, expired, or cancelled",
6263
+ content: { "application/json": { schema: ApiErrorSchema } }
6264
+ },
6265
+ 409: {
6266
+ description: "Username/email already taken, or the identity is already linked to a different user",
6267
+ content: { "application/json": { schema: ApiErrorSchema } }
6268
+ },
6269
+ 500: {
6270
+ description: "Internal server error",
6271
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6272
+ }
6273
+ }
6274
+ });
6275
+ var logoutFederatedRegistrationRoute = createRoute30({
6276
+ method: "post",
6277
+ path: "/auth/federated-registration/{token}/logout",
6278
+ tags: ["federatedRegistration"],
6279
+ summary: "Cancel a pending federated registration and invalidate the grant",
6280
+ request: {
6281
+ params: TokenParamSchema
6282
+ },
6283
+ responses: {
6284
+ 204: { description: "Grant cancelled (or was already inactive) \u2014 idempotent" },
6285
+ 500: {
6286
+ description: "Internal server error",
6287
+ content: { "application/json": { schema: InternalServerErrorSchema } }
6288
+ }
6289
+ }
6290
+ });
6291
+ var federatedRegistrationRoutes = {
6292
+ getFederatedRegistrationRoute,
6293
+ submitFederatedRegistrationRoute,
6294
+ logoutFederatedRegistrationRoute
6295
+ };
6296
+
5850
6297
  // src/contracts/invite-accept.ts
5851
- import { createRoute as createRoute29 } from "@hono/zod-openapi";
6298
+ import { createRoute as createRoute31 } from "@hono/zod-openapi";
5852
6299
 
5853
6300
  // src/schemas/invite-accept.ts
5854
- import { z as z51 } from "@hono/zod-openapi";
5855
- var InviteAcceptRequestSchema = z51.object({
5856
- token: z51.string(),
5857
- username: z51.string().min(1),
5858
- name: z51.string().min(1),
5859
- password: z51.string().min(6)
6301
+ import { z as z56 } from "@hono/zod-openapi";
6302
+ var InviteAcceptRequestSchema = z56.object({
6303
+ token: z56.string(),
6304
+ username: UsernameSchema,
6305
+ name: z56.string().min(1),
6306
+ password: z56.string().min(6)
5860
6307
  });
5861
- var InvitePreviewResponseSchema = z51.object({
5862
- email: z51.string().email()
6308
+ var InvitePreviewResponseSchema = z56.object({
6309
+ email: z56.string().email()
5863
6310
  });
5864
6311
 
5865
6312
  // src/contracts/invite-accept.ts
5866
- var invitePreviewRoute = createRoute29({
6313
+ var invitePreviewRoute = createRoute31({
5867
6314
  method: "get",
5868
6315
  path: "/invite/accept",
5869
6316
  tags: ["inviteAccept"],
@@ -5890,7 +6337,7 @@ var invitePreviewRoute = createRoute29({
5890
6337
  }
5891
6338
  }
5892
6339
  });
5893
- var acceptInviteRoute = createRoute29({
6340
+ var acceptInviteRoute = createRoute31({
5894
6341
  method: "post",
5895
6342
  path: "/invite/accept",
5896
6343
  tags: ["inviteAccept"],
@@ -5933,23 +6380,23 @@ var inviteAcceptRoutes = {
5933
6380
  };
5934
6381
 
5935
6382
  // src/contracts/password-reset.ts
5936
- import { createRoute as createRoute30 } from "@hono/zod-openapi";
6383
+ import { createRoute as createRoute32 } from "@hono/zod-openapi";
5937
6384
 
5938
6385
  // src/schemas/password-reset.ts
5939
- import { z as z52 } from "@hono/zod-openapi";
5940
- var ForgotPasswordRequestSchema = z52.object({
5941
- email: z52.string().email()
6386
+ import { z as z57 } from "@hono/zod-openapi";
6387
+ var ForgotPasswordRequestSchema = z57.object({
6388
+ email: z57.string().email()
5942
6389
  });
5943
- var ForgotPasswordResponseSchema = z52.object({
5944
- ok: z52.literal(true)
6390
+ var ForgotPasswordResponseSchema = z57.object({
6391
+ ok: z57.literal(true)
5945
6392
  });
5946
- var ResetPasswordRequestSchema = z52.object({
5947
- token: z52.string(),
5948
- password: z52.string().min(6)
6393
+ var ResetPasswordRequestSchema = z57.object({
6394
+ token: z57.string(),
6395
+ password: z57.string().min(6)
5949
6396
  });
5950
6397
 
5951
6398
  // src/contracts/password-reset.ts
5952
- var forgotPasswordRoute = createRoute30({
6399
+ var forgotPasswordRoute = createRoute32({
5953
6400
  method: "post",
5954
6401
  path: "/auth/forgot-password",
5955
6402
  tags: ["passwordReset"],
@@ -5974,7 +6421,7 @@ var forgotPasswordRoute = createRoute30({
5974
6421
  }
5975
6422
  }
5976
6423
  });
5977
- var validateResetTokenRoute = createRoute30({
6424
+ var validateResetTokenRoute = createRoute32({
5978
6425
  method: "get",
5979
6426
  path: "/auth/reset-password",
5980
6427
  tags: ["passwordReset"],
@@ -5997,7 +6444,7 @@ var validateResetTokenRoute = createRoute30({
5997
6444
  }
5998
6445
  }
5999
6446
  });
6000
- var selfResetPasswordRoute = createRoute30({
6447
+ var selfResetPasswordRoute = createRoute32({
6001
6448
  method: "post",
6002
6449
  path: "/auth/reset-password",
6003
6450
  tags: ["passwordReset"],
@@ -6037,19 +6484,19 @@ var passwordResetRoutes = {
6037
6484
  };
6038
6485
 
6039
6486
  // src/contracts/activation.ts
6040
- import { createRoute as createRoute31 } from "@hono/zod-openapi";
6487
+ import { createRoute as createRoute33 } from "@hono/zod-openapi";
6041
6488
 
6042
6489
  // src/schemas/activation.ts
6043
- import { z as z53 } from "@hono/zod-openapi";
6044
- var ActivateRequestSchema = z53.object({
6045
- token: z53.string()
6490
+ import { z as z58 } from "@hono/zod-openapi";
6491
+ var ActivateRequestSchema = z58.object({
6492
+ token: z58.string()
6046
6493
  });
6047
- var ActivateValidationResponseSchema = z53.object({
6048
- ok: z53.literal(true)
6494
+ var ActivateValidationResponseSchema = z58.object({
6495
+ ok: z58.literal(true)
6049
6496
  });
6050
6497
 
6051
6498
  // src/contracts/activation.ts
6052
- var validateActivationTokenRoute = createRoute31({
6499
+ var validateActivationTokenRoute = createRoute33({
6053
6500
  method: "get",
6054
6501
  path: "/auth/activate",
6055
6502
  tags: ["activation"],
@@ -6072,7 +6519,7 @@ var validateActivationTokenRoute = createRoute31({
6072
6519
  }
6073
6520
  }
6074
6521
  });
6075
- var activateAccountRoute = createRoute31({
6522
+ var activateAccountRoute = createRoute33({
6076
6523
  method: "post",
6077
6524
  path: "/auth/activate",
6078
6525
  tags: ["activation"],
@@ -6107,21 +6554,21 @@ var activationRoutes = {
6107
6554
  };
6108
6555
 
6109
6556
  // src/contracts/email-change.ts
6110
- import { createRoute as createRoute32 } from "@hono/zod-openapi";
6557
+ import { createRoute as createRoute34 } from "@hono/zod-openapi";
6111
6558
 
6112
6559
  // src/schemas/email-change.ts
6113
- import { z as z54 } from "@hono/zod-openapi";
6114
- var ConfirmEmailChangeRequestSchema = z54.object({
6115
- token: z54.string()
6560
+ import { z as z59 } from "@hono/zod-openapi";
6561
+ var ConfirmEmailChangeRequestSchema = z59.object({
6562
+ token: z59.string()
6116
6563
  });
6117
- var ConfirmEmailChangeResponseSchema = z54.object({
6118
- ok: z54.literal(true),
6564
+ var ConfirmEmailChangeResponseSchema = z59.object({
6565
+ ok: z59.literal(true),
6119
6566
  /** The newly-confirmed email address. */
6120
- email: z54.string().email()
6567
+ email: z59.string().email()
6121
6568
  });
6122
6569
 
6123
6570
  // src/contracts/email-change.ts
6124
- var validateEmailChangeTokenRoute = createRoute32({
6571
+ var validateEmailChangeTokenRoute = createRoute34({
6125
6572
  method: "get",
6126
6573
  path: "/auth/confirm-email-change",
6127
6574
  tags: ["emailChange"],
@@ -6144,7 +6591,7 @@ var validateEmailChangeTokenRoute = createRoute32({
6144
6591
  }
6145
6592
  }
6146
6593
  });
6147
- var confirmEmailChangeRoute = createRoute32({
6594
+ var confirmEmailChangeRoute = createRoute34({
6148
6595
  method: "post",
6149
6596
  path: "/auth/confirm-email-change",
6150
6597
  tags: ["emailChange"],
@@ -6183,9 +6630,9 @@ var emailChangeRoutes = {
6183
6630
  };
6184
6631
 
6185
6632
  // src/contracts/user.ts
6186
- import { createRoute as createRoute33, z as z55 } from "@hono/zod-openapi";
6187
- var UsernameParamSchema = z55.object({ username: z55.string() });
6188
- var getUserPageRoute = createRoute33({
6633
+ import { createRoute as createRoute35, z as z60 } from "@hono/zod-openapi";
6634
+ var UsernameParamSchema = z60.object({ username: z60.string() });
6635
+ var getUserPageRoute = createRoute35({
6189
6636
  method: "get",
6190
6637
  path: "/user/{username}",
6191
6638
  tags: ["user"],
@@ -6213,7 +6660,7 @@ var getUserPageRoute = createRoute33({
6213
6660
  }
6214
6661
  }
6215
6662
  });
6216
- var getUserBookmarksRoute = createRoute33({
6663
+ var getUserBookmarksRoute = createRoute35({
6217
6664
  method: "get",
6218
6665
  path: "/user/{username}/bookmarks",
6219
6666
  tags: ["user"],
@@ -6242,7 +6689,7 @@ var getUserBookmarksRoute = createRoute33({
6242
6689
  }
6243
6690
  }
6244
6691
  });
6245
- var getUserPagesRoute = createRoute33({
6692
+ var getUserPagesRoute = createRoute35({
6246
6693
  method: "get",
6247
6694
  path: "/user/{username}/pages",
6248
6695
  tags: ["user"],
@@ -6271,7 +6718,7 @@ var getUserPagesRoute = createRoute33({
6271
6718
  }
6272
6719
  }
6273
6720
  });
6274
- var getUserSubpagesRoute = createRoute33({
6721
+ var getUserSubpagesRoute = createRoute35({
6275
6722
  method: "get",
6276
6723
  path: "/user/{username}/subpages",
6277
6724
  tags: ["user"],
@@ -6308,7 +6755,7 @@ var getUserSubpagesRoute = createRoute33({
6308
6755
  }
6309
6756
  }
6310
6757
  });
6311
- var listMembersRoute = createRoute33({
6758
+ var listMembersRoute = createRoute35({
6312
6759
  method: "get",
6313
6760
  path: "/users",
6314
6761
  tags: ["user"],
@@ -6354,6 +6801,13 @@ var stubTokens = {
6354
6801
  expiresIn: 0,
6355
6802
  user: stubUser
6356
6803
  };
6804
+ var stubProviderList = { providers: [] };
6805
+ var stubFederatedRegistrationSnapshot = {
6806
+ email: "stub@example.com",
6807
+ provider: "",
6808
+ providerLabel: "",
6809
+ approvalPending: false
6810
+ };
6357
6811
  var stubProfile = {
6358
6812
  id: "",
6359
6813
  username: "",
@@ -6363,7 +6817,8 @@ var stubProfile = {
6363
6817
  theme: "system",
6364
6818
  image: null,
6365
6819
  hasPassword: false,
6366
- createdAt: ""
6820
+ createdAt: "",
6821
+ federated: false
6367
6822
  };
6368
6823
  var stubAccessToken = {
6369
6824
  id: "",
@@ -6602,6 +7057,7 @@ var stubPendingUsersCount = { count: 0 };
6602
7057
  var stubListPlugins = { plugins: [] };
6603
7058
  var stubPluginConfig = { name: "", fields: [], values: {} };
6604
7059
  var stubUpdatePluginConfig = { ok: true, hotReloaded: false, reconfigureFailed: false };
7060
+ var stubPluginReadiness = { issues: [] };
6605
7061
  var stubClearRenderCache = { ok: true, clearedAt: "", removedCount: 0 };
6606
7062
  var appAuthMeUserChain = new OpenAPIHono().openapi(
6607
7063
  appRoutes.getAppInfoRoute,
@@ -6641,27 +7097,29 @@ var bookmarkBacklinkCommentRevisionChain = new OpenAPIHono().openapi(bookmarkRou
6641
7097
  var pageChain = new OpenAPIHono().openapi(pageRoutes.getPageRoute, (c) => c.json(stubPageWithRevision, 200)).openapi(pageRoutes.listPagesRoute, (c) => c.json(stubListPages, 200)).openapi(pageRoutes.listPageChildrenRoute, (c) => c.json(stubListPageChildren, 200)).openapi(pageRoutes.createPageRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.updatePageRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.setPageGrantRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.seenPageRoute, (c) => c.json(stubSeenUsers, 200)).openapi(pageRoutes.getSeenUsersRoute, (c) => c.json(stubSeenUsers, 200)).openapi(pageRoutes.likePageRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.unlikePageRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.claimPageLinkAccessRoute, (c) => c.json({ ...stubPageWithRevision, granted: false }, 200)).openapi(pageRoutes.getWatchStatusRoute, (c) => c.json(stubWatchStatus, 200)).openapi(pageRoutes.setWatchStatusRoute, (c) => c.json(stubWatchStatus, 200)).openapi(pageRoutes.deletePageRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.revertDeletedPageRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.revertToRevisionRoute, (c) => c.json(stubPageResponse, 200)).openapi(pageRoutes.renamePageRoute, (c) => c.json({ ...stubPageResponse, renamed_count: 1 }, 200)).openapi(pageRoutes.renameSubtreeRoute, (c) => c.json({ renamed_count: 0 }, 200)).openapi(pagePreviewRoutes.previewPageRoute, (c) => c.json(stubPreview, 200)).openapi(pageCollabRoutes.getYjsTokenRoute, (c) => c.json(stubWsToken, 200)).openapi(presenceRoutes.getPresenceTokenRoute, (c) => c.json(stubPresenceToken, 200)).openapi(presenceRoutes.getLikersRoute, (c) => c.json(stubLikers, 200));
6642
7098
  var lateContractApp = new OpenAPIHono().openapi(draftRoutes.createDraftRoute, (c) => c.json(stubCreateDraft, 201)).openapi(draftRoutes.listDraftsRoute, (c) => c.json(stubListDrafts, 200)).openapi(draftRoutes.cancelDraftRoute, (c) => c.json(stubCreateDraft, 200)).openapi(autocompleteRoutes.autocompleteUsersRoute, (c) => c.json(stubAutocomplete, 200)).openapi(autocompleteRoutes.autocompletePagesRoute, (c) => c.json(stubAutocomplete, 200)).openapi(attachmentRoutes.getAttachmentUsageRoute, (c) => c.json(stubAttachmentUsage, 200)).openapi(attachmentRoutes.listAttachmentsRoute, (c) => c.json(stubListAttachments, 200)).openapi(attachmentRoutes.addAttachmentRoute, (c) => c.json(stubAddAttachment, 200)).openapi(attachmentRoutes.uploadAttachmentRoute, (c) => c.json(stubUploadAttachment, 200)).openapi(attachmentRoutes.getAttachmentMetaRoute, (c) => c.json(stubAttachmentMeta, 200)).openapi(attachmentRoutes.removeAttachmentRoute, (c) => c.json(stubRemoveAttachment, 200)).openapi(searchRoutes.searchPagesRoute, (c) => c.json(stubSearchPages, 200)).openapi(adminCryptoRoutes.getCryptoStatusRoute, (c) => c.json(stubCryptoStatus, 200)).openapi(adminCryptoRoutes.reencryptAllRoute, (c) => c.json(stubReencrypt, 200)).openapi(notificationRoutes.listNotificationsRoute, (c) => c.json(stubListNotifications, 200)).openapi(notificationRoutes.markAllAsReadRoute, (c) => c.json(stubMarkAllAsRead, 200)).openapi(notificationRoutes.getNotificationsTokenRoute, (c) => c.json(stubNotificationsToken, 200)).openapi(notificationRoutes.getUnreadCountRoute, (c) => c.json(stubNotificationStatus, 200)).openapi(notificationRoutes.openNotificationRoute, (c) => c.json(stubOpenNotification, 200));
6643
7099
  var adminSettingsContractApp = new OpenAPIHono().openapi(adminAppRoutes.getAppSettingsRoute, (c) => c.json(stubGetAppSettings, 200)).openapi(adminAppRoutes.updateAppSettingsRoute, (c) => c.json(stubUpdateAppSettings, 200)).openapi(adminAuthRoutes.getAuthSettingsRoute, (c) => c.json(stubAuthSettings, 200)).openapi(adminAuthRoutes.updateAuthSettingsRoute, (c) => c.json(stubAuthSettings, 200)).openapi(adminSecurityRoutes.getSecuritySettingsRoute, (c) => c.json(stubSecuritySettings, 200)).openapi(adminSecurityRoutes.updateSecuritySettingsRoute, (c) => c.json(stubSecuritySettings, 200)).openapi(adminMailRoutes.getMailSettingsRoute, (c) => c.json(stubMailSettings, 200)).openapi(adminMailRoutes.updateMailSettingsRoute, (c) => c.json(stubUpdateMailSettings, 200)).openapi(adminMailRoutes.sendTestMailRoute, (c) => c.json(stubSendTestMail, 200)).openapi(adminStorageRoutes.getStorageStatusRoute, (c) => c.json(stubStorageStatus, 200)).openapi(adminSearchRoutes.getSearchStatusRoute, (c) => c.json(stubSearchStatus, 200));
6644
- var adminUsersPluginsContractApp = new OpenAPIHono().openapi(adminUsersRoutes.listUsersRoute, (c) => c.json(stubListAdminUsers, 200)).openapi(adminUsersRoutes.searchUsersByEmailRoute, (c) => c.json(stubSearchAdminUsersByEmail, 200)).openapi(adminUsersRoutes.pendingUsersCountRoute, (c) => c.json(stubPendingUsersCount, 200)).openapi(adminUsersRoutes.inviteUsersRoute, (c) => c.json(stubInviteUsers, 200)).openapi(adminUsersRoutes.editUserRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.makeAdminRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.removeFromAdminRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.activateUserRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.suspendUserRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.resetPasswordRoute, (c) => c.json(stubResetPassword, 200)).openapi(adminUsersRoutes.resendInviteRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.updateUserEmailRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.deleteUserRoute, (c) => c.json(stubDeleteAdminUser, 200)).openapi(adminPluginsRoutes.listPluginsRoute, (c) => c.json(stubListPlugins, 200)).openapi(adminPluginsRoutes.getPluginConfigRoute, (c) => c.json(stubPluginConfig, 200)).openapi(adminPluginsRoutes.updatePluginConfigRoute, (c) => c.json(stubUpdatePluginConfig, 200)).openapi(adminPluginsRoutes.clearRenderCacheAllRoute, (c) => c.json(stubClearRenderCache, 200)).openapi(adminPluginsRoutes.clearRenderCachePluginRoute, (c) => c.json(stubClearRenderCache, 200));
7100
+ var adminUsersPluginsContractApp = new OpenAPIHono().openapi(adminUsersRoutes.listUsersRoute, (c) => c.json(stubListAdminUsers, 200)).openapi(adminUsersRoutes.searchUsersByEmailRoute, (c) => c.json(stubSearchAdminUsersByEmail, 200)).openapi(adminUsersRoutes.pendingUsersCountRoute, (c) => c.json(stubPendingUsersCount, 200)).openapi(adminUsersRoutes.inviteUsersRoute, (c) => c.json(stubInviteUsers, 200)).openapi(adminUsersRoutes.editUserRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.makeAdminRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.removeFromAdminRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.activateUserRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.suspendUserRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.resetPasswordRoute, (c) => c.json(stubResetPassword, 200)).openapi(adminUsersRoutes.resendInviteRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.updateUserEmailRoute, (c) => c.json(stubAdminUserMutation, 200)).openapi(adminUsersRoutes.deleteUserRoute, (c) => c.json(stubDeleteAdminUser, 200)).openapi(adminPluginsRoutes.listPluginsRoute, (c) => c.json(stubListPlugins, 200)).openapi(adminPluginsRoutes.getPluginConfigRoute, (c) => c.json(stubPluginConfig, 200)).openapi(adminPluginsRoutes.updatePluginConfigRoute, (c) => c.json(stubUpdatePluginConfig, 200)).openapi(adminPluginsRoutes.getPluginReadinessRoute, (c) => c.json(stubPluginReadiness, 200)).openapi(adminPluginsRoutes.clearRenderCacheAllRoute, (c) => c.json(stubClearRenderCache, 200)).openapi(adminPluginsRoutes.clearRenderCachePluginRoute, (c) => c.json(stubClearRenderCache, 200));
6645
7101
  var oauthContractApp = new OpenAPIHono().openapi(oauthRoutes.authorizeRoute, (c) => c.json(stubAuthorize, 200)).openapi(oauthRoutes.tokenRoute, (c) => c.json(stubToken, 200)).openapi(oauthRoutes.revokeRoute, (c) => c.json(stubRevoke, 200)).openapi(oauthRoutes.discoveryRoute, (c) => c.json(stubDiscovery, 200)).openapi(oauthRoutes.deviceAuthorizeRoute, (c) => c.json(stubDeviceAuthorize, 200)).openapi(oauthRoutes.deviceInfoRoute, (c) => c.json(stubDeviceInfo, 200)).openapi(oauthRoutes.deviceVerifyRoute, (c) => c.json(stubDeviceVerify, 200)).openapi(oauthRoutes.clientInfoRoute, (c) => c.json(stubClientInfo, 200));
7102
+ var federatedAuthContractApp = new OpenAPIHono().openapi(federatedAuthRoutes.listFederatedProvidersRoute, (c) => c.json(stubProviderList, 200)).openapi(federatedAuthRoutes.startFederatedProviderRoute, (c) => c.redirect("", 302)).openapi(federatedAuthRoutes.callbackFederatedProviderRoute, (c) => c.redirect("", 302)).openapi(federatedAuthRoutes.federatedHandoffRoute, (c) => c.json(stubTokens, 200)).openapi(federatedAuthRoutes.listLinkedAuthProvidersRoute, (c) => c.json({ identities: [] }, 200)).openapi(federatedAuthRoutes.createAuthProviderLinkGrantRoute, (c) => c.json({ linkGrant: "" }, 200)).openapi(federatedAuthRoutes.unlinkAuthProviderRoute, (c) => c.body(null, 204));
7103
+ var federatedRegistrationContractApp = new OpenAPIHono().openapi(federatedRegistrationRoutes.getFederatedRegistrationRoute, (c) => c.json(stubFederatedRegistrationSnapshot, 200)).openapi(federatedRegistrationRoutes.submitFederatedRegistrationRoute, (c) => c.json({ status: "approval_required" }, 200)).openapi(federatedRegistrationRoutes.logoutFederatedRegistrationRoute, (c) => c.body(null, 204));
6646
7104
  var createClient = (baseUrl, options = {}) => hc(baseUrl, {
6647
7105
  headers: options.headers,
6648
7106
  fetch: options.fetch
6649
7107
  });
6650
7108
 
6651
7109
  // src/schemas/mail-token.ts
6652
- import { z as z56 } from "@hono/zod-openapi";
6653
- var MailTokenPurposeSchema = z56.enum(["invite", "activate", "reset", "email-change"]);
6654
- var MailTokenPayloadSchema = z56.object({
7110
+ import { z as z61 } from "@hono/zod-openapi";
7111
+ var MailTokenPurposeSchema = z61.enum(["invite", "activate", "reset", "email-change"]);
7112
+ var MailTokenPayloadSchema = z61.object({
6655
7113
  purpose: MailTokenPurposeSchema,
6656
- userId: z56.string(),
7114
+ userId: z61.string(),
6657
7115
  /** Target address. For `email-change` this is the NEW address. */
6658
- email: z56.string().email(),
7116
+ email: z61.string().email(),
6659
7117
  /**
6660
7118
  * For `email-change`: the account's email at issue time. The confirm
6661
7119
  * endpoint rejects the token unless it still matches, making the token
6662
7120
  * single-use (a stale token cannot revert a later change).
6663
7121
  */
6664
- fromEmail: z56.string().email().optional(),
7122
+ fromEmail: z61.string().email().optional(),
6665
7123
  /**
6666
7124
  * For `reset`: the account's `passwordResetGeneration` at issue time.
6667
7125
  * Consuming the link increments that counter, so the token only matches
@@ -6670,7 +7128,7 @@ var MailTokenPayloadSchema = z56.object({
6670
7128
  * schema because the other purposes don't carry it (and links minted
6671
7129
  * before the claim existed simply no longer match).
6672
7130
  */
6673
- resetGeneration: z56.number().int().nonnegative().optional(),
7131
+ resetGeneration: z61.number().int().nonnegative().optional(),
6674
7132
  /**
6675
7133
  * For `email-change`: the account's `authVersion` at issue time. The
6676
7134
  * confirm endpoint requires it to still match, so a pending address change
@@ -6682,10 +7140,22 @@ var MailTokenPayloadSchema = z56.object({
6682
7140
  * semantics wanted are exactly "the session that asked for this is gone",
6683
7141
  * and that is what every bump of it already means.
6684
7142
  */
6685
- authVersion: z56.number().int().nonnegative().optional(),
7143
+ authVersion: z61.number().int().nonnegative().optional(),
7144
+ /**
7145
+ * For `email-change`: the account's `emailChangeGeneration` at issue time.
7146
+ * Requesting a change increments it, so asking for a different address
7147
+ * supersedes any link still pending — which is what lets a user call off a
7148
+ * change they did not want (one an attacker started with a stolen session,
7149
+ * or one sent to a mistyped address). `authVersion` cannot serve this: it
7150
+ * means "the session that asked is gone", and bumping it on a mere request
7151
+ * would log the user out of their own account for editing their profile.
7152
+ * Optional in the schema for the same reason as the others — links minted
7153
+ * before the claim existed simply no longer match.
7154
+ */
7155
+ emailChangeGeneration: z61.number().int().nonnegative().optional(),
6686
7156
  // iat / exp are injected and verified by the JWT layer.
6687
- iat: z56.number().optional(),
6688
- exp: z56.number().optional()
7157
+ iat: z61.number().optional(),
7158
+ exp: z61.number().optional()
6689
7159
  });
6690
7160
 
6691
7161
  // src/util/html-elements.ts
@@ -6900,6 +7370,8 @@ export {
6900
7370
  CommentInvalidRequestErrorSchema,
6901
7371
  CommentNotFoundErrorSchema,
6902
7372
  CommentSchema,
7373
+ ConfigReadinessIssueSchema,
7374
+ ConfigReadinessResponseSchema,
6903
7375
  ConfirmEmailChangeRequestSchema,
6904
7376
  ConfirmEmailChangeResponseSchema,
6905
7377
  ConflictErrorSchema,
@@ -6910,6 +7382,8 @@ export {
6910
7382
  CreateAdminResponseSchema,
6911
7383
  CreateDraftRequestSchema,
6912
7384
  CreateDraftResponseSchema,
7385
+ CreateLinkGrantRequestSchema,
7386
+ CreateLinkGrantResponseSchema,
6913
7387
  CreatePageRequestSchema,
6914
7388
  CrowiCodeSidecarSchema,
6915
7389
  CrowiDiagramNodeSchema,
@@ -6945,6 +7419,14 @@ export {
6945
7419
  EditAdminUserRequestSchema,
6946
7420
  EncryptionNotConfiguredErrorSchema,
6947
7421
  ErrorCodeSchema,
7422
+ FederatedHandoffRequestSchema,
7423
+ FederatedHandoffResponseSchema,
7424
+ FederatedProviderSchema,
7425
+ FederatedRegistrationActiveResultSchema,
7426
+ FederatedRegistrationApprovalResultSchema,
7427
+ FederatedRegistrationResultSchema,
7428
+ FederatedRegistrationSnapshotSchema,
7429
+ FederatedRegistrationSubmitRequestSchema,
6948
7430
  ForbiddenErrorSchema,
6949
7431
  ForgotPasswordRequestSchema,
6950
7432
  ForgotPasswordResponseSchema,
@@ -6986,6 +7468,7 @@ export {
6986
7468
  LanguageSchema,
6987
7469
  LikerSchema,
6988
7470
  LikersResponseSchema,
7471
+ LinkedAuthProviderListResponseSchema,
6989
7472
  ListAccessTokensResponseSchema,
6990
7473
  ListAdminUsersRequestSchema,
6991
7474
  ListAdminUsersResponseSchema,
@@ -7057,6 +7540,7 @@ export {
7057
7540
  PluginFieldSchema,
7058
7541
  PluginInfoSchema,
7059
7542
  PluginNotFoundErrorSchema,
7543
+ PluginReadinessFieldSchema,
7060
7544
  PresenceClientMessageSchema,
7061
7545
  PresenceCommentChangedMessageSchema,
7062
7546
  PresenceHeartbeatMessageSchema,
@@ -7069,6 +7553,7 @@ export {
7069
7553
  PreviewPageRequestSchema,
7070
7554
  PreviewPageResponseSchema,
7071
7555
  ProfileErrorResponseSchema,
7556
+ ProviderListResponseSchema,
7072
7557
  RENDERED_AST_NODE_DEFS,
7073
7558
  RecentlyViewedPagesResponseSchema,
7074
7559
  ReencryptResponseSchema,
@@ -7117,6 +7602,8 @@ export {
7117
7602
  SendTestMailErrorSchema,
7118
7603
  SendTestMailRequestSchema,
7119
7604
  SendTestMailResponseSchema,
7605
+ SenderProofSchema,
7606
+ SenderPublicJwkSchema,
7120
7607
  SensitiveConfigEntrySchema,
7121
7608
  ServiceUnavailableErrorSchema,
7122
7609
  SetPageGrantRequestSchema,
@@ -7137,6 +7624,7 @@ export {
7137
7624
  TokenRequestSchema,
7138
7625
  TokenResponseSchema,
7139
7626
  UPLOAD_ALLOWED_MIME,
7627
+ UnlinkAuthProviderErrorSchema,
7140
7628
  UpdateAdminUserEmailRequestSchema,
7141
7629
  UpdateAppSettingsRequestSchema,
7142
7630
  UpdateAppSettingsResponseSchema,
@@ -7168,6 +7656,7 @@ export {
7168
7656
  UserStatusErrorSchema,
7169
7657
  UserStatusSchema,
7170
7658
  UserSubpagesRequestSchema,
7659
+ UsernameSchema,
7171
7660
  ValidationErrorSchema,
7172
7661
  WS_CLOSE_CODES,
7173
7662
  WatchStatusResponseSchema,
@@ -7199,6 +7688,7 @@ export {
7199
7688
  autocompleteUsersRoute,
7200
7689
  backlinkRoutes,
7201
7690
  bookmarkRoutes,
7691
+ callbackFederatedProviderRoute,
7202
7692
  cancelDraftRoute,
7203
7693
  claimPageLinkAccessRoute,
7204
7694
  clearRenderCacheAllRoute,
@@ -7208,6 +7698,7 @@ export {
7208
7698
  confirmEmailChangeRoute,
7209
7699
  createAccessTokenRoute,
7210
7700
  createAdminRoute,
7701
+ createAuthProviderLinkGrantRoute,
7211
7702
  createClient,
7212
7703
  createDraftRoute,
7213
7704
  createPageRoute,
@@ -7223,6 +7714,9 @@ export {
7223
7714
  draftRoutes,
7224
7715
  editUserRoute,
7225
7716
  emailChangeRoutes,
7717
+ federatedAuthRoutes,
7718
+ federatedHandoffRoute,
7719
+ federatedRegistrationRoutes,
7226
7720
  forgotPasswordRoute,
7227
7721
  getAppInfoRoute,
7228
7722
  getAppSettingsRoute,
@@ -7232,12 +7726,14 @@ export {
7232
7726
  getBacklinksRoute,
7233
7727
  getBookmarkRoute,
7234
7728
  getCryptoStatusRoute,
7729
+ getFederatedRegistrationRoute,
7235
7730
  getInstallerStatusRoute,
7236
7731
  getLikersRoute,
7237
7732
  getMailSettingsRoute,
7238
7733
  getNotificationsTokenRoute,
7239
7734
  getPageRoute,
7240
7735
  getPluginConfigRoute,
7736
+ getPluginReadinessRoute,
7241
7737
  getPresenceTokenRoute,
7242
7738
  getProfileRoute,
7243
7739
  getRevisionRoute,
@@ -7264,6 +7760,8 @@ export {
7264
7760
  listAttachmentsRoute,
7265
7761
  listCommentsRoute,
7266
7762
  listDraftsRoute,
7763
+ listFederatedProvidersRoute,
7764
+ listLinkedAuthProvidersRoute,
7267
7765
  listMembersRoute,
7268
7766
  listMyBookmarksRoute,
7269
7767
  listNotificationsRoute,
@@ -7272,6 +7770,7 @@ export {
7272
7770
  listPluginsRoute,
7273
7771
  listRevisionsRoute,
7274
7772
  listUsersRoute,
7773
+ logoutFederatedRegistrationRoute,
7275
7774
  makeAdminRoute,
7276
7775
  markAllAsReadRoute,
7277
7776
  meRoutes,
@@ -7308,7 +7807,9 @@ export {
7308
7807
  sendTestMailRoute,
7309
7808
  setPageGrantRoute,
7310
7809
  setWatchStatusRoute,
7810
+ startFederatedProviderRoute,
7311
7811
  stripKnownHtmlTags,
7812
+ submitFederatedRegistrationRoute,
7312
7813
  suspendUserRoute,
7313
7814
  tokenAuthRoutes,
7314
7815
  tokenLoginRoute,
@@ -7318,6 +7819,7 @@ export {
7318
7819
  tokenRegisterRoute,
7319
7820
  tokenRoute,
7320
7821
  unlikePageRoute,
7822
+ unlinkAuthProviderRoute,
7321
7823
  unwrapRenderedAst,
7322
7824
  updateAppSettingsRoute,
7323
7825
  updateAuthSettingsRoute,