@spfn/auth 0.1.0-alpha.1 → 0.1.0-alpha.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +250 -0
  2. package/dist/adapters/nextjs/api.d.ts +446 -0
  3. package/dist/adapters/nextjs/api.js +3279 -0
  4. package/dist/adapters/nextjs/api.js.map +1 -0
  5. package/dist/adapters/nextjs/server.d.ts +246 -0
  6. package/dist/adapters/nextjs/server.js +3645 -0
  7. package/dist/adapters/nextjs/server.js.map +1 -0
  8. package/dist/index.d.ts +3 -46
  9. package/dist/index.js +777 -645
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/api/auth-codes-verify.d.ts +37 -0
  12. package/dist/lib/api/auth-codes-verify.js +2949 -0
  13. package/dist/lib/api/auth-codes-verify.js.map +1 -0
  14. package/dist/lib/api/auth-codes.d.ts +37 -0
  15. package/dist/lib/api/auth-codes.js +2949 -0
  16. package/dist/lib/api/auth-codes.js.map +1 -0
  17. package/dist/lib/api/auth-exists.d.ts +38 -0
  18. package/dist/lib/api/auth-exists.js +2949 -0
  19. package/dist/lib/api/auth-exists.js.map +1 -0
  20. package/dist/lib/api/auth-invitations-accept.d.ts +38 -0
  21. package/dist/lib/api/auth-invitations-accept.js +2883 -0
  22. package/dist/lib/api/auth-invitations-accept.js.map +1 -0
  23. package/dist/lib/api/auth-invitations-cancel.d.ts +37 -0
  24. package/dist/lib/api/auth-invitations-cancel.js +2883 -0
  25. package/dist/lib/api/auth-invitations-cancel.js.map +1 -0
  26. package/dist/lib/api/auth-invitations-delete.d.ts +36 -0
  27. package/dist/lib/api/auth-invitations-delete.js +2883 -0
  28. package/dist/lib/api/auth-invitations-delete.js.map +1 -0
  29. package/dist/lib/api/auth-invitations-resend.d.ts +37 -0
  30. package/dist/lib/api/auth-invitations-resend.js +2883 -0
  31. package/dist/lib/api/auth-invitations-resend.js.map +1 -0
  32. package/dist/lib/api/auth-invitations.d.ts +109 -0
  33. package/dist/lib/api/auth-invitations.js +2887 -0
  34. package/dist/lib/api/auth-invitations.js.map +1 -0
  35. package/dist/lib/api/auth-keys-rotate.d.ts +37 -0
  36. package/dist/lib/api/auth-keys-rotate.js +2949 -0
  37. package/dist/lib/api/auth-keys-rotate.js.map +1 -0
  38. package/dist/lib/api/auth-login.d.ts +39 -0
  39. package/dist/lib/api/auth-login.js +2949 -0
  40. package/dist/lib/api/auth-login.js.map +1 -0
  41. package/dist/lib/api/auth-logout.d.ts +36 -0
  42. package/dist/lib/api/auth-logout.js +2949 -0
  43. package/dist/lib/api/auth-logout.js.map +1 -0
  44. package/dist/lib/api/auth-me.d.ts +50 -0
  45. package/dist/lib/api/auth-me.js +2949 -0
  46. package/dist/lib/api/auth-me.js.map +1 -0
  47. package/dist/lib/api/auth-password.d.ts +36 -0
  48. package/dist/lib/api/auth-password.js +2949 -0
  49. package/dist/lib/api/auth-password.js.map +1 -0
  50. package/dist/lib/api/auth-register.d.ts +38 -0
  51. package/dist/lib/api/auth-register.js +2949 -0
  52. package/dist/lib/api/auth-register.js.map +1 -0
  53. package/dist/lib/api/index.d.ts +356 -0
  54. package/dist/lib/api/index.js +3261 -0
  55. package/dist/lib/api/index.js.map +1 -0
  56. package/dist/lib/config.d.ts +70 -0
  57. package/dist/lib/config.js +64 -0
  58. package/dist/lib/config.js.map +1 -0
  59. package/dist/lib/contracts/auth.d.ts +41 -1
  60. package/dist/lib/contracts/auth.js +28 -0
  61. package/dist/lib/contracts/auth.js.map +1 -1
  62. package/dist/lib/contracts/index.d.ts +1 -1
  63. package/dist/lib/contracts/index.js +28 -0
  64. package/dist/lib/contracts/index.js.map +1 -1
  65. package/dist/lib/crypto.d.ts +76 -0
  66. package/dist/lib/crypto.js +127 -0
  67. package/dist/lib/crypto.js.map +1 -0
  68. package/dist/lib/index.d.ts +4 -0
  69. package/dist/lib/index.js +313 -0
  70. package/dist/lib/index.js.map +1 -0
  71. package/dist/lib/session.d.ts +68 -0
  72. package/dist/lib/session.js +126 -0
  73. package/dist/lib/session.js.map +1 -0
  74. package/dist/{api-BcQM4WKb.d.ts → lib/types/api.d.ts} +2 -2
  75. package/dist/lib/types/api.js +1 -0
  76. package/dist/lib/types/api.js.map +1 -0
  77. package/dist/lib/types/index.d.ts +3 -0
  78. package/dist/lib/types/index.js +2647 -0
  79. package/dist/lib/types/index.js.map +1 -0
  80. package/dist/lib/types/schemas.d.ts +45 -0
  81. package/dist/lib/types/schemas.js +2647 -0
  82. package/dist/lib/types/schemas.js.map +1 -0
  83. package/dist/lib.d.ts +2 -0
  84. package/dist/lib.js +1 -0
  85. package/dist/lib.js.map +1 -0
  86. package/dist/plugin.js +777 -645
  87. package/dist/plugin.js.map +1 -1
  88. package/dist/server/entities/index.d.ts +1 -0
  89. package/dist/server/entities/index.js +23 -27
  90. package/dist/server/entities/index.js.map +1 -1
  91. package/dist/server/entities/invitations.js +12 -9
  92. package/dist/server/entities/invitations.js.map +1 -1
  93. package/dist/server/entities/permissions.js +8 -3
  94. package/dist/server/entities/permissions.js.map +1 -1
  95. package/dist/server/entities/role-permissions.js +12 -9
  96. package/dist/server/entities/role-permissions.js.map +1 -1
  97. package/dist/server/entities/roles.js +8 -3
  98. package/dist/server/entities/roles.js.map +1 -1
  99. package/dist/server/entities/schema.d.ts +14 -0
  100. package/dist/server/entities/schema.js +7 -0
  101. package/dist/server/entities/schema.js.map +1 -0
  102. package/dist/server/entities/user-permissions.js +14 -12
  103. package/dist/server/entities/user-permissions.js.map +1 -1
  104. package/dist/server/entities/user-public-keys.js +12 -9
  105. package/dist/server/entities/user-public-keys.js.map +1 -1
  106. package/dist/server/entities/user-social-accounts.js +12 -9
  107. package/dist/server/entities/user-social-accounts.js.map +1 -1
  108. package/dist/server/entities/users.js +10 -6
  109. package/dist/server/entities/users.js.map +1 -1
  110. package/dist/server/entities/verification-codes.js +8 -3
  111. package/dist/server/entities/verification-codes.js.map +1 -1
  112. package/dist/server/routes/auth/index.js +495 -512
  113. package/dist/server/routes/auth/index.js.map +1 -1
  114. package/dist/server/routes/index.js +775 -545
  115. package/dist/server/routes/index.js.map +1 -1
  116. package/dist/server/routes/invitations/index.js +416 -230
  117. package/dist/server/routes/invitations/index.js.map +1 -1
  118. package/dist/server.d.ts +91 -62
  119. package/dist/server.js +320 -327
  120. package/dist/server.js.map +1 -1
  121. package/migrations/{0000_tired_gambit.sql → 0000_complex_swordsman.sql} +2 -0
  122. package/migrations/meta/0000_snapshot.json +4 -2
  123. package/migrations/meta/_journal.json +2 -2
  124. package/package.json +30 -3
package/dist/plugin.js CHANGED
@@ -8,15 +8,25 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/server/entities/schema.ts
12
+ import { createFunctionSchema } from "@spfn/core/db";
13
+ var authSchema;
14
+ var init_schema = __esm({
15
+ "src/server/entities/schema.ts"() {
16
+ "use strict";
17
+ authSchema = createFunctionSchema("@spfn/auth");
18
+ }
19
+ });
20
+
11
21
  // src/server/entities/roles.ts
12
22
  import { text, boolean, integer, index } from "drizzle-orm/pg-core";
13
- import { id, timestamps, createFunctionSchema } from "@spfn/core/db";
14
- var schema, roles;
23
+ import { id, timestamps } from "@spfn/core/db";
24
+ var roles;
15
25
  var init_roles = __esm({
16
26
  "src/server/entities/roles.ts"() {
17
27
  "use strict";
18
- schema = createFunctionSchema("@spfn/auth");
19
- roles = schema.table(
28
+ init_schema();
29
+ roles = authSchema.table(
20
30
  "roles",
21
31
  {
22
32
  // Primary key
@@ -58,15 +68,15 @@ var init_roles = __esm({
58
68
 
59
69
  // src/server/entities/users.ts
60
70
  import { text as text2, timestamp, check, boolean as boolean2, bigint, index as index2 } from "drizzle-orm/pg-core";
61
- import { id as id2, timestamps as timestamps2, createFunctionSchema as createFunctionSchema2 } from "@spfn/core/db";
71
+ import { id as id2, timestamps as timestamps2 } from "@spfn/core/db";
62
72
  import { sql } from "drizzle-orm";
63
- var schema2, users;
73
+ var users;
64
74
  var init_users = __esm({
65
75
  "src/server/entities/users.ts"() {
66
76
  "use strict";
67
77
  init_roles();
68
- schema2 = createFunctionSchema2("@spfn/auth");
69
- users = schema2.table(
78
+ init_schema();
79
+ users = authSchema.table(
70
80
  "users",
71
81
  {
72
82
  // Identity
@@ -131,14 +141,14 @@ var init_users = __esm({
131
141
 
132
142
  // src/server/entities/user-social-accounts.ts
133
143
  import { text as text3, timestamp as timestamp2, uniqueIndex } from "drizzle-orm/pg-core";
134
- import { id as id3, timestamps as timestamps3, foreignKey, createFunctionSchema as createFunctionSchema3 } from "@spfn/core/db";
135
- var schema3, userSocialAccounts;
144
+ import { id as id3, timestamps as timestamps3, foreignKey } from "@spfn/core/db";
145
+ var userSocialAccounts;
136
146
  var init_user_social_accounts = __esm({
137
147
  "src/server/entities/user-social-accounts.ts"() {
138
148
  "use strict";
139
149
  init_users();
140
- schema3 = createFunctionSchema3("@spfn/auth");
141
- userSocialAccounts = schema3.table(
150
+ init_schema();
151
+ userSocialAccounts = authSchema.table(
142
152
  "user_social_accounts",
143
153
  {
144
154
  id: id3(),
@@ -169,14 +179,14 @@ var init_user_social_accounts = __esm({
169
179
 
170
180
  // src/server/entities/user-public-keys.ts
171
181
  import { text as text4, timestamp as timestamp3, boolean as boolean3, index as index3 } from "drizzle-orm/pg-core";
172
- import { id as id4, foreignKey as foreignKey2, createFunctionSchema as createFunctionSchema4 } from "@spfn/core/db";
173
- var schema4, userPublicKeys;
182
+ import { id as id4, foreignKey as foreignKey2 } from "@spfn/core/db";
183
+ var userPublicKeys;
174
184
  var init_user_public_keys = __esm({
175
185
  "src/server/entities/user-public-keys.ts"() {
176
186
  "use strict";
177
187
  init_users();
178
- schema4 = createFunctionSchema4("@spfn/auth");
179
- userPublicKeys = schema4.table(
188
+ init_schema();
189
+ userPublicKeys = authSchema.table(
180
190
  "user_public_keys",
181
191
  {
182
192
  id: id4(),
@@ -214,13 +224,13 @@ var init_user_public_keys = __esm({
214
224
 
215
225
  // src/server/entities/verification-codes.ts
216
226
  import { text as text5, timestamp as timestamp4, index as index4 } from "drizzle-orm/pg-core";
217
- import { id as id5, timestamps as timestamps4, createFunctionSchema as createFunctionSchema5 } from "@spfn/core/db";
218
- var schema5, verificationCodes;
227
+ import { id as id5, timestamps as timestamps4 } from "@spfn/core/db";
228
+ var verificationCodes;
219
229
  var init_verification_codes = __esm({
220
230
  "src/server/entities/verification-codes.ts"() {
221
231
  "use strict";
222
- schema5 = createFunctionSchema5("@spfn/auth");
223
- verificationCodes = schema5.table(
232
+ init_schema();
233
+ verificationCodes = authSchema.table(
224
234
  "verification_codes",
225
235
  {
226
236
  id: id5(),
@@ -261,15 +271,15 @@ var init_verification_codes = __esm({
261
271
 
262
272
  // src/server/entities/invitations.ts
263
273
  import { text as text6, timestamp as timestamp5, bigint as bigint2, index as index5, jsonb } from "drizzle-orm/pg-core";
264
- import { id as id6, timestamps as timestamps5, createFunctionSchema as createFunctionSchema6 } from "@spfn/core/db";
265
- var schema6, invitations;
274
+ import { id as id6, timestamps as timestamps5 } from "@spfn/core/db";
275
+ var invitations;
266
276
  var init_invitations = __esm({
267
277
  "src/server/entities/invitations.ts"() {
268
278
  "use strict";
269
279
  init_roles();
270
280
  init_users();
271
- schema6 = createFunctionSchema6("@spfn/auth");
272
- invitations = schema6.table(
281
+ init_schema();
282
+ invitations = authSchema.table(
273
283
  "user_invitations",
274
284
  {
275
285
  // Primary key
@@ -337,13 +347,13 @@ var init_invitations = __esm({
337
347
 
338
348
  // src/server/entities/permissions.ts
339
349
  import { text as text7, boolean as boolean4, index as index6 } from "drizzle-orm/pg-core";
340
- import { id as id7, timestamps as timestamps6, createFunctionSchema as createFunctionSchema7 } from "@spfn/core/db";
341
- var schema7, permissions;
350
+ import { id as id7, timestamps as timestamps6 } from "@spfn/core/db";
351
+ var permissions;
342
352
  var init_permissions = __esm({
343
353
  "src/server/entities/permissions.ts"() {
344
354
  "use strict";
345
- schema7 = createFunctionSchema7("@spfn/auth");
346
- permissions = schema7.table(
355
+ init_schema();
356
+ permissions = authSchema.table(
347
357
  "permissions",
348
358
  {
349
359
  // Primary key
@@ -384,15 +394,15 @@ var init_permissions = __esm({
384
394
 
385
395
  // src/server/entities/role-permissions.ts
386
396
  import { bigint as bigint3, index as index7, unique } from "drizzle-orm/pg-core";
387
- import { id as id8, timestamps as timestamps7, createFunctionSchema as createFunctionSchema8 } from "@spfn/core/db";
388
- var schema8, rolePermissions;
397
+ import { id as id8, timestamps as timestamps7 } from "@spfn/core/db";
398
+ var rolePermissions;
389
399
  var init_role_permissions = __esm({
390
400
  "src/server/entities/role-permissions.ts"() {
391
401
  "use strict";
392
402
  init_roles();
393
403
  init_permissions();
394
- schema8 = createFunctionSchema8("@spfn/auth");
395
- rolePermissions = schema8.table(
404
+ init_schema();
405
+ rolePermissions = authSchema.table(
396
406
  "role_permissions",
397
407
  {
398
408
  // Primary key
@@ -416,15 +426,15 @@ var init_role_permissions = __esm({
416
426
 
417
427
  // src/server/entities/user-permissions.ts
418
428
  import { bigint as bigint4, boolean as boolean5, text as text8, timestamp as timestamp6, index as index8, unique as unique2 } from "drizzle-orm/pg-core";
419
- import { id as id9, timestamps as timestamps8, createFunctionSchema as createFunctionSchema9 } from "@spfn/core/db";
420
- var schema9, userPermissions;
429
+ import { id as id9, timestamps as timestamps8 } from "@spfn/core/db";
430
+ var userPermissions;
421
431
  var init_user_permissions = __esm({
422
432
  "src/server/entities/user-permissions.ts"() {
423
433
  "use strict";
424
434
  init_users();
425
435
  init_permissions();
426
- schema9 = createFunctionSchema9("@spfn/auth");
427
- userPermissions = schema9.table(
436
+ init_schema();
437
+ userPermissions = authSchema.table(
428
438
  "user_permissions",
429
439
  {
430
440
  // Primary key
@@ -460,6 +470,7 @@ var init_user_permissions = __esm({
460
470
  // src/server/entities/index.ts
461
471
  var entities_exports = {};
462
472
  __export(entities_exports, {
473
+ authSchema: () => authSchema,
463
474
  invitations: () => invitations,
464
475
  permissions: () => permissions,
465
476
  rolePermissions: () => rolePermissions,
@@ -473,6 +484,7 @@ __export(entities_exports, {
473
484
  var init_entities = __esm({
474
485
  "src/server/entities/index.ts"() {
475
486
  "use strict";
487
+ init_schema();
476
488
  init_users();
477
489
  init_user_social_accounts();
478
490
  init_user_public_keys();
@@ -558,6 +570,14 @@ var init_builtin = __esm({
558
570
  isSystem: true,
559
571
  isBuiltin: true
560
572
  },
573
+ USER_INVITE: {
574
+ name: "user:invite",
575
+ displayName: "Invite Users",
576
+ description: "Create and send user invitations",
577
+ category: "user",
578
+ isSystem: true,
579
+ isBuiltin: true
580
+ },
561
581
  // RBAC management (superadmin functions)
562
582
  RBAC_ROLE_MANAGE: {
563
583
  name: "rbac:role:manage",
@@ -582,6 +602,7 @@ var init_builtin = __esm({
582
602
  "user:read",
583
603
  "user:write",
584
604
  "user:delete",
605
+ "user:invite",
585
606
  "rbac:role:manage",
586
607
  "rbac:permission:manage"
587
608
  ],
@@ -589,7 +610,8 @@ var init_builtin = __esm({
589
610
  "auth:self:manage",
590
611
  "user:read",
591
612
  "user:write",
592
- "user:delete"
613
+ "user:delete",
614
+ "user:invite"
593
615
  ],
594
616
  user: [
595
617
  "auth:self:manage"
@@ -598,167 +620,64 @@ var init_builtin = __esm({
598
620
  }
599
621
  });
600
622
 
601
- // src/server/rbac/presets.ts
602
- var PRESET_ROLES, PRESET_PERMISSIONS, PRESET_ROLE_PERMISSIONS;
603
- var init_presets = __esm({
604
- "src/server/rbac/presets.ts"() {
605
- "use strict";
606
- PRESET_ROLES = {
607
- MODERATOR: {
608
- name: "moderator",
609
- displayName: "Moderator",
610
- description: "Content moderation and community management",
611
- priority: 50,
612
- isSystem: true
613
- },
614
- EDITOR: {
615
- name: "editor",
616
- displayName: "Editor",
617
- description: "Content creation and editing",
618
- priority: 30,
619
- isSystem: true
620
- },
621
- VIEWER: {
622
- name: "viewer",
623
- displayName: "Viewer",
624
- description: "Read-only access to content",
625
- priority: 5,
626
- isSystem: true
627
- }
628
- };
629
- PRESET_PERMISSIONS = {
630
- // Content management
631
- CONTENT_READ: {
632
- name: "content:read",
633
- displayName: "Read Content",
634
- description: "View all content including drafts",
635
- category: "content",
636
- isSystem: true
637
- },
638
- CONTENT_WRITE: {
639
- name: "content:write",
640
- displayName: "Write Content",
641
- description: "Create and edit content",
642
- category: "content",
643
- isSystem: true
644
- },
645
- CONTENT_DELETE: {
646
- name: "content:delete",
647
- displayName: "Delete Content",
648
- description: "Delete any content",
649
- category: "content",
650
- isSystem: true
651
- },
652
- CONTENT_PUBLISH: {
653
- name: "content:publish",
654
- displayName: "Publish Content",
655
- description: "Publish content to make it public",
656
- category: "content",
657
- isSystem: true
658
- },
659
- // Moderation
660
- COMMENT_MODERATE: {
661
- name: "comment:moderate",
662
- displayName: "Moderate Comments",
663
- description: "Review and delete inappropriate comments",
664
- category: "moderation",
665
- isSystem: true
666
- },
667
- // System
668
- SYSTEM_CONFIG: {
669
- name: "system:config",
670
- displayName: "System Configuration",
671
- description: "Configure application settings",
672
- category: "system",
673
- isSystem: true
674
- },
675
- // Analytics
676
- ANALYTICS_VIEW: {
677
- name: "analytics:view",
678
- displayName: "View Analytics",
679
- description: "Access analytics dashboard and reports",
680
- category: "analytics",
681
- isSystem: true
682
- }
683
- };
684
- PRESET_ROLE_PERMISSIONS = {
685
- moderator: [
686
- "auth:self:manage",
687
- "user:read",
688
- "content:read",
689
- "content:write",
690
- "content:delete",
691
- "comment:moderate"
692
- ],
693
- editor: [
694
- "auth:self:manage",
695
- "content:read",
696
- "content:write",
697
- "content:publish"
698
- ],
699
- viewer: [
700
- "auth:self:manage",
701
- "content:read"
702
- ]
703
- };
704
- }
705
- });
706
-
707
623
  // src/server/rbac/index.ts
708
624
  var init_rbac = __esm({
709
625
  "src/server/rbac/index.ts"() {
710
626
  "use strict";
711
627
  init_types();
712
628
  init_builtin();
713
- init_presets();
629
+ }
630
+ });
631
+
632
+ // src/lib/config.ts
633
+ function configureAuth(config) {
634
+ globalConfig = {
635
+ ...globalConfig,
636
+ ...config
637
+ };
638
+ }
639
+ var globalConfig;
640
+ var init_config = __esm({
641
+ "src/lib/config.ts"() {
642
+ "use strict";
643
+ globalConfig = {
644
+ sessionTtl: "7d"
645
+ // Default: 7 days
646
+ };
714
647
  }
715
648
  });
716
649
 
717
650
  // src/server/services/rbac.service.ts
718
651
  import { getDatabase } from "@spfn/core/db";
652
+ import { logger } from "@spfn/core/logger";
719
653
  import { eq, and, inArray } from "drizzle-orm";
720
654
  async function initializeAuth(options = {}) {
721
655
  const db = getDatabase();
722
656
  if (!db) {
723
657
  throw new Error("[Auth] Database not initialized. Call initDatabase() first.");
724
658
  }
725
- console.log("[Auth] \u{1F510} Initializing RBAC system...");
726
- const allRoles = [...Object.values(BUILTIN_ROLES)];
727
- if (options.usePresets) {
728
- allRoles.push(...Object.values(PRESET_ROLES));
729
- } else if (options.presetRoles) {
730
- for (const presetKey of options.presetRoles) {
731
- if (PRESET_ROLES[presetKey]) {
732
- allRoles.push(PRESET_ROLES[presetKey]);
733
- }
734
- }
735
- }
736
- if (options.roles) {
737
- allRoles.push(...options.roles);
659
+ authLogger.info("\u{1F510} Initializing RBAC system...");
660
+ if (options.sessionTtl !== void 0) {
661
+ configureAuth({
662
+ sessionTtl: options.sessionTtl
663
+ });
664
+ authLogger.info(`\u23F1\uFE0F Session TTL: ${options.sessionTtl}`);
738
665
  }
666
+ const allRoles = [
667
+ ...Object.values(BUILTIN_ROLES),
668
+ ...options.roles || []
669
+ ];
739
670
  for (const roleConfig of allRoles) {
740
671
  await upsertRole(roleConfig);
741
672
  }
742
- const allPermissions = [...Object.values(BUILTIN_PERMISSIONS)];
743
- if (options.usePresets) {
744
- allPermissions.push(...Object.values(PRESET_PERMISSIONS));
745
- } else if (options.presetPermissions) {
746
- for (const presetKey of options.presetPermissions) {
747
- if (PRESET_PERMISSIONS[presetKey]) {
748
- allPermissions.push(PRESET_PERMISSIONS[presetKey]);
749
- }
750
- }
751
- }
752
- if (options.permissions) {
753
- allPermissions.push(...options.permissions);
754
- }
673
+ const allPermissions = [
674
+ ...Object.values(BUILTIN_PERMISSIONS),
675
+ ...options.permissions || []
676
+ ];
755
677
  for (const permConfig of allPermissions) {
756
678
  await upsertPermission(permConfig);
757
679
  }
758
680
  const allMappings = { ...BUILTIN_ROLE_PERMISSIONS };
759
- if (options.usePresets) {
760
- Object.assign(allMappings, PRESET_ROLE_PERMISSIONS);
761
- }
762
681
  if (options.rolePermissions) {
763
682
  for (const [roleName, permNames] of Object.entries(options.rolePermissions)) {
764
683
  if (allMappings[roleName]) {
@@ -773,9 +692,9 @@ async function initializeAuth(options = {}) {
773
692
  for (const [roleName, permNames] of Object.entries(allMappings)) {
774
693
  await assignPermissionsToRole(roleName, permNames);
775
694
  }
776
- console.log("[Auth] \u2705 RBAC initialization complete");
777
- console.log(`[Auth] \u{1F4CA} Roles: ${allRoles.length}, Permissions: ${allPermissions.length}`);
778
- console.log(`[Auth] \u{1F512} Built-in roles: user, admin, superadmin`);
695
+ authLogger.info("\u2705 RBAC initialization complete");
696
+ authLogger.info(`\u{1F4CA} Roles: ${allRoles.length}, Permissions: ${allPermissions.length}`);
697
+ authLogger.info("\u{1F512} Built-in roles: user, admin, superadmin");
779
698
  }
780
699
  async function upsertRole(config) {
781
700
  const db = getDatabase();
@@ -789,7 +708,7 @@ async function upsertRole(config) {
789
708
  isSystem: config.isSystem ?? false,
790
709
  isBuiltin: config.isBuiltin ?? false
791
710
  });
792
- console.log(`[Auth] \u2705 Created role: ${config.name}`);
711
+ authLogger.info(` \u2705 Created role: ${config.name}`);
793
712
  } else {
794
713
  const updateData = {
795
714
  displayName: config.displayName,
@@ -813,7 +732,7 @@ async function upsertPermission(config) {
813
732
  isSystem: config.isSystem ?? false,
814
733
  isBuiltin: config.isBuiltin ?? false
815
734
  });
816
- console.log(`[Auth] \u2705 Created permission: ${config.name}`);
735
+ authLogger.info(` \u2705 Created permission: ${config.name}`);
817
736
  } else {
818
737
  await db.update(permissions).set({
819
738
  displayName: config.displayName,
@@ -826,12 +745,12 @@ async function assignPermissionsToRole(roleName, permissionNames) {
826
745
  const db = getDatabase();
827
746
  const [role] = await db.select().from(roles).where(eq(roles.name, roleName)).limit(1);
828
747
  if (!role) {
829
- console.warn(`[Auth] \u26A0\uFE0F Role not found: ${roleName}, skipping permission assignment`);
748
+ authLogger.warn(` \u26A0\uFE0F Role not found: ${roleName}, skipping permission assignment`);
830
749
  return;
831
750
  }
832
751
  const perms = await db.select().from(permissions).where(inArray(permissions.name, permissionNames));
833
752
  if (perms.length === 0) {
834
- console.warn(`[Auth] \u26A0\uFE0F No permissions found for role: ${roleName}`);
753
+ authLogger.warn(` \u26A0\uFE0F No permissions found for role: ${roleName}`);
835
754
  return;
836
755
  }
837
756
  for (const perm of perms) {
@@ -849,11 +768,14 @@ async function assignPermissionsToRole(roleName, permissionNames) {
849
768
  }
850
769
  }
851
770
  }
771
+ var authLogger;
852
772
  var init_rbac_service = __esm({
853
773
  "src/server/services/rbac.service.ts"() {
854
774
  "use strict";
855
775
  init_entities();
856
776
  init_rbac();
777
+ init_config();
778
+ authLogger = logger.child("@spfn/auth");
857
779
  }
858
780
  });
859
781
 
@@ -2619,8 +2541,8 @@ var init_value2 = __esm({
2619
2541
  });
2620
2542
 
2621
2543
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs
2622
- function CloneType(schema10, options) {
2623
- return options === void 0 ? Clone(schema10) : Clone({ ...options, ...schema10 });
2544
+ function CloneType(schema, options) {
2545
+ return options === void 0 ? Clone(schema) : Clone({ ...options, ...schema });
2624
2546
  }
2625
2547
  var init_type = __esm({
2626
2548
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs"() {
@@ -2737,8 +2659,8 @@ var init_immutable = __esm({
2737
2659
  });
2738
2660
 
2739
2661
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/create/type.mjs
2740
- function CreateType(schema10, options) {
2741
- const result = options !== void 0 ? { ...options, ...schema10 } : schema10;
2662
+ function CreateType(schema, options) {
2663
+ const result = options !== void 0 ? { ...options, ...schema } : schema;
2742
2664
  switch (TypeSystemPolicy.InstanceMode) {
2743
2665
  case "freeze":
2744
2666
  return Immutable(result);
@@ -3068,16 +2990,16 @@ function IsBoolean3(value) {
3068
2990
  return IsKindOf2(value, "Boolean") && value.type === "boolean" && IsOptionalString(value.$id);
3069
2991
  }
3070
2992
  function IsComputed2(value) {
3071
- return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10));
2993
+ return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema));
3072
2994
  }
3073
2995
  function IsConstructor2(value) {
3074
- return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10)) && IsSchema2(value.returns);
2996
+ return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
3075
2997
  }
3076
2998
  function IsDate3(value) {
3077
2999
  return IsKindOf2(value, "Date") && value.type === "Date" && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximumTimestamp) && IsOptionalNumber(value.exclusiveMinimumTimestamp) && IsOptionalNumber(value.maximumTimestamp) && IsOptionalNumber(value.minimumTimestamp) && IsOptionalNumber(value.multipleOfTimestamp);
3078
3000
  }
3079
3001
  function IsFunction3(value) {
3080
- return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10)) && IsSchema2(value.returns);
3002
+ return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
3081
3003
  }
3082
3004
  function IsImport(value) {
3083
3005
  return IsKindOf2(value, "Import") && HasPropertyKey(value, "$defs") && IsObject(value.$defs) && IsProperties(value.$defs) && HasPropertyKey(value, "$ref") && IsString(value.$ref) && value.$ref in value.$defs;
@@ -3086,10 +3008,10 @@ function IsInteger2(value) {
3086
3008
  return IsKindOf2(value, "Integer") && value.type === "integer" && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximum) && IsOptionalNumber(value.exclusiveMinimum) && IsOptionalNumber(value.maximum) && IsOptionalNumber(value.minimum) && IsOptionalNumber(value.multipleOf);
3087
3009
  }
3088
3010
  function IsProperties(value) {
3089
- return IsObject(value) && Object.entries(value).every(([key, schema10]) => IsControlCharacterFree(key) && IsSchema2(schema10));
3011
+ return IsObject(value) && Object.entries(value).every(([key, schema]) => IsControlCharacterFree(key) && IsSchema2(schema));
3090
3012
  }
3091
3013
  function IsIntersect2(value) {
3092
- return IsKindOf2(value, "Intersect") && (IsString(value.type) && value.type !== "object" ? false : true) && IsArray(value.allOf) && value.allOf.every((schema10) => IsSchema2(schema10) && !IsTransform2(schema10)) && IsOptionalString(value.type) && (IsOptionalBoolean(value.unevaluatedProperties) || IsOptionalSchema(value.unevaluatedProperties)) && IsOptionalString(value.$id);
3014
+ return IsKindOf2(value, "Intersect") && (IsString(value.type) && value.type !== "object" ? false : true) && IsArray(value.allOf) && value.allOf.every((schema) => IsSchema2(schema) && !IsTransform2(schema)) && IsOptionalString(value.type) && (IsOptionalBoolean(value.unevaluatedProperties) || IsOptionalSchema(value.unevaluatedProperties)) && IsOptionalString(value.$id);
3093
3015
  }
3094
3016
  function IsIterator3(value) {
3095
3017
  return IsKindOf2(value, "Iterator") && value.type === "Iterator" && IsOptionalString(value.$id) && IsSchema2(value.items);
@@ -3137,9 +3059,9 @@ function IsPromise2(value) {
3137
3059
  return IsKindOf2(value, "Promise") && value.type === "Promise" && IsOptionalString(value.$id) && IsSchema2(value.item);
3138
3060
  }
3139
3061
  function IsRecord2(value) {
3140
- return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((schema10) => {
3141
- const keys = Object.getOwnPropertyNames(schema10.patternProperties);
3142
- return keys.length === 1 && IsPattern(keys[0]) && IsObject(schema10.patternProperties) && IsSchema2(schema10.patternProperties[keys[0]]);
3062
+ return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((schema) => {
3063
+ const keys = Object.getOwnPropertyNames(schema.patternProperties);
3064
+ return keys.length === 1 && IsPattern(keys[0]) && IsObject(schema.patternProperties) && IsSchema2(schema.patternProperties[keys[0]]);
3143
3065
  })(value);
3144
3066
  }
3145
3067
  function IsRecursive(value) {
@@ -3168,16 +3090,16 @@ function IsTransform2(value) {
3168
3090
  }
3169
3091
  function IsTuple2(value) {
3170
3092
  return IsKindOf2(value, "Tuple") && value.type === "array" && IsOptionalString(value.$id) && IsNumber(value.minItems) && IsNumber(value.maxItems) && value.minItems === value.maxItems && // empty
3171
- (IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((schema10) => IsSchema2(schema10)));
3093
+ (IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((schema) => IsSchema2(schema)));
3172
3094
  }
3173
3095
  function IsUndefined4(value) {
3174
3096
  return IsKindOf2(value, "Undefined") && value.type === "undefined" && IsOptionalString(value.$id);
3175
3097
  }
3176
3098
  function IsUnionLiteral(value) {
3177
- return IsUnion2(value) && value.anyOf.every((schema10) => IsLiteralString(schema10) || IsLiteralNumber(schema10));
3099
+ return IsUnion2(value) && value.anyOf.every((schema) => IsLiteralString(schema) || IsLiteralNumber(schema));
3178
3100
  }
3179
3101
  function IsUnion2(value) {
3180
- return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((schema10) => IsSchema2(schema10));
3102
+ return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((schema) => IsSchema2(schema));
3181
3103
  }
3182
3104
  function IsUint8Array3(value) {
3183
3105
  return IsKindOf2(value, "Uint8Array") && value.type === "Uint8Array" && IsOptionalString(value.$id) && IsOptionalNumber(value.minByteLength) && IsOptionalNumber(value.maxByteLength);
@@ -3778,8 +3700,8 @@ function IsTemplateLiteralExpressionFinite(expression) {
3778
3700
  throw new TemplateLiteralFiniteError(`Unknown expression type`);
3779
3701
  })();
3780
3702
  }
3781
- function IsTemplateLiteralFinite(schema10) {
3782
- const expression = TemplateLiteralParseExact(schema10.pattern);
3703
+ function IsTemplateLiteralFinite(schema) {
3704
+ const expression = TemplateLiteralParseExact(schema.pattern);
3783
3705
  return IsTemplateLiteralExpressionFinite(expression);
3784
3706
  }
3785
3707
  var TemplateLiteralFiniteError;
@@ -3818,8 +3740,8 @@ function* TemplateLiteralExpressionGenerate(expression) {
3818
3740
  throw new TemplateLiteralGenerateError("Unknown expression");
3819
3741
  })();
3820
3742
  }
3821
- function TemplateLiteralGenerate(schema10) {
3822
- const expression = TemplateLiteralParseExact(schema10.pattern);
3743
+ function TemplateLiteralGenerate(schema) {
3744
+ const expression = TemplateLiteralParseExact(schema.pattern);
3823
3745
  return IsTemplateLiteralExpressionFinite(expression) ? [...TemplateLiteralExpressionGenerate(expression)] : [];
3824
3746
  }
3825
3747
  var TemplateLiteralGenerateError;
@@ -3991,13 +3913,13 @@ var init_syntax = __esm({
3991
3913
  function Escape(value) {
3992
3914
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3993
3915
  }
3994
- function Visit2(schema10, acc) {
3995
- return IsTemplateLiteral(schema10) ? schema10.pattern.slice(1, schema10.pattern.length - 1) : IsUnion(schema10) ? `(${schema10.anyOf.map((schema11) => Visit2(schema11, acc)).join("|")})` : IsNumber3(schema10) ? `${acc}${PatternNumber}` : IsInteger(schema10) ? `${acc}${PatternNumber}` : IsBigInt2(schema10) ? `${acc}${PatternNumber}` : IsString2(schema10) ? `${acc}${PatternString}` : IsLiteral(schema10) ? `${acc}${Escape(schema10.const.toString())}` : IsBoolean2(schema10) ? `${acc}${PatternBoolean}` : (() => {
3996
- throw new TemplateLiteralPatternError(`Unexpected Kind '${schema10[Kind]}'`);
3916
+ function Visit2(schema, acc) {
3917
+ return IsTemplateLiteral(schema) ? schema.pattern.slice(1, schema.pattern.length - 1) : IsUnion(schema) ? `(${schema.anyOf.map((schema2) => Visit2(schema2, acc)).join("|")})` : IsNumber3(schema) ? `${acc}${PatternNumber}` : IsInteger(schema) ? `${acc}${PatternNumber}` : IsBigInt2(schema) ? `${acc}${PatternNumber}` : IsString2(schema) ? `${acc}${PatternString}` : IsLiteral(schema) ? `${acc}${Escape(schema.const.toString())}` : IsBoolean2(schema) ? `${acc}${PatternBoolean}` : (() => {
3918
+ throw new TemplateLiteralPatternError(`Unexpected Kind '${schema[Kind]}'`);
3997
3919
  })();
3998
3920
  }
3999
3921
  function TemplateLiteralPattern(kinds) {
4000
- return `^${kinds.map((schema10) => Visit2(schema10, "")).join("")}$`;
3922
+ return `^${kinds.map((schema) => Visit2(schema, "")).join("")}$`;
4001
3923
  }
4002
3924
  var TemplateLiteralPatternError;
4003
3925
  var init_pattern = __esm({
@@ -4013,8 +3935,8 @@ var init_pattern = __esm({
4013
3935
  });
4014
3936
 
4015
3937
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/template-literal/union.mjs
4016
- function TemplateLiteralToUnion(schema10) {
4017
- const R = TemplateLiteralGenerate(schema10);
3938
+ function TemplateLiteralToUnion(schema) {
3939
+ const R = TemplateLiteralGenerate(schema);
4018
3940
  const L = R.map((S) => Literal(S));
4019
3941
  return UnionEvaluated(L);
4020
3942
  }
@@ -4279,18 +4201,18 @@ var init_promise2 = __esm({
4279
4201
  });
4280
4202
 
4281
4203
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly.mjs
4282
- function RemoveReadonly(schema10) {
4283
- return CreateType(Discard(schema10, [ReadonlyKind]));
4204
+ function RemoveReadonly(schema) {
4205
+ return CreateType(Discard(schema, [ReadonlyKind]));
4284
4206
  }
4285
- function AddReadonly(schema10) {
4286
- return CreateType({ ...schema10, [ReadonlyKind]: "Readonly" });
4207
+ function AddReadonly(schema) {
4208
+ return CreateType({ ...schema, [ReadonlyKind]: "Readonly" });
4287
4209
  }
4288
- function ReadonlyWithFlag(schema10, F) {
4289
- return F === false ? RemoveReadonly(schema10) : AddReadonly(schema10);
4210
+ function ReadonlyWithFlag(schema, F) {
4211
+ return F === false ? RemoveReadonly(schema) : AddReadonly(schema);
4290
4212
  }
4291
- function Readonly(schema10, enable) {
4213
+ function Readonly(schema, enable) {
4292
4214
  const F = enable ?? true;
4293
- return IsMappedResult(schema10) ? ReadonlyFromMappedResult(schema10, F) : ReadonlyWithFlag(schema10, F);
4215
+ return IsMappedResult(schema) ? ReadonlyFromMappedResult(schema, F) : ReadonlyWithFlag(schema, F);
4294
4216
  }
4295
4217
  var init_readonly = __esm({
4296
4218
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly.mjs"() {
@@ -4444,18 +4366,18 @@ var init_mapped2 = __esm({
4444
4366
  });
4445
4367
 
4446
4368
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional.mjs
4447
- function RemoveOptional(schema10) {
4448
- return CreateType(Discard(schema10, [OptionalKind]));
4369
+ function RemoveOptional(schema) {
4370
+ return CreateType(Discard(schema, [OptionalKind]));
4449
4371
  }
4450
- function AddOptional(schema10) {
4451
- return CreateType({ ...schema10, [OptionalKind]: "Optional" });
4372
+ function AddOptional(schema) {
4373
+ return CreateType({ ...schema, [OptionalKind]: "Optional" });
4452
4374
  }
4453
- function OptionalWithFlag(schema10, F) {
4454
- return F === false ? RemoveOptional(schema10) : AddOptional(schema10);
4375
+ function OptionalWithFlag(schema, F) {
4376
+ return F === false ? RemoveOptional(schema) : AddOptional(schema);
4455
4377
  }
4456
- function Optional(schema10, enable) {
4378
+ function Optional(schema, enable) {
4457
4379
  const F = enable ?? true;
4458
- return IsMappedResult(schema10) ? OptionalFromMappedResult(schema10, F) : OptionalWithFlag(schema10, F);
4380
+ return IsMappedResult(schema) ? OptionalFromMappedResult(schema, F) : OptionalWithFlag(schema, F);
4459
4381
  }
4460
4382
  var init_optional = __esm({
4461
4383
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional.mjs"() {
@@ -4501,7 +4423,7 @@ var init_optional2 = __esm({
4501
4423
 
4502
4424
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/intersect/intersect-create.mjs
4503
4425
  function IntersectCreate(T, options = {}) {
4504
- const allObjects = T.every((schema10) => IsObject3(schema10));
4426
+ const allObjects = T.every((schema) => IsObject3(schema));
4505
4427
  const clonedUnevaluatedProperties = IsSchema(options.unevaluatedProperties) ? { unevaluatedProperties: options.unevaluatedProperties } : {};
4506
4428
  return CreateType(options.unevaluatedProperties === false || IsSchema(options.unevaluatedProperties) || allObjects ? { ...clonedUnevaluatedProperties, [Kind]: "Intersect", type: "object", allOf: T } : { ...clonedUnevaluatedProperties, [Kind]: "Intersect", allOf: T }, options);
4507
4429
  }
@@ -4532,7 +4454,7 @@ function IntersectEvaluated(types, options = {}) {
4532
4454
  return CreateType(types[0], options);
4533
4455
  if (types.length === 0)
4534
4456
  return Never(options);
4535
- if (types.some((schema10) => IsTransform(schema10)))
4457
+ if (types.some((schema) => IsTransform(schema)))
4536
4458
  throw new Error("Cannot intersect transform types");
4537
4459
  return ResolveIntersect(types, options);
4538
4460
  }
@@ -4562,7 +4484,7 @@ function Intersect(types, options) {
4562
4484
  return CreateType(types[0], options);
4563
4485
  if (types.length === 0)
4564
4486
  return Never(options);
4565
- if (types.some((schema10) => IsTransform(schema10)))
4487
+ if (types.some((schema) => IsTransform(schema)))
4566
4488
  throw new Error("Cannot intersect transform types");
4567
4489
  return IntersectCreate(types, options);
4568
4490
  }
@@ -4992,8 +4914,8 @@ var init_const2 = __esm({
4992
4914
  });
4993
4915
 
4994
4916
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/constructor-parameters/constructor-parameters.mjs
4995
- function ConstructorParameters(schema10, options) {
4996
- return IsConstructor(schema10) ? Tuple(schema10.parameters, options) : Never(options);
4917
+ function ConstructorParameters(schema, options) {
4918
+ return IsConstructor(schema) ? Tuple(schema.parameters, options) : Never(options);
4997
4919
  }
4998
4920
  var init_constructor_parameters = __esm({
4999
4921
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/constructor-parameters/constructor-parameters.mjs"() {
@@ -5056,7 +4978,7 @@ function FromAnyRight(left, right) {
5056
4978
  return ExtendsResult.True;
5057
4979
  }
5058
4980
  function FromAny(left, right) {
5059
- return type_exports.IsIntersect(right) ? FromIntersectRight(left, right) : type_exports.IsUnion(right) && right.anyOf.some((schema10) => type_exports.IsAny(schema10) || type_exports.IsUnknown(schema10)) ? ExtendsResult.True : type_exports.IsUnion(right) ? ExtendsResult.Union : type_exports.IsUnknown(right) ? ExtendsResult.True : type_exports.IsAny(right) ? ExtendsResult.True : ExtendsResult.Union;
4981
+ return type_exports.IsIntersect(right) ? FromIntersectRight(left, right) : type_exports.IsUnion(right) && right.anyOf.some((schema) => type_exports.IsAny(schema) || type_exports.IsUnknown(schema)) ? ExtendsResult.True : type_exports.IsUnion(right) ? ExtendsResult.Union : type_exports.IsUnknown(right) ? ExtendsResult.True : type_exports.IsAny(right) ? ExtendsResult.True : ExtendsResult.Union;
5060
4982
  }
5061
4983
  function FromArrayRight(left, right) {
5062
4984
  return type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : type_exports.IsNever(left) ? ExtendsResult.True : ExtendsResult.False;
@@ -5077,13 +4999,13 @@ function FromBoolean(left, right) {
5077
4999
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsBoolean(right) ? ExtendsResult.True : ExtendsResult.False;
5078
5000
  }
5079
5001
  function FromConstructor(left, right) {
5080
- return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsConstructor(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema10, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema10)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
5002
+ return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsConstructor(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
5081
5003
  }
5082
5004
  function FromDate(left, right) {
5083
5005
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsDate(right) ? ExtendsResult.True : ExtendsResult.False;
5084
5006
  }
5085
5007
  function FromFunction(left, right) {
5086
- return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsFunction(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema10, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema10)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
5008
+ return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsFunction(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
5087
5009
  }
5088
5010
  function FromIntegerRight(left, right) {
5089
5011
  return type_exports.IsLiteral(left) && value_exports.IsNumber(left.const) ? ExtendsResult.True : type_exports.IsNumber(left) || type_exports.IsInteger(left) ? ExtendsResult.True : ExtendsResult.False;
@@ -5092,10 +5014,10 @@ function FromInteger(left, right) {
5092
5014
  return type_exports.IsInteger(right) || type_exports.IsNumber(right) ? ExtendsResult.True : IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : ExtendsResult.False;
5093
5015
  }
5094
5016
  function FromIntersectRight(left, right) {
5095
- return right.allOf.every((schema10) => Visit3(left, schema10) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5017
+ return right.allOf.every((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5096
5018
  }
5097
5019
  function FromIntersect4(left, right) {
5098
- return left.allOf.some((schema10) => Visit3(schema10, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5020
+ return left.allOf.some((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5099
5021
  }
5100
5022
  function FromIterator(left, right) {
5101
5023
  return IsStructuralRight(right) ? StructuralRight(left, right) : !type_exports.IsIterator(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.items, right.items));
@@ -5109,8 +5031,8 @@ function FromNeverRight(left, right) {
5109
5031
  function FromNever(left, right) {
5110
5032
  return ExtendsResult.True;
5111
5033
  }
5112
- function UnwrapTNot(schema10) {
5113
- let [current, depth] = [schema10, 0];
5034
+ function UnwrapTNot(schema) {
5035
+ let [current, depth] = [schema, 0];
5114
5036
  while (true) {
5115
5037
  if (!type_exports.IsNot(current))
5116
5038
  break;
@@ -5131,44 +5053,44 @@ function FromNumberRight(left, right) {
5131
5053
  function FromNumber(left, right) {
5132
5054
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsInteger(right) || type_exports.IsNumber(right) ? ExtendsResult.True : ExtendsResult.False;
5133
5055
  }
5134
- function IsObjectPropertyCount(schema10, count) {
5135
- return Object.getOwnPropertyNames(schema10.properties).length === count;
5056
+ function IsObjectPropertyCount(schema, count) {
5057
+ return Object.getOwnPropertyNames(schema.properties).length === count;
5136
5058
  }
5137
- function IsObjectStringLike(schema10) {
5138
- return IsObjectArrayLike(schema10);
5059
+ function IsObjectStringLike(schema) {
5060
+ return IsObjectArrayLike(schema);
5139
5061
  }
5140
- function IsObjectSymbolLike(schema10) {
5141
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "description" in schema10.properties && type_exports.IsUnion(schema10.properties.description) && schema10.properties.description.anyOf.length === 2 && (type_exports.IsString(schema10.properties.description.anyOf[0]) && type_exports.IsUndefined(schema10.properties.description.anyOf[1]) || type_exports.IsString(schema10.properties.description.anyOf[1]) && type_exports.IsUndefined(schema10.properties.description.anyOf[0]));
5062
+ function IsObjectSymbolLike(schema) {
5063
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "description" in schema.properties && type_exports.IsUnion(schema.properties.description) && schema.properties.description.anyOf.length === 2 && (type_exports.IsString(schema.properties.description.anyOf[0]) && type_exports.IsUndefined(schema.properties.description.anyOf[1]) || type_exports.IsString(schema.properties.description.anyOf[1]) && type_exports.IsUndefined(schema.properties.description.anyOf[0]));
5142
5064
  }
5143
- function IsObjectNumberLike(schema10) {
5144
- return IsObjectPropertyCount(schema10, 0);
5065
+ function IsObjectNumberLike(schema) {
5066
+ return IsObjectPropertyCount(schema, 0);
5145
5067
  }
5146
- function IsObjectBooleanLike(schema10) {
5147
- return IsObjectPropertyCount(schema10, 0);
5068
+ function IsObjectBooleanLike(schema) {
5069
+ return IsObjectPropertyCount(schema, 0);
5148
5070
  }
5149
- function IsObjectBigIntLike(schema10) {
5150
- return IsObjectPropertyCount(schema10, 0);
5071
+ function IsObjectBigIntLike(schema) {
5072
+ return IsObjectPropertyCount(schema, 0);
5151
5073
  }
5152
- function IsObjectDateLike(schema10) {
5153
- return IsObjectPropertyCount(schema10, 0);
5074
+ function IsObjectDateLike(schema) {
5075
+ return IsObjectPropertyCount(schema, 0);
5154
5076
  }
5155
- function IsObjectUint8ArrayLike(schema10) {
5156
- return IsObjectArrayLike(schema10);
5077
+ function IsObjectUint8ArrayLike(schema) {
5078
+ return IsObjectArrayLike(schema);
5157
5079
  }
5158
- function IsObjectFunctionLike(schema10) {
5080
+ function IsObjectFunctionLike(schema) {
5159
5081
  const length = Number2();
5160
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "length" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["length"], length)) === ExtendsResult.True;
5082
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
5161
5083
  }
5162
- function IsObjectConstructorLike(schema10) {
5163
- return IsObjectPropertyCount(schema10, 0);
5084
+ function IsObjectConstructorLike(schema) {
5085
+ return IsObjectPropertyCount(schema, 0);
5164
5086
  }
5165
- function IsObjectArrayLike(schema10) {
5087
+ function IsObjectArrayLike(schema) {
5166
5088
  const length = Number2();
5167
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "length" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["length"], length)) === ExtendsResult.True;
5089
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
5168
5090
  }
5169
- function IsObjectPromiseLike(schema10) {
5091
+ function IsObjectPromiseLike(schema) {
5170
5092
  const then = Function([Any()], Any());
5171
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "then" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["then"], then)) === ExtendsResult.True;
5093
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "then" in schema.properties && IntoBooleanResult(Visit3(schema.properties["then"], then)) === ExtendsResult.True;
5172
5094
  }
5173
5095
  function Property(left, right) {
5174
5096
  return Visit3(left, right) === ExtendsResult.False ? ExtendsResult.False : type_exports.IsOptional(left) && !type_exports.IsOptional(right) ? ExtendsResult.False : ExtendsResult.True;
@@ -5199,11 +5121,11 @@ function FromObject(left, right) {
5199
5121
  function FromPromise2(left, right) {
5200
5122
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectPromiseLike(right) ? ExtendsResult.True : !type_exports.IsPromise(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.item, right.item));
5201
5123
  }
5202
- function RecordKey(schema10) {
5203
- return PatternNumberExact in schema10.patternProperties ? Number2() : PatternStringExact in schema10.patternProperties ? String2() : Throw("Unknown record key pattern");
5124
+ function RecordKey(schema) {
5125
+ return PatternNumberExact in schema.patternProperties ? Number2() : PatternStringExact in schema.patternProperties ? String2() : Throw("Unknown record key pattern");
5204
5126
  }
5205
- function RecordValue(schema10) {
5206
- return PatternNumberExact in schema10.patternProperties ? schema10.patternProperties[PatternNumberExact] : PatternStringExact in schema10.patternProperties ? schema10.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
5127
+ function RecordValue(schema) {
5128
+ return PatternNumberExact in schema.patternProperties ? schema.patternProperties[PatternNumberExact] : PatternStringExact in schema.patternProperties ? schema.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
5207
5129
  }
5208
5130
  function FromRecordRight(left, right) {
5209
5131
  const [Key, Value] = [RecordKey(right), RecordValue(right)];
@@ -5237,13 +5159,13 @@ function FromTemplateLiteral2(left, right) {
5237
5159
  return type_exports.IsTemplateLiteral(left) ? Visit3(TemplateLiteralToUnion(left), right) : type_exports.IsTemplateLiteral(right) ? Visit3(left, TemplateLiteralToUnion(right)) : Throw("Invalid fallthrough for TemplateLiteral");
5238
5160
  }
5239
5161
  function IsArrayOfTuple(left, right) {
5240
- return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((schema10) => Visit3(schema10, right.items) === ExtendsResult.True);
5162
+ return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((schema) => Visit3(schema, right.items) === ExtendsResult.True);
5241
5163
  }
5242
5164
  function FromTupleRight(left, right) {
5243
5165
  return type_exports.IsNever(left) ? ExtendsResult.True : type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : ExtendsResult.False;
5244
5166
  }
5245
5167
  function FromTuple3(left, right) {
5246
- return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : type_exports.IsArray(right) && IsArrayOfTuple(left, right) ? ExtendsResult.True : !type_exports.IsTuple(right) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) || !value_exports.IsUndefined(left.items) && value_exports.IsUndefined(right.items) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) ? ExtendsResult.True : left.items.every((schema10, index9) => Visit3(schema10, right.items[index9]) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5168
+ return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : type_exports.IsArray(right) && IsArrayOfTuple(left, right) ? ExtendsResult.True : !type_exports.IsTuple(right) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) || !value_exports.IsUndefined(left.items) && value_exports.IsUndefined(right.items) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) ? ExtendsResult.True : left.items.every((schema, index9) => Visit3(schema, right.items[index9]) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5247
5169
  }
5248
5170
  function FromUint8Array(left, right) {
5249
5171
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsUint8Array(right) ? ExtendsResult.True : ExtendsResult.False;
@@ -5252,10 +5174,10 @@ function FromUndefined(left, right) {
5252
5174
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsVoid(right) ? FromVoidRight(left, right) : type_exports.IsUndefined(right) ? ExtendsResult.True : ExtendsResult.False;
5253
5175
  }
5254
5176
  function FromUnionRight(left, right) {
5255
- return right.anyOf.some((schema10) => Visit3(left, schema10) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5177
+ return right.anyOf.some((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5256
5178
  }
5257
5179
  function FromUnion6(left, right) {
5258
- return left.anyOf.every((schema10) => Visit3(schema10, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5180
+ return left.anyOf.every((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
5259
5181
  }
5260
5182
  function FromUnknownRight(left, right) {
5261
5183
  return ExtendsResult.True;
@@ -5534,8 +5456,8 @@ var init_extract2 = __esm({
5534
5456
  });
5535
5457
 
5536
5458
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/instance-type/instance-type.mjs
5537
- function InstanceType(schema10, options) {
5538
- return IsConstructor(schema10) ? CreateType(schema10.returns, options) : Never(options);
5459
+ function InstanceType(schema, options) {
5460
+ return IsConstructor(schema) ? CreateType(schema.returns, options) : Never(options);
5539
5461
  }
5540
5462
  var init_instance_type = __esm({
5541
5463
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/instance-type/instance-type.mjs"() {
@@ -5555,8 +5477,8 @@ var init_instance_type2 = __esm({
5555
5477
  });
5556
5478
 
5557
5479
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly-optional/readonly-optional.mjs
5558
- function ReadonlyOptional(schema10) {
5559
- return Readonly(Optional(schema10));
5480
+ function ReadonlyOptional(schema) {
5481
+ return Readonly(Optional(schema));
5560
5482
  }
5561
5483
  var init_readonly_optional = __esm({
5562
5484
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly-optional/readonly-optional.mjs"() {
@@ -5815,11 +5737,11 @@ function ApplyUppercase(value) {
5815
5737
  function ApplyLowercase(value) {
5816
5738
  return value.toLowerCase();
5817
5739
  }
5818
- function FromTemplateLiteral3(schema10, mode, options) {
5819
- const expression = TemplateLiteralParseExact(schema10.pattern);
5740
+ function FromTemplateLiteral3(schema, mode, options) {
5741
+ const expression = TemplateLiteralParseExact(schema.pattern);
5820
5742
  const finite = IsTemplateLiteralExpressionFinite(expression);
5821
5743
  if (!finite)
5822
- return { ...schema10, pattern: FromLiteralValue(schema10.pattern, mode) };
5744
+ return { ...schema, pattern: FromLiteralValue(schema.pattern, mode) };
5823
5745
  const strings = [...TemplateLiteralExpressionGenerate(expression)];
5824
5746
  const literals = strings.map((value) => Literal(value));
5825
5747
  const mapped = FromRest5(literals, mode);
@@ -5832,14 +5754,14 @@ function FromLiteralValue(value, mode) {
5832
5754
  function FromRest5(T, M) {
5833
5755
  return T.map((L) => Intrinsic(L, M));
5834
5756
  }
5835
- function Intrinsic(schema10, mode, options = {}) {
5757
+ function Intrinsic(schema, mode, options = {}) {
5836
5758
  return (
5837
5759
  // Intrinsic-Mapped-Inference
5838
- IsMappedKey(schema10) ? IntrinsicFromMappedKey(schema10, mode, options) : (
5760
+ IsMappedKey(schema) ? IntrinsicFromMappedKey(schema, mode, options) : (
5839
5761
  // Standard-Inference
5840
- IsTemplateLiteral(schema10) ? FromTemplateLiteral3(schema10, mode, options) : IsUnion(schema10) ? Union(FromRest5(schema10.anyOf, mode), options) : IsLiteral(schema10) ? Literal(FromLiteralValue(schema10.const, mode), options) : (
5762
+ IsTemplateLiteral(schema) ? FromTemplateLiteral3(schema, mode, options) : IsUnion(schema) ? Union(FromRest5(schema.anyOf, mode), options) : IsLiteral(schema) ? Literal(FromLiteralValue(schema.const, mode), options) : (
5841
5763
  // Default Type
5842
- CreateType(schema10, options)
5764
+ CreateType(schema, options)
5843
5765
  )
5844
5766
  )
5845
5767
  );
@@ -6496,8 +6418,8 @@ var init_not2 = __esm({
6496
6418
  });
6497
6419
 
6498
6420
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/parameters/parameters.mjs
6499
- function Parameters(schema10, options) {
6500
- return IsFunction2(schema10) ? Tuple(schema10.parameters, options) : Never();
6421
+ function Parameters(schema, options) {
6422
+ return IsFunction2(schema) ? Tuple(schema.parameters, options) : Never();
6501
6423
  }
6502
6424
  var init_parameters = __esm({
6503
6425
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/parameters/parameters.mjs"() {
@@ -6589,8 +6511,8 @@ var init_rest2 = __esm({
6589
6511
  });
6590
6512
 
6591
6513
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs
6592
- function ReturnType(schema10, options) {
6593
- return IsFunction2(schema10) ? CreateType(schema10.returns, options) : Never(options);
6514
+ function ReturnType(schema, options) {
6515
+ return IsFunction2(schema) ? CreateType(schema.returns, options) : Never(options);
6594
6516
  }
6595
6517
  var init_return_type = __esm({
6596
6518
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs"() {
@@ -6617,18 +6539,18 @@ var init_anyschema = __esm({
6617
6539
  });
6618
6540
 
6619
6541
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/schema.mjs
6620
- var init_schema = __esm({
6542
+ var init_schema2 = __esm({
6621
6543
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/schema.mjs"() {
6622
6544
  "use strict";
6623
6545
  }
6624
6546
  });
6625
6547
 
6626
6548
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/index.mjs
6627
- var init_schema2 = __esm({
6549
+ var init_schema3 = __esm({
6628
6550
  "../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/index.mjs"() {
6629
6551
  "use strict";
6630
6552
  init_anyschema();
6631
- init_schema();
6553
+ init_schema2();
6632
6554
  }
6633
6555
  });
6634
6556
 
@@ -6648,8 +6570,8 @@ var init_static2 = __esm({
6648
6570
  });
6649
6571
 
6650
6572
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/transform/transform.mjs
6651
- function Transform(schema10) {
6652
- return new TransformDecodeBuilder(schema10);
6573
+ function Transform(schema) {
6574
+ return new TransformDecodeBuilder(schema);
6653
6575
  }
6654
6576
  var TransformDecodeBuilder, TransformEncodeBuilder;
6655
6577
  var init_transform = __esm({
@@ -6658,27 +6580,27 @@ var init_transform = __esm({
6658
6580
  init_symbols2();
6659
6581
  init_kind();
6660
6582
  TransformDecodeBuilder = class {
6661
- constructor(schema10) {
6662
- this.schema = schema10;
6583
+ constructor(schema) {
6584
+ this.schema = schema;
6663
6585
  }
6664
6586
  Decode(decode) {
6665
6587
  return new TransformEncodeBuilder(this.schema, decode);
6666
6588
  }
6667
6589
  };
6668
6590
  TransformEncodeBuilder = class {
6669
- constructor(schema10, decode) {
6670
- this.schema = schema10;
6591
+ constructor(schema, decode) {
6592
+ this.schema = schema;
6671
6593
  this.decode = decode;
6672
6594
  }
6673
- EncodeTransform(encode, schema10) {
6674
- const Encode = (value) => schema10[TransformKind].Encode(encode(value));
6675
- const Decode = (value) => this.decode(schema10[TransformKind].Decode(value));
6595
+ EncodeTransform(encode, schema) {
6596
+ const Encode = (value) => schema[TransformKind].Encode(encode(value));
6597
+ const Decode = (value) => this.decode(schema[TransformKind].Decode(value));
6676
6598
  const Codec = { Encode, Decode };
6677
- return { ...schema10, [TransformKind]: Codec };
6599
+ return { ...schema, [TransformKind]: Codec };
6678
6600
  }
6679
- EncodeSchema(encode, schema10) {
6601
+ EncodeSchema(encode, schema) {
6680
6602
  const Codec = { Decode: this.decode, Encode: encode };
6681
- return { ...schema10, [TransformKind]: Codec };
6603
+ return { ...schema, [TransformKind]: Codec };
6682
6604
  }
6683
6605
  Encode(encode) {
6684
6606
  return IsTransform(this.schema) ? this.EncodeTransform(encode, this.schema) : this.EncodeSchema(encode, this.schema);
@@ -6937,7 +6859,7 @@ var init_esm = __esm({
6937
6859
  init_required2();
6938
6860
  init_rest2();
6939
6861
  init_return_type2();
6940
- init_schema2();
6862
+ init_schema3();
6941
6863
  init_static2();
6942
6864
  init_string2();
6943
6865
  init_symbol2();
@@ -6987,7 +6909,7 @@ var init_schemas = __esm({
6987
6909
  });
6988
6910
 
6989
6911
  // src/lib/contracts/auth.ts
6990
- var EMAIL_PATTERN, PHONE_PATTERN, FINGERPRINT_PATTERN, UUID_PATTERN, BASE64_PATTERN, sendVerificationCodeContract, verifyCodeContract, checkAccountExistsContract, registerContract, loginContract, logoutContract, rotateKeyContract, changePasswordContract;
6912
+ var EMAIL_PATTERN, PHONE_PATTERN, FINGERPRINT_PATTERN, UUID_PATTERN, BASE64_PATTERN, sendVerificationCodeContract, verifyCodeContract, checkAccountExistsContract, registerContract, loginContract, logoutContract, rotateKeyContract, changePasswordContract, getMeContract;
6991
6913
  var init_auth = __esm({
6992
6914
  "src/lib/contracts/auth.ts"() {
6993
6915
  "use strict";
@@ -7262,6 +7184,33 @@ var init_auth = __esm({
7262
7184
  })
7263
7185
  )
7264
7186
  };
7187
+ getMeContract = {
7188
+ method: "GET",
7189
+ path: "/_auth/me",
7190
+ body: Type.Object({}),
7191
+ response: ApiResponseSchema(
7192
+ Type.Object({
7193
+ userId: Type.String({ description: "User ID" }),
7194
+ email: Type.Optional(Type.String({ description: "User email address" })),
7195
+ phone: Type.Optional(Type.String({ description: "User phone number" })),
7196
+ role: Type.Object({
7197
+ id: Type.Number({ description: "Role ID" }),
7198
+ name: Type.String({ description: "Role name (e.g., user, admin)" }),
7199
+ displayName: Type.String({ description: "Display name for UI" }),
7200
+ priority: Type.Number({ description: "Role priority level" })
7201
+ }, { description: "User role information" }),
7202
+ permissions: Type.Array(
7203
+ Type.Object({
7204
+ id: Type.Number({ description: "Permission ID" }),
7205
+ name: Type.String({ description: "Permission name (e.g., user:delete)" }),
7206
+ displayName: Type.String({ description: "Display name for UI" }),
7207
+ category: Type.Optional(Type.String({ description: "Permission category" }))
7208
+ }),
7209
+ { description: "List of permissions granted through role" }
7210
+ )
7211
+ })
7212
+ )
7213
+ };
7265
7214
  }
7266
7215
  });
7267
7216
 
@@ -7514,9 +7463,55 @@ var init_contracts = __esm({
7514
7463
  }
7515
7464
  });
7516
7465
 
7466
+ // src/server/helpers/password.ts
7467
+ import bcrypt from "bcrypt";
7468
+ async function hashPassword(password) {
7469
+ if (!password || password.length === 0) {
7470
+ throw new Error("Password cannot be empty");
7471
+ }
7472
+ return bcrypt.hash(password, SALT_ROUNDS);
7473
+ }
7474
+ async function verifyPassword(password, hash) {
7475
+ if (!password || password.length === 0) {
7476
+ throw new Error("Password cannot be empty");
7477
+ }
7478
+ if (!hash || hash.length === 0) {
7479
+ throw new Error("Hash cannot be empty");
7480
+ }
7481
+ return bcrypt.compare(password, hash);
7482
+ }
7483
+ var SALT_ROUNDS;
7484
+ var init_password = __esm({
7485
+ "src/server/helpers/password.ts"() {
7486
+ "use strict";
7487
+ SALT_ROUNDS = parseInt(
7488
+ process.env.SPFN_AUTH_BCRYPT_SALT_ROUNDS || // New prefixed version (recommended)
7489
+ process.env.BCRYPT_SALT_ROUNDS || // Legacy fallback
7490
+ "10",
7491
+ 10
7492
+ );
7493
+ }
7494
+ });
7495
+
7517
7496
  // src/server/helpers/jwt.ts
7497
+ var jwt_exports = {};
7498
+ __export(jwt_exports, {
7499
+ decodeToken: () => decodeToken,
7500
+ generateToken: () => generateToken,
7501
+ verifyClientToken: () => verifyClientToken,
7502
+ verifyKeyFingerprint: () => verifyKeyFingerprint,
7503
+ verifyToken: () => verifyToken
7504
+ });
7518
7505
  import jwt from "jsonwebtoken";
7519
7506
  import crypto from "crypto";
7507
+ function generateToken(payload) {
7508
+ return jwt.sign(payload, JWT_SECRET, {
7509
+ expiresIn: JWT_EXPIRES_IN
7510
+ });
7511
+ }
7512
+ function verifyToken(token) {
7513
+ return jwt.verify(token, JWT_SECRET);
7514
+ }
7520
7515
  function verifyClientToken(token, publicKeyB64, algorithm) {
7521
7516
  try {
7522
7517
  const publicKeyDER = Buffer.from(publicKeyB64, "base64");
@@ -7545,6 +7540,13 @@ function verifyClientToken(token, publicKeyB64, algorithm) {
7545
7540
  throw new Error(`Token verification failed: ${error instanceof Error ? error.message : "Unknown error"}`);
7546
7541
  }
7547
7542
  }
7543
+ function decodeToken(token) {
7544
+ try {
7545
+ return jwt.decode(token);
7546
+ } catch {
7547
+ return null;
7548
+ }
7549
+ }
7548
7550
  function verifyKeyFingerprint(publicKeyB64, expectedFingerprint) {
7549
7551
  try {
7550
7552
  const publicKeyDER = Buffer.from(publicKeyB64, "base64");
@@ -7568,6 +7570,146 @@ var init_jwt = __esm({
7568
7570
  }
7569
7571
  });
7570
7572
 
7573
+ // src/server/helpers/verification.ts
7574
+ import jwt2 from "jsonwebtoken";
7575
+ import { getDatabase as getDatabase2, create } from "@spfn/core/db";
7576
+ import { eq as eq2, and as and2 } from "drizzle-orm";
7577
+ function getVerificationTokenSecret() {
7578
+ const secret = process.env.SPFN_AUTH_VERIFICATION_TOKEN_SECRET || // New prefixed version (recommended)
7579
+ process.env.VERIFICATION_TOKEN_SECRET || // Legacy fallback
7580
+ process.env.SPFN_AUTH_JWT_SECRET || // New JWT secret fallback
7581
+ process.env.JWT_SECRET;
7582
+ if (!secret || secret.length < 32) {
7583
+ throw new Error("SPFN_AUTH_VERIFICATION_TOKEN_SECRET must be at least 32 characters long");
7584
+ }
7585
+ return secret;
7586
+ }
7587
+ function generateVerificationCode() {
7588
+ const code = Math.floor(Math.random() * 1e6).toString().padStart(6, "0");
7589
+ return code;
7590
+ }
7591
+ async function storeVerificationCode(target, targetType, code, purpose) {
7592
+ const db = getDatabase2();
7593
+ if (!db) {
7594
+ throw new Error("Database not initialized");
7595
+ }
7596
+ const expiresAt = /* @__PURE__ */ new Date();
7597
+ expiresAt.setMinutes(expiresAt.getMinutes() + VERIFICATION_CODE_EXPIRY_MINUTES);
7598
+ const record = await create(verificationCodes, {
7599
+ target,
7600
+ targetType,
7601
+ code,
7602
+ purpose,
7603
+ expiresAt,
7604
+ attempts: "0"
7605
+ });
7606
+ return record;
7607
+ }
7608
+ async function validateVerificationCode(target, targetType, code, purpose) {
7609
+ const db = getDatabase2();
7610
+ if (!db) {
7611
+ throw new Error("Database not initialized");
7612
+ }
7613
+ const records = await db.select().from(verificationCodes).where(
7614
+ and2(
7615
+ eq2(verificationCodes.target, target),
7616
+ eq2(verificationCodes.targetType, targetType),
7617
+ eq2(verificationCodes.code, code),
7618
+ eq2(verificationCodes.purpose, purpose)
7619
+ )
7620
+ ).limit(1);
7621
+ if (records.length === 0) {
7622
+ return { valid: false, error: "Invalid verification code" };
7623
+ }
7624
+ const record = records[0];
7625
+ if (record.usedAt) {
7626
+ return { valid: false, error: "Verification code already used" };
7627
+ }
7628
+ if (/* @__PURE__ */ new Date() > new Date(record.expiresAt)) {
7629
+ return { valid: false, error: "Verification code expired" };
7630
+ }
7631
+ const attempts = parseInt(record.attempts, 10);
7632
+ if (attempts >= MAX_VERIFICATION_ATTEMPTS) {
7633
+ return { valid: false, error: "Too many attempts, please request a new code" };
7634
+ }
7635
+ await db.update(verificationCodes).set({ attempts: (attempts + 1).toString() }).where(eq2(verificationCodes.id, record.id));
7636
+ return { valid: true, codeId: record.id };
7637
+ }
7638
+ async function markCodeAsUsed(codeId) {
7639
+ const db = getDatabase2();
7640
+ if (!db) {
7641
+ throw new Error("Database not initialized");
7642
+ }
7643
+ await db.update(verificationCodes).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq2(verificationCodes.id, codeId));
7644
+ }
7645
+ function createVerificationToken(payload) {
7646
+ const secret = getVerificationTokenSecret();
7647
+ return jwt2.sign(payload, secret, {
7648
+ expiresIn: VERIFICATION_TOKEN_EXPIRY,
7649
+ issuer: "spfn-auth",
7650
+ audience: "spfn-client"
7651
+ });
7652
+ }
7653
+ function validateVerificationToken(token) {
7654
+ try {
7655
+ const secret = getVerificationTokenSecret();
7656
+ const decoded = jwt2.verify(token, secret, {
7657
+ issuer: "spfn-auth",
7658
+ audience: "spfn-client"
7659
+ });
7660
+ if (typeof decoded === "object" && decoded !== null && "target" in decoded && "targetType" in decoded && "purpose" in decoded && "codeId" in decoded) {
7661
+ return decoded;
7662
+ }
7663
+ return null;
7664
+ } catch (error) {
7665
+ console.error("[validateVerificationToken] Error:", error);
7666
+ return null;
7667
+ }
7668
+ }
7669
+ async function sendVerificationEmail(email, code, purpose) {
7670
+ console.log(`[VERIFICATION EMAIL] To: ${email}, Code: ${code}, Purpose: ${purpose}`);
7671
+ }
7672
+ async function sendVerificationSMS(phone, code, purpose) {
7673
+ console.log(`[VERIFICATION SMS] To: ${phone}, Code: ${code}, Purpose: ${purpose}`);
7674
+ }
7675
+ var VERIFICATION_TOKEN_EXPIRY, VERIFICATION_CODE_EXPIRY_MINUTES, MAX_VERIFICATION_ATTEMPTS;
7676
+ var init_verification = __esm({
7677
+ "src/server/helpers/verification.ts"() {
7678
+ "use strict";
7679
+ init_verification_codes();
7680
+ VERIFICATION_TOKEN_EXPIRY = "15m";
7681
+ VERIFICATION_CODE_EXPIRY_MINUTES = 5;
7682
+ MAX_VERIFICATION_ATTEMPTS = 5;
7683
+ }
7684
+ });
7685
+
7686
+ // src/server/helpers/context.ts
7687
+ function getAuth(c) {
7688
+ if ("raw" in c && c.raw) {
7689
+ return c.raw.get("auth");
7690
+ }
7691
+ return c.get("auth");
7692
+ }
7693
+ function getUser(c) {
7694
+ return getAuth(c).user;
7695
+ }
7696
+ var init_context2 = __esm({
7697
+ "src/server/helpers/context.ts"() {
7698
+ "use strict";
7699
+ }
7700
+ });
7701
+
7702
+ // src/server/helpers/index.ts
7703
+ var init_helpers3 = __esm({
7704
+ "src/server/helpers/index.ts"() {
7705
+ "use strict";
7706
+ init_password();
7707
+ init_jwt();
7708
+ init_verification();
7709
+ init_context2();
7710
+ }
7711
+ });
7712
+
7571
7713
  // src/server/errors/auth-errors.ts
7572
7714
  import {
7573
7715
  ValidationError,
@@ -7605,16 +7747,14 @@ var init_auth_errors = __esm({
7605
7747
  };
7606
7748
  AccountDisabledError = class extends ForbiddenError {
7607
7749
  constructor(status = "disabled") {
7608
- super(`Account is ${status}`);
7750
+ super(`Account is ${status}`, { details: { status } });
7609
7751
  this.name = "AccountDisabledError";
7610
- this.details = { status };
7611
7752
  }
7612
7753
  };
7613
7754
  AccountAlreadyExistsError = class extends ConflictError {
7614
7755
  constructor(identifier, identifierType) {
7615
- super("Account already exists");
7756
+ super("Account already exists", { details: { identifier, identifierType } });
7616
7757
  this.name = "AccountAlreadyExistsError";
7617
- this.details = { identifier, identifierType };
7618
7758
  }
7619
7759
  };
7620
7760
  InvalidVerificationCodeError = class extends ValidationError {
@@ -7637,9 +7777,8 @@ var init_auth_errors = __esm({
7637
7777
  };
7638
7778
  VerificationTokenPurposeMismatchError = class extends ValidationError {
7639
7779
  constructor(expected, actual) {
7640
- super(`Verification token is for ${actual}, but ${expected} was expected`);
7780
+ super(`Verification token is for ${actual}, but ${expected} was expected`, { details: { expected, actual } });
7641
7781
  this.name = "VerificationTokenPurposeMismatchError";
7642
- this.details = { expected, actual };
7643
7782
  }
7644
7783
  };
7645
7784
  VerificationTokenTargetMismatchError = class extends ValidationError {
@@ -7659,287 +7798,9 @@ var init_errors = __esm({
7659
7798
  }
7660
7799
  });
7661
7800
 
7662
- // src/server/middleware/authenticate.ts
7663
- import { findOne, getDatabase as getDatabase2 } from "@spfn/core/db";
7664
- import { UnauthorizedError as UnauthorizedError2 } from "@spfn/core/errors";
7665
- import { eq as eq2, and as and2 } from "drizzle-orm";
7666
- async function authenticate(c, next) {
7667
- const authHeader = c.req.header("Authorization");
7668
- const keyId = c.req.header("X-Key-Id");
7669
- if (!authHeader || !authHeader.startsWith("Bearer ")) {
7670
- throw new UnauthorizedError2("Missing or invalid authorization header");
7671
- }
7672
- if (!keyId) {
7673
- throw new UnauthorizedError2("Missing X-Key-Id header");
7674
- }
7675
- const token = authHeader.substring(7);
7676
- const db = getDatabase2();
7677
- const [keyRecord] = await db.select().from(userPublicKeys).where(
7678
- and2(
7679
- eq2(userPublicKeys.keyId, keyId),
7680
- eq2(userPublicKeys.isActive, true)
7681
- )
7682
- );
7683
- if (!keyRecord) {
7684
- throw new UnauthorizedError2("Invalid or revoked key");
7685
- }
7686
- if (keyRecord.expiresAt && /* @__PURE__ */ new Date() > keyRecord.expiresAt) {
7687
- throw new KeyExpiredError();
7688
- }
7689
- try {
7690
- verifyClientToken(
7691
- token,
7692
- keyRecord.publicKey,
7693
- keyRecord.algorithm
7694
- );
7695
- } catch (err) {
7696
- if (err instanceof Error) {
7697
- if (err.name === "TokenExpiredError") {
7698
- throw new TokenExpiredError();
7699
- }
7700
- if (err.name === "JsonWebTokenError") {
7701
- throw new InvalidTokenError("Invalid token signature");
7702
- }
7703
- }
7704
- throw new UnauthorizedError2("Authentication failed");
7705
- }
7706
- const user = await findOne(users, { id: keyRecord.userId });
7707
- if (!user) {
7708
- throw new UnauthorizedError2("User not found");
7709
- }
7710
- if (user.status !== "active") {
7711
- throw new AccountDisabledError(user.status);
7712
- }
7713
- db.update(userPublicKeys).set({ lastUsedAt: /* @__PURE__ */ new Date() }).where(eq2(userPublicKeys.id, keyRecord.id)).execute().catch((err) => console.error("Failed to update lastUsedAt:", err));
7714
- c.set("auth", {
7715
- user,
7716
- userId: String(user.id),
7717
- keyId
7718
- });
7719
- await next();
7720
- }
7721
- var init_authenticate = __esm({
7722
- "src/server/middleware/authenticate.ts"() {
7723
- "use strict";
7724
- init_jwt();
7725
- init_entities();
7726
- init_errors();
7727
- }
7728
- });
7729
-
7730
- // src/server/helpers/context.ts
7731
- function getAuth(c) {
7732
- if ("raw" in c && c.raw) {
7733
- return c.raw.get("auth");
7734
- }
7735
- return c.get("auth");
7736
- }
7737
- function getUser(c) {
7738
- return getAuth(c).user;
7739
- }
7740
- var init_context2 = __esm({
7741
- "src/server/helpers/context.ts"() {
7742
- "use strict";
7743
- }
7744
- });
7745
-
7746
- // src/server/services/permission.service.ts
7747
- import { getDatabase as getDatabase3 } from "@spfn/core/db";
7748
- import { eq as eq3, and as and3 } from "drizzle-orm";
7749
- var init_permission_service = __esm({
7750
- "src/server/services/permission.service.ts"() {
7751
- "use strict";
7752
- init_entities();
7753
- }
7754
- });
7755
-
7756
- // src/server/middleware/require-permission.ts
7757
- import { ForbiddenError as ForbiddenError2 } from "@spfn/core/errors";
7758
- var init_require_permission = __esm({
7759
- "src/server/middleware/require-permission.ts"() {
7760
- "use strict";
7761
- init_context2();
7762
- init_permission_service();
7763
- }
7764
- });
7765
-
7766
- // src/server/middleware/require-role.ts
7767
- import { ForbiddenError as ForbiddenError3 } from "@spfn/core/errors";
7768
- var init_require_role = __esm({
7769
- "src/server/middleware/require-role.ts"() {
7770
- "use strict";
7771
- init_context2();
7772
- init_permission_service();
7773
- }
7774
- });
7775
-
7776
- // src/server/middleware/index.ts
7777
- var init_middleware = __esm({
7778
- "src/server/middleware/index.ts"() {
7779
- "use strict";
7780
- init_authenticate();
7781
- init_require_permission();
7782
- init_require_role();
7783
- }
7784
- });
7785
-
7786
- // src/server/helpers/password.ts
7787
- import bcrypt from "bcrypt";
7788
- async function hashPassword(password) {
7789
- if (!password || password.length === 0) {
7790
- throw new Error("Password cannot be empty");
7791
- }
7792
- return bcrypt.hash(password, SALT_ROUNDS);
7793
- }
7794
- async function verifyPassword(password, hash) {
7795
- if (!password || password.length === 0) {
7796
- throw new Error("Password cannot be empty");
7797
- }
7798
- if (!hash || hash.length === 0) {
7799
- throw new Error("Hash cannot be empty");
7800
- }
7801
- return bcrypt.compare(password, hash);
7802
- }
7803
- var SALT_ROUNDS;
7804
- var init_password = __esm({
7805
- "src/server/helpers/password.ts"() {
7806
- "use strict";
7807
- SALT_ROUNDS = parseInt(
7808
- process.env.SPFN_AUTH_BCRYPT_SALT_ROUNDS || // New prefixed version (recommended)
7809
- process.env.BCRYPT_SALT_ROUNDS || // Legacy fallback
7810
- "10",
7811
- 10
7812
- );
7813
- }
7814
- });
7815
-
7816
- // src/server/helpers/verification.ts
7817
- import jwt2 from "jsonwebtoken";
7818
- import { getDatabase as getDatabase4, create } from "@spfn/core/db";
7819
- import { eq as eq4, and as and4 } from "drizzle-orm";
7820
- function getVerificationTokenSecret() {
7821
- const secret = process.env.SPFN_AUTH_VERIFICATION_TOKEN_SECRET || // New prefixed version (recommended)
7822
- process.env.VERIFICATION_TOKEN_SECRET || // Legacy fallback
7823
- process.env.SPFN_AUTH_JWT_SECRET || // New JWT secret fallback
7824
- process.env.JWT_SECRET;
7825
- if (!secret || secret.length < 32) {
7826
- throw new Error("SPFN_AUTH_VERIFICATION_TOKEN_SECRET must be at least 32 characters long");
7827
- }
7828
- return secret;
7829
- }
7830
- function generateVerificationCode() {
7831
- const code = Math.floor(Math.random() * 1e6).toString().padStart(6, "0");
7832
- return code;
7833
- }
7834
- async function storeVerificationCode(target, targetType, code, purpose) {
7835
- const db = getDatabase4();
7836
- if (!db) {
7837
- throw new Error("Database not initialized");
7838
- }
7839
- const expiresAt = /* @__PURE__ */ new Date();
7840
- expiresAt.setMinutes(expiresAt.getMinutes() + VERIFICATION_CODE_EXPIRY_MINUTES);
7841
- const record = await create(verificationCodes, {
7842
- target,
7843
- targetType,
7844
- code,
7845
- purpose,
7846
- expiresAt,
7847
- attempts: "0"
7848
- });
7849
- return record;
7850
- }
7851
- async function validateVerificationCode(target, targetType, code, purpose) {
7852
- const db = getDatabase4();
7853
- if (!db) {
7854
- throw new Error("Database not initialized");
7855
- }
7856
- const records = await db.select().from(verificationCodes).where(
7857
- and4(
7858
- eq4(verificationCodes.target, target),
7859
- eq4(verificationCodes.targetType, targetType),
7860
- eq4(verificationCodes.code, code),
7861
- eq4(verificationCodes.purpose, purpose)
7862
- )
7863
- ).limit(1);
7864
- if (records.length === 0) {
7865
- return { valid: false, error: "Invalid verification code" };
7866
- }
7867
- const record = records[0];
7868
- if (record.usedAt) {
7869
- return { valid: false, error: "Verification code already used" };
7870
- }
7871
- if (/* @__PURE__ */ new Date() > new Date(record.expiresAt)) {
7872
- return { valid: false, error: "Verification code expired" };
7873
- }
7874
- const attempts = parseInt(record.attempts, 10);
7875
- if (attempts >= MAX_VERIFICATION_ATTEMPTS) {
7876
- return { valid: false, error: "Too many attempts, please request a new code" };
7877
- }
7878
- await db.update(verificationCodes).set({ attempts: (attempts + 1).toString() }).where(eq4(verificationCodes.id, record.id));
7879
- return { valid: true, codeId: record.id };
7880
- }
7881
- async function markCodeAsUsed(codeId) {
7882
- const db = getDatabase4();
7883
- if (!db) {
7884
- throw new Error("Database not initialized");
7885
- }
7886
- await db.update(verificationCodes).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq4(verificationCodes.id, codeId));
7887
- }
7888
- function createVerificationToken(payload) {
7889
- const secret = getVerificationTokenSecret();
7890
- return jwt2.sign(payload, secret, {
7891
- expiresIn: VERIFICATION_TOKEN_EXPIRY,
7892
- issuer: "spfn-auth",
7893
- audience: "spfn-client"
7894
- });
7895
- }
7896
- function validateVerificationToken(token) {
7897
- try {
7898
- const secret = getVerificationTokenSecret();
7899
- const decoded = jwt2.verify(token, secret, {
7900
- issuer: "spfn-auth",
7901
- audience: "spfn-client"
7902
- });
7903
- if (typeof decoded === "object" && decoded !== null && "target" in decoded && "targetType" in decoded && "purpose" in decoded && "codeId" in decoded) {
7904
- return decoded;
7905
- }
7906
- return null;
7907
- } catch (error) {
7908
- console.error("[validateVerificationToken] Error:", error);
7909
- return null;
7910
- }
7911
- }
7912
- async function sendVerificationEmail(email, code, purpose) {
7913
- console.log(`[VERIFICATION EMAIL] To: ${email}, Code: ${code}, Purpose: ${purpose}`);
7914
- }
7915
- async function sendVerificationSMS(phone, code, purpose) {
7916
- console.log(`[VERIFICATION SMS] To: ${phone}, Code: ${code}, Purpose: ${purpose}`);
7917
- }
7918
- var VERIFICATION_TOKEN_EXPIRY, VERIFICATION_CODE_EXPIRY_MINUTES, MAX_VERIFICATION_ATTEMPTS;
7919
- var init_verification = __esm({
7920
- "src/server/helpers/verification.ts"() {
7921
- "use strict";
7922
- init_verification_codes();
7923
- VERIFICATION_TOKEN_EXPIRY = "15m";
7924
- VERIFICATION_CODE_EXPIRY_MINUTES = 5;
7925
- MAX_VERIFICATION_ATTEMPTS = 5;
7926
- }
7927
- });
7928
-
7929
- // src/server/helpers/index.ts
7930
- var init_helpers3 = __esm({
7931
- "src/server/helpers/index.ts"() {
7932
- "use strict";
7933
- init_password();
7934
- init_jwt();
7935
- init_verification();
7936
- init_context2();
7937
- }
7938
- });
7939
-
7940
7801
  // src/server/services/key.service.ts
7941
- import { create as create2, getDatabase as getDatabase5 } from "@spfn/core/db";
7942
- import { eq as eq5, and as and5 } from "drizzle-orm";
7802
+ import { create as create2, getDatabase as getDatabase3 } from "@spfn/core/db";
7803
+ import { eq as eq3, and as and3 } from "drizzle-orm";
7943
7804
  function getKeyExpiryDate() {
7944
7805
  const expiresAt = /* @__PURE__ */ new Date();
7945
7806
  expiresAt.setDate(expiresAt.getDate() + 90);
@@ -7968,15 +7829,15 @@ async function rotateKeyService(params) {
7968
7829
  if (!isValidFingerprint) {
7969
7830
  throw new InvalidKeyFingerprintError();
7970
7831
  }
7971
- const db = getDatabase5();
7832
+ const db = getDatabase3();
7972
7833
  await db.update(userPublicKeys).set({
7973
7834
  isActive: false,
7974
7835
  revokedAt: /* @__PURE__ */ new Date(),
7975
7836
  revokedReason: "Replaced by key rotation"
7976
7837
  }).where(
7977
- and5(
7978
- eq5(userPublicKeys.keyId, oldKeyId),
7979
- eq5(userPublicKeys.userId, userId)
7838
+ and3(
7839
+ eq3(userPublicKeys.keyId, oldKeyId),
7840
+ eq3(userPublicKeys.userId, userId)
7980
7841
  )
7981
7842
  );
7982
7843
  await create2(userPublicKeys, {
@@ -7996,15 +7857,15 @@ async function rotateKeyService(params) {
7996
7857
  }
7997
7858
  async function revokeKeyService(params) {
7998
7859
  const { userId, keyId, reason } = params;
7999
- const db = getDatabase5();
7860
+ const db = getDatabase3();
8000
7861
  await db.update(userPublicKeys).set({
8001
7862
  isActive: false,
8002
7863
  revokedAt: /* @__PURE__ */ new Date(),
8003
7864
  revokedReason: reason
8004
7865
  }).where(
8005
- and5(
8006
- eq5(userPublicKeys.keyId, keyId),
8007
- eq5(userPublicKeys.userId, userId)
7866
+ and3(
7867
+ eq3(userPublicKeys.keyId, keyId),
7868
+ eq3(userPublicKeys.userId, userId)
8008
7869
  )
8009
7870
  );
8010
7871
  }
@@ -8018,7 +7879,7 @@ var init_key_service = __esm({
8018
7879
  });
8019
7880
 
8020
7881
  // src/server/services/user.service.ts
8021
- import { findOne as findOne2, updateOne } from "@spfn/core/db";
7882
+ import { findOne, updateOne } from "@spfn/core/db";
8022
7883
  async function updateLastLoginService(userId) {
8023
7884
  await updateOne(users, { id: userId }, {
8024
7885
  lastLoginAt: /* @__PURE__ */ new Date()
@@ -8044,14 +7905,14 @@ __export(role_service_exports, {
8044
7905
  setRolePermissions: () => setRolePermissions,
8045
7906
  updateRole: () => updateRole
8046
7907
  });
8047
- import { getDatabase as getDatabase6 } from "@spfn/core/db";
8048
- import { eq as eq6, and as and6 } from "drizzle-orm";
7908
+ import { getDatabase as getDatabase4 } from "@spfn/core/db";
7909
+ import { eq as eq4, and as and4 } from "drizzle-orm";
8049
7910
  async function createRole(data) {
8050
- const db = getDatabase6();
7911
+ const db = getDatabase4();
8051
7912
  if (!db) {
8052
7913
  throw new Error("[Auth] Database not initialized");
8053
7914
  }
8054
- const existing = await db.select().from(roles).where(eq6(roles.name, data.name)).limit(1);
7915
+ const existing = await db.select().from(roles).where(eq4(roles.name, data.name)).limit(1);
8055
7916
  if (existing.length > 0) {
8056
7917
  throw new Error(`Role with name '${data.name}' already exists`);
8057
7918
  }
@@ -8075,28 +7936,28 @@ async function createRole(data) {
8075
7936
  return newRole;
8076
7937
  }
8077
7938
  async function updateRole(roleId, data) {
8078
- const db = getDatabase6();
7939
+ const db = getDatabase4();
8079
7940
  if (!db) {
8080
7941
  throw new Error("[Auth] Database not initialized");
8081
7942
  }
8082
7943
  const roleIdNum = Number(roleId);
8083
- const [role] = await db.select().from(roles).where(eq6(roles.id, roleIdNum)).limit(1);
7944
+ const [role] = await db.select().from(roles).where(eq4(roles.id, roleIdNum)).limit(1);
8084
7945
  if (!role) {
8085
7946
  throw new Error("Role not found");
8086
7947
  }
8087
7948
  if (role.isBuiltin && data.priority !== void 0) {
8088
7949
  throw new Error("Cannot modify priority of built-in roles");
8089
7950
  }
8090
- const [updated] = await db.update(roles).set(data).where(eq6(roles.id, roleIdNum)).returning();
7951
+ const [updated] = await db.update(roles).set(data).where(eq4(roles.id, roleIdNum)).returning();
8091
7952
  return updated;
8092
7953
  }
8093
7954
  async function deleteRole(roleId) {
8094
- const db = getDatabase6();
7955
+ const db = getDatabase4();
8095
7956
  if (!db) {
8096
7957
  throw new Error("[Auth] Database not initialized");
8097
7958
  }
8098
7959
  const roleIdNum = Number(roleId);
8099
- const [role] = await db.select().from(roles).where(eq6(roles.id, roleIdNum)).limit(1);
7960
+ const [role] = await db.select().from(roles).where(eq4(roles.id, roleIdNum)).limit(1);
8100
7961
  if (!role) {
8101
7962
  throw new Error("Role not found");
8102
7963
  }
@@ -8106,20 +7967,20 @@ async function deleteRole(roleId) {
8106
7967
  if (role.isSystem) {
8107
7968
  throw new Error(`Cannot delete system role: ${role.name}. Deactivate it instead.`);
8108
7969
  }
8109
- await db.delete(roles).where(eq6(roles.id, roleIdNum));
7970
+ await db.delete(roles).where(eq4(roles.id, roleIdNum));
8110
7971
  console.log(`[Auth] \u{1F5D1}\uFE0F Deleted role: ${role.name}`);
8111
7972
  }
8112
7973
  async function addPermissionToRole(roleId, permissionId) {
8113
- const db = getDatabase6();
7974
+ const db = getDatabase4();
8114
7975
  if (!db) {
8115
7976
  throw new Error("[Auth] Database not initialized");
8116
7977
  }
8117
7978
  const roleIdNum = Number(roleId);
8118
7979
  const permissionIdNum = Number(permissionId);
8119
7980
  const existing = await db.select().from(rolePermissions).where(
8120
- and6(
8121
- eq6(rolePermissions.roleId, roleIdNum),
8122
- eq6(rolePermissions.permissionId, permissionIdNum)
7981
+ and4(
7982
+ eq4(rolePermissions.roleId, roleIdNum),
7983
+ eq4(rolePermissions.permissionId, permissionIdNum)
8123
7984
  )
8124
7985
  ).limit(1);
8125
7986
  if (existing.length > 0) {
@@ -8131,26 +7992,26 @@ async function addPermissionToRole(roleId, permissionId) {
8131
7992
  });
8132
7993
  }
8133
7994
  async function removePermissionFromRole(roleId, permissionId) {
8134
- const db = getDatabase6();
7995
+ const db = getDatabase4();
8135
7996
  if (!db) {
8136
7997
  throw new Error("[Auth] Database not initialized");
8137
7998
  }
8138
7999
  const roleIdNum = Number(roleId);
8139
8000
  const permissionIdNum = Number(permissionId);
8140
8001
  await db.delete(rolePermissions).where(
8141
- and6(
8142
- eq6(rolePermissions.roleId, roleIdNum),
8143
- eq6(rolePermissions.permissionId, permissionIdNum)
8002
+ and4(
8003
+ eq4(rolePermissions.roleId, roleIdNum),
8004
+ eq4(rolePermissions.permissionId, permissionIdNum)
8144
8005
  )
8145
8006
  );
8146
8007
  }
8147
8008
  async function setRolePermissions(roleId, permissionIds) {
8148
- const db = getDatabase6();
8009
+ const db = getDatabase4();
8149
8010
  if (!db) {
8150
8011
  throw new Error("[Auth] Database not initialized");
8151
8012
  }
8152
8013
  const roleIdNum = Number(roleId);
8153
- await db.delete(rolePermissions).where(eq6(rolePermissions.roleId, roleIdNum));
8014
+ await db.delete(rolePermissions).where(eq4(rolePermissions.roleId, roleIdNum));
8154
8015
  if (permissionIds.length > 0) {
8155
8016
  const mappings = permissionIds.map((permId) => ({
8156
8017
  roleId: roleIdNum,
@@ -8160,31 +8021,31 @@ async function setRolePermissions(roleId, permissionIds) {
8160
8021
  }
8161
8022
  }
8162
8023
  async function getAllRoles(includeInactive = false) {
8163
- const db = getDatabase6();
8024
+ const db = getDatabase4();
8164
8025
  if (!db) {
8165
8026
  throw new Error("[Auth] Database not initialized");
8166
8027
  }
8167
8028
  const query = db.select().from(roles);
8168
8029
  if (!includeInactive) {
8169
- return query.where(eq6(roles.isActive, true));
8030
+ return query.where(eq4(roles.isActive, true));
8170
8031
  }
8171
8032
  return query;
8172
8033
  }
8173
8034
  async function getRoleByName(name) {
8174
- const db = getDatabase6();
8035
+ const db = getDatabase4();
8175
8036
  if (!db) {
8176
8037
  throw new Error("[Auth] Database not initialized");
8177
8038
  }
8178
- const [role] = await db.select().from(roles).where(eq6(roles.name, name)).limit(1);
8039
+ const [role] = await db.select().from(roles).where(eq4(roles.name, name)).limit(1);
8179
8040
  return role || null;
8180
8041
  }
8181
8042
  async function getRolePermissions(roleId) {
8182
- const db = getDatabase6();
8043
+ const db = getDatabase4();
8183
8044
  if (!db) {
8184
8045
  throw new Error("[Auth] Database not initialized");
8185
8046
  }
8186
8047
  const roleIdNum = Number(roleId);
8187
- const perms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq6(rolePermissions.permissionId, permissions.id)).where(eq6(rolePermissions.roleId, roleIdNum));
8048
+ const perms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq4(rolePermissions.permissionId, permissions.id)).where(eq4(rolePermissions.roleId, roleIdNum));
8188
8049
  return perms.map((p) => p.name);
8189
8050
  }
8190
8051
  var init_role_service = __esm({
@@ -8195,7 +8056,7 @@ var init_role_service = __esm({
8195
8056
  });
8196
8057
 
8197
8058
  // src/server/services/auth.service.ts
8198
- import { findOne as findOne3, create as create3 } from "@spfn/core/db";
8059
+ import { findOne as findOne2, create as create3 } from "@spfn/core/db";
8199
8060
  import { ValidationError as ValidationError2 } from "@spfn/core/errors";
8200
8061
  async function checkAccountExistsService(params) {
8201
8062
  const { email, phone } = params;
@@ -8205,11 +8066,11 @@ async function checkAccountExistsService(params) {
8205
8066
  if (email) {
8206
8067
  identifier = email;
8207
8068
  identifierType = "email";
8208
- user = await findOne3(users, { email });
8069
+ user = await findOne2(users, { email });
8209
8070
  } else if (phone) {
8210
8071
  identifier = phone;
8211
8072
  identifierType = "phone";
8212
- user = await findOne3(users, { phone });
8073
+ user = await findOne2(users, { phone });
8213
8074
  } else {
8214
8075
  throw new ValidationError2("Either email or phone must be provided");
8215
8076
  }
@@ -8238,9 +8099,9 @@ async function registerService(params) {
8238
8099
  }
8239
8100
  let existingUser;
8240
8101
  if (email) {
8241
- existingUser = await findOne3(users, { email });
8102
+ existingUser = await findOne2(users, { email });
8242
8103
  } else if (phone) {
8243
- existingUser = await findOne3(users, { phone });
8104
+ existingUser = await findOne2(users, { phone });
8244
8105
  } else {
8245
8106
  throw new ValidationError2("Either email or phone must be provided");
8246
8107
  }
@@ -8281,9 +8142,9 @@ async function loginService(params) {
8281
8142
  const { email, phone, password, publicKey, keyId, fingerprint, oldKeyId, algorithm } = params;
8282
8143
  let user;
8283
8144
  if (email) {
8284
- user = await findOne3(users, { email });
8145
+ user = await findOne2(users, { email });
8285
8146
  } else if (phone) {
8286
- user = await findOne3(users, { phone });
8147
+ user = await findOne2(users, { phone });
8287
8148
  } else {
8288
8149
  throw new ValidationError2("Either email or phone must be provided");
8289
8150
  }
@@ -8333,7 +8194,7 @@ async function changePasswordService(params) {
8333
8194
  if (providedHash) {
8334
8195
  passwordHash = providedHash;
8335
8196
  } else {
8336
- const user = await findOne3(users, { id: userId });
8197
+ const user = await findOne2(users, { id: userId });
8337
8198
  if (!user) {
8338
8199
  throw new ValidationError2("User not found");
8339
8200
  }
@@ -8407,6 +8268,136 @@ var init_verification_service = __esm({
8407
8268
  }
8408
8269
  });
8409
8270
 
8271
+ // src/server/services/me.service.ts
8272
+ import { getDatabase as getDatabase5 } from "@spfn/core/db";
8273
+ import { eq as eq5, and as and5 } from "drizzle-orm";
8274
+ async function getMeService(userId) {
8275
+ const db = getDatabase5();
8276
+ if (!db) {
8277
+ throw new Error("[Auth] Database not initialized");
8278
+ }
8279
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
8280
+ const [userWithRole] = await db.select({
8281
+ userId: users.id,
8282
+ email: users.email,
8283
+ phone: users.phone,
8284
+ roleId: roles.id,
8285
+ roleName: roles.name,
8286
+ roleDisplayName: roles.displayName,
8287
+ rolePriority: roles.priority
8288
+ }).from(users).innerJoin(roles, eq5(users.roleId, roles.id)).where(eq5(users.id, userIdNum)).limit(1);
8289
+ if (!userWithRole) {
8290
+ throw new Error("[Auth] User not found");
8291
+ }
8292
+ const rolePerms = await db.select({
8293
+ id: permissions.id,
8294
+ name: permissions.name,
8295
+ displayName: permissions.displayName,
8296
+ category: permissions.category
8297
+ }).from(rolePermissions).innerJoin(permissions, eq5(rolePermissions.permissionId, permissions.id)).where(
8298
+ and5(
8299
+ eq5(rolePermissions.roleId, userWithRole.roleId),
8300
+ eq5(permissions.isActive, true)
8301
+ )
8302
+ );
8303
+ return {
8304
+ userId: userWithRole.userId.toString(),
8305
+ email: userWithRole.email ?? void 0,
8306
+ phone: userWithRole.phone ?? void 0,
8307
+ role: {
8308
+ id: userWithRole.roleId,
8309
+ name: userWithRole.roleName,
8310
+ displayName: userWithRole.roleDisplayName,
8311
+ priority: userWithRole.rolePriority
8312
+ },
8313
+ permissions: rolePerms.map((perm) => ({
8314
+ id: perm.id,
8315
+ name: perm.name,
8316
+ displayName: perm.displayName,
8317
+ category: perm.category ?? void 0
8318
+ }))
8319
+ };
8320
+ }
8321
+ var init_me_service = __esm({
8322
+ "src/server/services/me.service.ts"() {
8323
+ "use strict";
8324
+ init_entities();
8325
+ }
8326
+ });
8327
+
8328
+ // src/server/services/permission.service.ts
8329
+ import { getDatabase as getDatabase6 } from "@spfn/core/db";
8330
+ import { eq as eq6, and as and6 } from "drizzle-orm";
8331
+ async function getUserPermissions(userId) {
8332
+ const db = getDatabase6();
8333
+ if (!db) {
8334
+ throw new Error("[Auth] Database not initialized");
8335
+ }
8336
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
8337
+ const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq6(users.id, userIdNum)).limit(1);
8338
+ if (!user || !user.roleId) {
8339
+ return [];
8340
+ }
8341
+ const permSet = /* @__PURE__ */ new Set();
8342
+ const rolePerms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq6(rolePermissions.permissionId, permissions.id)).where(
8343
+ and6(
8344
+ eq6(rolePermissions.roleId, user.roleId),
8345
+ eq6(permissions.isActive, true)
8346
+ )
8347
+ );
8348
+ for (const perm of rolePerms) {
8349
+ permSet.add(perm.name);
8350
+ }
8351
+ const userPerms = await db.select({
8352
+ name: permissions.name,
8353
+ granted: userPermissions.granted,
8354
+ expiresAt: userPermissions.expiresAt
8355
+ }).from(userPermissions).innerJoin(permissions, eq6(userPermissions.permissionId, permissions.id)).where(eq6(userPermissions.userId, userIdNum));
8356
+ const now = /* @__PURE__ */ new Date();
8357
+ for (const userPerm of userPerms) {
8358
+ if (userPerm.expiresAt && userPerm.expiresAt < now) {
8359
+ continue;
8360
+ }
8361
+ if (userPerm.granted) {
8362
+ permSet.add(userPerm.name);
8363
+ } else {
8364
+ permSet.delete(userPerm.name);
8365
+ }
8366
+ }
8367
+ return Array.from(permSet);
8368
+ }
8369
+ async function hasAllPermissions(userId, permissionNames) {
8370
+ const perms = await getUserPermissions(userId);
8371
+ return permissionNames.every((p) => perms.includes(p));
8372
+ }
8373
+ async function hasRole(userId, roleName) {
8374
+ const db = getDatabase6();
8375
+ if (!db) {
8376
+ throw new Error("[Auth] Database not initialized");
8377
+ }
8378
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
8379
+ const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq6(users.id, userIdNum)).limit(1);
8380
+ if (!user || !user.roleId) {
8381
+ return false;
8382
+ }
8383
+ const [role] = await db.select({ name: roles.name }).from(roles).where(eq6(roles.id, user.roleId)).limit(1);
8384
+ return role?.name === roleName;
8385
+ }
8386
+ async function hasAnyRole(userId, roleNames) {
8387
+ for (const roleName of roleNames) {
8388
+ if (await hasRole(userId, roleName)) {
8389
+ return true;
8390
+ }
8391
+ }
8392
+ return false;
8393
+ }
8394
+ var init_permission_service = __esm({
8395
+ "src/server/services/permission.service.ts"() {
8396
+ "use strict";
8397
+ init_entities();
8398
+ }
8399
+ });
8400
+
8410
8401
  // src/server/services/invitation.service.ts
8411
8402
  import { getDatabase as getDatabase7 } from "@spfn/core/db";
8412
8403
  import { eq as eq7, and as and7, lt, desc, sql as sql2 } from "drizzle-orm";
@@ -8685,6 +8676,7 @@ var init_services = __esm({
8685
8676
  init_verification_service();
8686
8677
  init_key_service();
8687
8678
  init_user_service();
8679
+ init_me_service();
8688
8680
  init_rbac_service();
8689
8681
  init_permission_service();
8690
8682
  init_role_service();
@@ -8699,7 +8691,6 @@ var init_auth2 = __esm({
8699
8691
  "src/server/routes/auth/index.ts"() {
8700
8692
  "use strict";
8701
8693
  init_contracts();
8702
- init_middleware();
8703
8694
  init_helpers3();
8704
8695
  init_services();
8705
8696
  app = createApp();
@@ -8728,12 +8719,16 @@ var init_auth2 = __esm({
8728
8719
  const result = await loginService(body);
8729
8720
  return c.success(result);
8730
8721
  });
8731
- app.bind(logoutContract, [authenticate], async (c) => {
8732
- const { keyId, userId } = getAuth(c);
8722
+ app.bind(logoutContract, async (c) => {
8723
+ const auth = getAuth(c);
8724
+ if (!auth) {
8725
+ return c.success({ success: true });
8726
+ }
8727
+ const { keyId, userId } = auth;
8733
8728
  await logoutService({ userId: Number(userId), keyId });
8734
8729
  return c.success({ success: true });
8735
8730
  });
8736
- app.bind(rotateKeyContract, [authenticate], async (c) => {
8731
+ app.bind(rotateKeyContract, async (c) => {
8737
8732
  const body = await c.data();
8738
8733
  const { keyId: oldKeyId, userId } = getAuth(c);
8739
8734
  const result = await rotateKeyService({
@@ -8746,7 +8741,7 @@ var init_auth2 = __esm({
8746
8741
  });
8747
8742
  return c.success(result);
8748
8743
  });
8749
- app.bind(changePasswordContract, [authenticate], async (c) => {
8744
+ app.bind(changePasswordContract, async (c) => {
8750
8745
  const body = await c.data();
8751
8746
  const user = getUser(c);
8752
8747
  await changePasswordService({
@@ -8757,10 +8752,147 @@ var init_auth2 = __esm({
8757
8752
  });
8758
8753
  return c.success({ success: true });
8759
8754
  });
8755
+ app.bind(getMeContract, async (c) => {
8756
+ const { userId } = getAuth(c);
8757
+ const result = await getMeService(userId);
8758
+ return c.success(result);
8759
+ });
8760
8760
  auth_default = app;
8761
8761
  }
8762
8762
  });
8763
8763
 
8764
+ // src/server/middleware/authenticate.ts
8765
+ import { findOne as findOne3, getDatabase as getDatabase8 } from "@spfn/core/db";
8766
+ import { UnauthorizedError as UnauthorizedError2 } from "@spfn/core/errors";
8767
+ import { eq as eq8, and as and8 } from "drizzle-orm";
8768
+ async function authenticate(c, next) {
8769
+ const authHeader = c.req.header("Authorization");
8770
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
8771
+ throw new UnauthorizedError2("Missing or invalid authorization header");
8772
+ }
8773
+ const token = authHeader.substring(7);
8774
+ const { decodeToken: decodeToken2 } = await Promise.resolve().then(() => (init_jwt(), jwt_exports));
8775
+ const decoded = decodeToken2(token);
8776
+ if (!decoded || !decoded.keyId) {
8777
+ throw new UnauthorizedError2("Invalid token: missing keyId");
8778
+ }
8779
+ const keyId = decoded.keyId;
8780
+ const db = getDatabase8();
8781
+ const [keyRecord] = await db.select().from(userPublicKeys).where(
8782
+ and8(
8783
+ eq8(userPublicKeys.keyId, keyId),
8784
+ eq8(userPublicKeys.isActive, true)
8785
+ )
8786
+ );
8787
+ if (!keyRecord) {
8788
+ throw new UnauthorizedError2("Invalid or revoked key");
8789
+ }
8790
+ if (keyRecord.expiresAt && /* @__PURE__ */ new Date() > keyRecord.expiresAt) {
8791
+ throw new KeyExpiredError();
8792
+ }
8793
+ try {
8794
+ verifyClientToken(
8795
+ token,
8796
+ keyRecord.publicKey,
8797
+ keyRecord.algorithm
8798
+ );
8799
+ } catch (err) {
8800
+ if (err instanceof Error) {
8801
+ if (err.name === "TokenExpiredError") {
8802
+ throw new TokenExpiredError();
8803
+ }
8804
+ if (err.name === "JsonWebTokenError") {
8805
+ throw new InvalidTokenError("Invalid token signature");
8806
+ }
8807
+ }
8808
+ throw new UnauthorizedError2("Authentication failed");
8809
+ }
8810
+ const user = await findOne3(users, { id: keyRecord.userId });
8811
+ if (!user) {
8812
+ throw new UnauthorizedError2("User not found");
8813
+ }
8814
+ if (user.status !== "active") {
8815
+ throw new AccountDisabledError(user.status);
8816
+ }
8817
+ db.update(userPublicKeys).set({ lastUsedAt: /* @__PURE__ */ new Date() }).where(eq8(userPublicKeys.id, keyRecord.id)).execute().catch((err) => console.error("Failed to update lastUsedAt:", err));
8818
+ c.set("auth", {
8819
+ user,
8820
+ userId: String(user.id),
8821
+ keyId
8822
+ });
8823
+ await next();
8824
+ }
8825
+ var init_authenticate = __esm({
8826
+ "src/server/middleware/authenticate.ts"() {
8827
+ "use strict";
8828
+ init_jwt();
8829
+ init_entities();
8830
+ init_errors();
8831
+ }
8832
+ });
8833
+
8834
+ // src/server/middleware/require-permission.ts
8835
+ import { ForbiddenError as ForbiddenError2 } from "@spfn/core/errors";
8836
+ function requirePermissions(...permissionNames) {
8837
+ return async (c, next) => {
8838
+ const auth = getAuth(c);
8839
+ if (!auth) {
8840
+ throw new ForbiddenError2("Authentication required");
8841
+ }
8842
+ const { userId } = auth;
8843
+ const allowed = await hasAllPermissions(userId, permissionNames);
8844
+ if (!allowed) {
8845
+ throw new ForbiddenError2(
8846
+ `Missing required permissions: ${permissionNames.join(", ")}`
8847
+ );
8848
+ }
8849
+ await next();
8850
+ };
8851
+ }
8852
+ var init_require_permission = __esm({
8853
+ "src/server/middleware/require-permission.ts"() {
8854
+ "use strict";
8855
+ init_context2();
8856
+ init_permission_service();
8857
+ }
8858
+ });
8859
+
8860
+ // src/server/middleware/require-role.ts
8861
+ import { ForbiddenError as ForbiddenError3 } from "@spfn/core/errors";
8862
+ function requireRole(...roleNames) {
8863
+ return async (c, next) => {
8864
+ const auth = getAuth(c);
8865
+ if (!auth) {
8866
+ throw new ForbiddenError3("Authentication required");
8867
+ }
8868
+ const { userId } = auth;
8869
+ const allowed = await hasAnyRole(userId, roleNames);
8870
+ if (!allowed) {
8871
+ throw new ForbiddenError3(
8872
+ `Required roles: ${roleNames.join(", ")}`
8873
+ );
8874
+ }
8875
+ await next();
8876
+ };
8877
+ }
8878
+ var init_require_role = __esm({
8879
+ "src/server/middleware/require-role.ts"() {
8880
+ "use strict";
8881
+ init_context2();
8882
+ init_permission_service();
8883
+ }
8884
+ });
8885
+
8886
+ // src/server/middleware/index.ts
8887
+ var init_middleware = __esm({
8888
+ "src/server/middleware/index.ts"() {
8889
+ "use strict";
8890
+ init_authenticate();
8891
+ init_require_permission();
8892
+ init_require_role();
8893
+ }
8894
+ });
8895
+
8764
8896
  // src/server/routes/invitations/index.ts
8765
8897
  import { createApp as createApp2 } from "@spfn/core/route";
8766
8898
  var app2, invitations_default;
@@ -8804,7 +8936,7 @@ var init_invitations2 = __esm({
8804
8936
  });
8805
8937
  return c.success(result);
8806
8938
  });
8807
- app2.bind(createInvitationContract, [authenticate], async (c) => {
8939
+ app2.bind(createInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
8808
8940
  const body = await c.data();
8809
8941
  const { userId } = getAuth(c);
8810
8942
  const invitation = await createInvitation({
@@ -8825,7 +8957,7 @@ var init_invitations2 = __esm({
8825
8957
  invitationUrl
8826
8958
  });
8827
8959
  });
8828
- app2.bind(listInvitationsContract, [authenticate], async (c) => {
8960
+ app2.bind(listInvitationsContract, [authenticate, requirePermissions("user:read")], async (c) => {
8829
8961
  const query = await c.data();
8830
8962
  const result = await listInvitations({
8831
8963
  status: query.status,
@@ -8844,7 +8976,7 @@ var init_invitations2 = __esm({
8844
8976
  invitations: formattedInvitations
8845
8977
  });
8846
8978
  });
8847
- app2.bind(cancelInvitationContract, [authenticate], async (c) => {
8979
+ app2.bind(cancelInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
8848
8980
  const data = await c.data();
8849
8981
  const { userId } = getAuth(c);
8850
8982
  await cancelInvitation(
@@ -8857,7 +8989,7 @@ var init_invitations2 = __esm({
8857
8989
  cancelledAt: (/* @__PURE__ */ new Date()).toISOString()
8858
8990
  });
8859
8991
  });
8860
- app2.bind(resendInvitationContract, [authenticate], async (c) => {
8992
+ app2.bind(resendInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
8861
8993
  const data = await c.data();
8862
8994
  const updated = await resendInvitation(
8863
8995
  data.id,
@@ -8868,7 +9000,7 @@ var init_invitations2 = __esm({
8868
9000
  expiresAt: updated.expiresAt.toISOString()
8869
9001
  });
8870
9002
  });
8871
- app2.bind(deleteInvitationContract, [authenticate], async (c) => {
9003
+ app2.bind(deleteInvitationContract, [authenticate, requireRole("superadmin")], async (c) => {
8872
9004
  const data = await c.data();
8873
9005
  await deleteInvitation(data.id);
8874
9006
  return c.success({
@@ -8900,8 +9032,8 @@ var init_routes = __esm({
8900
9032
 
8901
9033
  // src/plugin.ts
8902
9034
  init_rbac_service();
8903
- import { logger } from "@spfn/core/logger";
8904
- var authLogger = logger.child("auth-plugin");
9035
+ import { logger as logger2 } from "@spfn/core/logger";
9036
+ var authLogger2 = logger2.child("auth-plugin");
8905
9037
  var spfnPlugin = {
8906
9038
  name: "@spfn/auth",
8907
9039
  /**
@@ -8909,12 +9041,12 @@ var spfnPlugin = {
8909
9041
  * Creates default roles (user, admin, superadmin) and permissions
8910
9042
  */
8911
9043
  afterInfrastructure: async () => {
8912
- authLogger.info("Initializing authentication system...");
9044
+ authLogger2.info("Initializing authentication system...");
8913
9045
  try {
8914
9046
  await initializeAuth();
8915
- authLogger.info("Authentication system initialized successfully");
9047
+ authLogger2.info("Authentication system initialized successfully");
8916
9048
  } catch (error) {
8917
- authLogger.error("Failed to initialize authentication system", error);
9049
+ authLogger2.error("Failed to initialize authentication system", error);
8918
9050
  throw error;
8919
9051
  }
8920
9052
  },
@@ -8923,13 +9055,13 @@ var spfnPlugin = {
8923
9055
  * Routes are auto-discovered from src/server/routes
8924
9056
  */
8925
9057
  beforeRoutes: async (app4) => {
8926
- authLogger.info("Mounting authentication routes...");
9058
+ authLogger2.info("Mounting authentication routes...");
8927
9059
  try {
8928
9060
  const authRoutes = await Promise.resolve().then(() => (init_routes(), routes_exports));
8929
9061
  app4.route("/_auth", authRoutes.default);
8930
- authLogger.info("Authentication routes mounted at /_auth");
9062
+ authLogger2.info("Authentication routes mounted at /_auth");
8931
9063
  } catch (error) {
8932
- authLogger.error("Failed to mount authentication routes", error);
9064
+ authLogger2.error("Failed to mount authentication routes", error);
8933
9065
  throw error;
8934
9066
  }
8935
9067
  },
@@ -8937,7 +9069,7 @@ var spfnPlugin = {
8937
9069
  * Log successful startup
8938
9070
  */
8939
9071
  afterStart: async () => {
8940
- authLogger.info("@spfn/auth plugin started successfully", {
9072
+ authLogger2.info("@spfn/auth plugin started successfully", {
8941
9073
  routes: "/_auth/*",
8942
9074
  rbac: "enabled"
8943
9075
  });