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

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 +7438 -7304
  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 +7438 -7304
  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 +497 -512
  113. package/dist/server/routes/auth/index.js.map +1 -1
  114. package/dist/server/routes/index.js +777 -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 +323 -327
  120. package/dist/server.js.map +1 -1
  121. package/migrations/{0000_tired_gambit.sql → 0000_familiar_firebrand.sql} +2 -0
  122. package/migrations/meta/0000_snapshot.json +4 -2
  123. package/migrations/meta/_journal.json +2 -2
  124. package/package.json +41 -7
@@ -8,26 +8,160 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/server/helpers/jwt.ts
12
+ var jwt_exports = {};
13
+ __export(jwt_exports, {
14
+ decodeToken: () => decodeToken,
15
+ generateToken: () => generateToken,
16
+ verifyClientToken: () => verifyClientToken,
17
+ verifyKeyFingerprint: () => verifyKeyFingerprint,
18
+ verifyToken: () => verifyToken
19
+ });
20
+ import jwt from "jsonwebtoken";
21
+ import crypto from "crypto";
22
+ function generateToken(payload) {
23
+ return jwt.sign(payload, JWT_SECRET, {
24
+ expiresIn: JWT_EXPIRES_IN
25
+ });
26
+ }
27
+ function verifyToken(token) {
28
+ return jwt.verify(token, JWT_SECRET);
29
+ }
30
+ function verifyClientToken(token, publicKeyB64, algorithm) {
31
+ try {
32
+ const publicKeyDER = Buffer.from(publicKeyB64, "base64");
33
+ const publicKeyObject = crypto.createPublicKey({
34
+ key: publicKeyDER,
35
+ format: "der",
36
+ type: "spki"
37
+ });
38
+ const decoded = jwt.verify(token, publicKeyObject, {
39
+ algorithms: [algorithm],
40
+ // Prevent algorithm confusion attacks
41
+ issuer: "spfn-client"
42
+ // Validate token issuer
43
+ });
44
+ if (typeof decoded === "string") {
45
+ throw new Error("Invalid token format: expected object payload");
46
+ }
47
+ return decoded;
48
+ } catch (error) {
49
+ if (error instanceof jwt.TokenExpiredError) {
50
+ throw new Error("Token has expired");
51
+ }
52
+ if (error instanceof jwt.JsonWebTokenError) {
53
+ throw new Error("Invalid token signature");
54
+ }
55
+ throw new Error(`Token verification failed: ${error instanceof Error ? error.message : "Unknown error"}`);
56
+ }
57
+ }
58
+ function decodeToken(token) {
59
+ try {
60
+ return jwt.decode(token);
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+ function verifyKeyFingerprint(publicKeyB64, expectedFingerprint) {
66
+ try {
67
+ const publicKeyDER = Buffer.from(publicKeyB64, "base64");
68
+ const fingerprint = crypto.createHash("sha256").update(publicKeyDER).digest("hex");
69
+ return fingerprint === expectedFingerprint;
70
+ } catch (error) {
71
+ console.error("Failed to verify key fingerprint:", error);
72
+ return false;
73
+ }
74
+ }
75
+ var JWT_SECRET, JWT_EXPIRES_IN;
76
+ var init_jwt = __esm({
77
+ "src/server/helpers/jwt.ts"() {
78
+ "use strict";
79
+ JWT_SECRET = process.env.SPFN_AUTH_JWT_SECRET || // New prefixed version (recommended)
80
+ process.env.JWT_SECRET || // Legacy fallback
81
+ "dev-secret-key-change-in-production";
82
+ JWT_EXPIRES_IN = process.env.SPFN_AUTH_JWT_EXPIRES_IN || // New prefixed version (recommended)
83
+ process.env.JWT_EXPIRES_IN || // Legacy fallback
84
+ "7d";
85
+ }
86
+ });
87
+
88
+ // src/server/entities/schema.ts
89
+ import { createFunctionSchema } from "@spfn/core/db";
90
+ var authSchema;
91
+ var init_schema = __esm({
92
+ "src/server/entities/schema.ts"() {
93
+ "use strict";
94
+ authSchema = createFunctionSchema("@spfn/auth");
95
+ }
96
+ });
97
+
98
+ // src/server/entities/verification-codes.ts
99
+ import { text, timestamp, index } from "drizzle-orm/pg-core";
100
+ import { id, timestamps } from "@spfn/core/db";
101
+ var verificationCodes;
102
+ var init_verification_codes = __esm({
103
+ "src/server/entities/verification-codes.ts"() {
104
+ "use strict";
105
+ init_schema();
106
+ verificationCodes = authSchema.table(
107
+ "verification_codes",
108
+ {
109
+ id: id(),
110
+ // Target (email or phone)
111
+ target: text("target").notNull(),
112
+ // Email address or E.164 phone number
113
+ targetType: text(
114
+ "target_type",
115
+ {
116
+ enum: ["email", "phone"]
117
+ }
118
+ ).notNull(),
119
+ // Code
120
+ code: text("code").notNull(),
121
+ // 6-digit code by default (configurable)
122
+ // Purpose
123
+ purpose: text(
124
+ "purpose",
125
+ {
126
+ enum: ["registration", "login", "password_reset", "email_change", "phone_change"]
127
+ }
128
+ ).notNull(),
129
+ // Expiry
130
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
131
+ // Usage tracking
132
+ usedAt: timestamp("used_at", { withTimezone: true }),
133
+ attempts: text("attempts").notNull().default("0"),
134
+ // Track failed verification attempts
135
+ ...timestamps()
136
+ },
137
+ (table) => [
138
+ // Index for quick lookup by target and purpose
139
+ index("target_purpose_idx").on(table.target, table.purpose, table.expiresAt)
140
+ ]
141
+ );
142
+ }
143
+ });
144
+
11
145
  // src/server/entities/roles.ts
12
- import { text, boolean, integer, index } from "drizzle-orm/pg-core";
13
- import { id, timestamps, createFunctionSchema } from "@spfn/core/db";
14
- var schema, roles;
146
+ import { text as text2, boolean, integer, index as index2 } from "drizzle-orm/pg-core";
147
+ import { id as id2, timestamps as timestamps2 } from "@spfn/core/db";
148
+ var roles;
15
149
  var init_roles = __esm({
16
150
  "src/server/entities/roles.ts"() {
17
151
  "use strict";
18
- schema = createFunctionSchema("@spfn/auth");
19
- roles = schema.table(
152
+ init_schema();
153
+ roles = authSchema.table(
20
154
  "roles",
21
155
  {
22
156
  // Primary key
23
- id: id(),
157
+ id: id2(),
24
158
  // Role identifier (used in code, e.g., 'admin', 'editor')
25
159
  // Must be unique, lowercase, kebab-case recommended
26
- name: text("name").notNull().unique(),
160
+ name: text2("name").notNull().unique(),
27
161
  // Display name for UI (e.g., 'Administrator', 'Content Editor')
28
- displayName: text("display_name").notNull(),
162
+ displayName: text2("display_name").notNull(),
29
163
  // Role description
30
- description: text("description"),
164
+ description: text2("description"),
31
165
  // Built-in role flag
32
166
  // true: Core package roles (user, admin, superadmin) - cannot be deleted
33
167
  // false: Custom or preset roles - can be deleted
@@ -43,45 +177,45 @@ var init_roles = __esm({
43
177
  // superadmin: 100, admin: 80, user: 10
44
178
  // Used for role hierarchy and conflict resolution
45
179
  priority: integer("priority").notNull().default(10),
46
- ...timestamps()
180
+ ...timestamps2()
47
181
  },
48
182
  (table) => [
49
- index("roles_name_idx").on(table.name),
50
- index("roles_is_system_idx").on(table.isSystem),
51
- index("roles_is_active_idx").on(table.isActive),
52
- index("roles_is_builtin_idx").on(table.isBuiltin),
53
- index("roles_priority_idx").on(table.priority)
183
+ index2("roles_name_idx").on(table.name),
184
+ index2("roles_is_system_idx").on(table.isSystem),
185
+ index2("roles_is_active_idx").on(table.isActive),
186
+ index2("roles_is_builtin_idx").on(table.isBuiltin),
187
+ index2("roles_priority_idx").on(table.priority)
54
188
  ]
55
189
  );
56
190
  }
57
191
  });
58
192
 
59
193
  // src/server/entities/users.ts
60
- 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";
194
+ import { text as text3, timestamp as timestamp2, check, boolean as boolean2, bigint, index as index3 } from "drizzle-orm/pg-core";
195
+ import { id as id3, timestamps as timestamps3 } from "@spfn/core/db";
62
196
  import { sql } from "drizzle-orm";
63
- var schema2, users;
197
+ var users;
64
198
  var init_users = __esm({
65
199
  "src/server/entities/users.ts"() {
66
200
  "use strict";
67
201
  init_roles();
68
- schema2 = createFunctionSchema2("@spfn/auth");
69
- users = schema2.table(
202
+ init_schema();
203
+ users = authSchema.table(
70
204
  "users",
71
205
  {
72
206
  // Identity
73
- id: id2(),
207
+ id: id3(),
74
208
  // Email address (unique identifier)
75
209
  // Used for: login, password reset, notifications
76
- email: text2("email").unique(),
210
+ email: text3("email").unique(),
77
211
  // Phone number in E.164 international format
78
212
  // Format: +[country code][number] (e.g., +821012345678)
79
213
  // Used for: SMS login, 2FA, notifications
80
- phone: text2("phone").unique(),
214
+ phone: text3("phone").unique(),
81
215
  // Authentication
82
216
  // Bcrypt password hash ($2b$10$[salt][hash], 60 chars)
83
217
  // Nullable to support OAuth-only accounts
84
- passwordHash: text2("password_hash"),
218
+ passwordHash: text3("password_hash"),
85
219
  // Force password change on next login
86
220
  // Use cases: initial setup, security breach, policy violation
87
221
  passwordChangeRequired: boolean2("password_change_required").notNull().default(false),
@@ -94,7 +228,7 @@ var init_users = __esm({
94
228
  // - active: Normal operation (default)
95
229
  // - inactive: Deactivated (user request, dormant)
96
230
  // - suspended: Locked (security incident, ToS violation)
97
- status: text2(
231
+ status: text3(
98
232
  "status",
99
233
  {
100
234
  enum: ["active", "inactive", "suspended"]
@@ -103,14 +237,14 @@ var init_users = __esm({
103
237
  // Verification timestamps
104
238
  // null = unverified, timestamp = verified at this time
105
239
  // Email verification (via verification code or magic link)
106
- emailVerifiedAt: timestamp("email_verified_at", { withTimezone: true }),
240
+ emailVerifiedAt: timestamp2("email_verified_at", { withTimezone: true }),
107
241
  // Phone verification (via SMS OTP)
108
- phoneVerifiedAt: timestamp("phone_verified_at", { withTimezone: true }),
242
+ phoneVerifiedAt: timestamp2("phone_verified_at", { withTimezone: true }),
109
243
  // Metadata
110
244
  // Last successful login timestamp
111
245
  // Used for: security auditing, dormant account detection
112
- lastLoginAt: timestamp("last_login_at", { withTimezone: true }),
113
- ...timestamps2()
246
+ lastLoginAt: timestamp2("last_login_at", { withTimezone: true }),
247
+ ...timestamps3()
114
248
  },
115
249
  (table) => [
116
250
  // Database constraints
@@ -120,44 +254,44 @@ var init_users = __esm({
120
254
  sql`${table.email} IS NOT NULL OR ${table.phone} IS NOT NULL`
121
255
  ),
122
256
  // Indexes for query optimization
123
- index2("users_email_idx").on(table.email),
124
- index2("users_phone_idx").on(table.phone),
125
- index2("users_status_idx").on(table.status),
126
- index2("users_role_id_idx").on(table.roleId)
257
+ index3("users_email_idx").on(table.email),
258
+ index3("users_phone_idx").on(table.phone),
259
+ index3("users_status_idx").on(table.status),
260
+ index3("users_role_id_idx").on(table.roleId)
127
261
  ]
128
262
  );
129
263
  }
130
264
  });
131
265
 
132
266
  // src/server/entities/user-social-accounts.ts
133
- 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;
267
+ import { text as text4, timestamp as timestamp3, uniqueIndex } from "drizzle-orm/pg-core";
268
+ import { id as id4, timestamps as timestamps4, foreignKey } from "@spfn/core/db";
269
+ var userSocialAccounts;
136
270
  var init_user_social_accounts = __esm({
137
271
  "src/server/entities/user-social-accounts.ts"() {
138
272
  "use strict";
139
273
  init_users();
140
- schema3 = createFunctionSchema3("@spfn/auth");
141
- userSocialAccounts = schema3.table(
274
+ init_schema();
275
+ userSocialAccounts = authSchema.table(
142
276
  "user_social_accounts",
143
277
  {
144
- id: id3(),
278
+ id: id4(),
145
279
  // Foreign key to users
146
280
  userId: foreignKey("user", () => users.id),
147
281
  // Provider info
148
- provider: text3(
282
+ provider: text4(
149
283
  "provider",
150
284
  {
151
285
  enum: ["google", "github", "kakao", "naver"]
152
286
  }
153
287
  ).notNull(),
154
- providerUserId: text3("provider_user_id").notNull(),
155
- providerEmail: text3("provider_email"),
288
+ providerUserId: text4("provider_user_id").notNull(),
289
+ providerEmail: text4("provider_email"),
156
290
  // OAuth tokens (encrypted in production)
157
- accessToken: text3("access_token"),
158
- refreshToken: text3("refresh_token"),
159
- tokenExpiresAt: timestamp2("token_expires_at", { withTimezone: true }),
160
- ...timestamps3()
291
+ accessToken: text4("access_token"),
292
+ refreshToken: text4("refresh_token"),
293
+ tokenExpiresAt: timestamp3("token_expires_at", { withTimezone: true }),
294
+ ...timestamps4()
161
295
  },
162
296
  (table) => [
163
297
  // Unique constraint: one provider account per provider
@@ -168,92 +302,45 @@ var init_user_social_accounts = __esm({
168
302
  });
169
303
 
170
304
  // src/server/entities/user-public-keys.ts
171
- 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;
305
+ import { text as text5, timestamp as timestamp4, boolean as boolean3, index as index4 } from "drizzle-orm/pg-core";
306
+ import { id as id5, foreignKey as foreignKey2 } from "@spfn/core/db";
307
+ var userPublicKeys;
174
308
  var init_user_public_keys = __esm({
175
309
  "src/server/entities/user-public-keys.ts"() {
176
310
  "use strict";
177
311
  init_users();
178
- schema4 = createFunctionSchema4("@spfn/auth");
179
- userPublicKeys = schema4.table(
312
+ init_schema();
313
+ userPublicKeys = authSchema.table(
180
314
  "user_public_keys",
181
315
  {
182
- id: id4(),
316
+ id: id5(),
183
317
  // User reference
184
318
  userId: foreignKey2("user", () => users.id),
185
319
  // Key identification (client-generated UUID)
186
- keyId: text4("key_id").notNull().unique(),
320
+ keyId: text5("key_id").notNull().unique(),
187
321
  // Public key in Base64-encoded DER format (SPKI)
188
- publicKey: text4("public_key").notNull(),
322
+ publicKey: text5("public_key").notNull(),
189
323
  // Algorithm used (ES256 recommended, RS256 fallback)
190
- algorithm: text4("algorithm", {
324
+ algorithm: text5("algorithm", {
191
325
  enum: ["ES256", "RS256"]
192
326
  }).notNull().default("ES256"),
193
327
  // Key fingerprint (SHA-256 hash for quick identification)
194
- fingerprint: text4("fingerprint").notNull(),
328
+ fingerprint: text5("fingerprint").notNull(),
195
329
  // Key status
196
330
  isActive: boolean3("is_active").notNull().default(true),
197
331
  // Timestamps
198
- createdAt: timestamp3("created_at", { mode: "date", withTimezone: true }).notNull().defaultNow(),
199
- lastUsedAt: timestamp3("last_used_at", { mode: "date", withTimezone: true }),
200
- expiresAt: timestamp3("expires_at", { mode: "date", withTimezone: true }),
332
+ createdAt: timestamp4("created_at", { mode: "date", withTimezone: true }).notNull().defaultNow(),
333
+ lastUsedAt: timestamp4("last_used_at", { mode: "date", withTimezone: true }),
334
+ expiresAt: timestamp4("expires_at", { mode: "date", withTimezone: true }),
201
335
  // Revocation
202
- revokedAt: timestamp3("revoked_at", { mode: "date", withTimezone: true }),
203
- revokedReason: text4("revoked_reason")
204
- },
205
- (table) => [
206
- index3("user_public_keys_user_id_idx").on(table.userId),
207
- index3("user_public_keys_key_id_idx").on(table.keyId),
208
- index3("user_public_keys_active_idx").on(table.isActive),
209
- index3("user_public_keys_fingerprint_idx").on(table.fingerprint)
210
- ]
211
- );
212
- }
213
- });
214
-
215
- // src/server/entities/verification-codes.ts
216
- 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;
219
- var init_verification_codes = __esm({
220
- "src/server/entities/verification-codes.ts"() {
221
- "use strict";
222
- schema5 = createFunctionSchema5("@spfn/auth");
223
- verificationCodes = schema5.table(
224
- "verification_codes",
225
- {
226
- id: id5(),
227
- // Target (email or phone)
228
- target: text5("target").notNull(),
229
- // Email address or E.164 phone number
230
- targetType: text5(
231
- "target_type",
232
- {
233
- enum: ["email", "phone"]
234
- }
235
- ).notNull(),
236
- // Code
237
- code: text5("code").notNull(),
238
- // 6-digit code by default (configurable)
239
- // Purpose
240
- purpose: text5(
241
- "purpose",
242
- {
243
- enum: ["registration", "login", "password_reset", "email_change", "phone_change"]
244
- }
245
- ).notNull(),
246
- // Expiry
247
- expiresAt: timestamp4("expires_at", { withTimezone: true }).notNull(),
248
- // Usage tracking
249
- usedAt: timestamp4("used_at", { withTimezone: true }),
250
- attempts: text5("attempts").notNull().default("0"),
251
- // Track failed verification attempts
252
- ...timestamps4()
336
+ revokedAt: timestamp4("revoked_at", { mode: "date", withTimezone: true }),
337
+ revokedReason: text5("revoked_reason")
253
338
  },
254
339
  (table) => [
255
- // Index for quick lookup by target and purpose
256
- index4("target_purpose_idx").on(table.target, table.purpose, table.expiresAt)
340
+ index4("user_public_keys_user_id_idx").on(table.userId),
341
+ index4("user_public_keys_key_id_idx").on(table.keyId),
342
+ index4("user_public_keys_active_idx").on(table.isActive),
343
+ index4("user_public_keys_fingerprint_idx").on(table.fingerprint)
257
344
  ]
258
345
  );
259
346
  }
@@ -261,15 +348,15 @@ var init_verification_codes = __esm({
261
348
 
262
349
  // src/server/entities/invitations.ts
263
350
  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;
351
+ import { id as id6, timestamps as timestamps5 } from "@spfn/core/db";
352
+ var invitations;
266
353
  var init_invitations = __esm({
267
354
  "src/server/entities/invitations.ts"() {
268
355
  "use strict";
269
356
  init_roles();
270
357
  init_users();
271
- schema6 = createFunctionSchema6("@spfn/auth");
272
- invitations = schema6.table(
358
+ init_schema();
359
+ invitations = authSchema.table(
273
360
  "user_invitations",
274
361
  {
275
362
  // Primary key
@@ -337,13 +424,13 @@ var init_invitations = __esm({
337
424
 
338
425
  // src/server/entities/permissions.ts
339
426
  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;
427
+ import { id as id7, timestamps as timestamps6 } from "@spfn/core/db";
428
+ var permissions;
342
429
  var init_permissions = __esm({
343
430
  "src/server/entities/permissions.ts"() {
344
431
  "use strict";
345
- schema7 = createFunctionSchema7("@spfn/auth");
346
- permissions = schema7.table(
432
+ init_schema();
433
+ permissions = authSchema.table(
347
434
  "permissions",
348
435
  {
349
436
  // Primary key
@@ -384,15 +471,15 @@ var init_permissions = __esm({
384
471
 
385
472
  // src/server/entities/role-permissions.ts
386
473
  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;
474
+ import { id as id8, timestamps as timestamps7 } from "@spfn/core/db";
475
+ var rolePermissions;
389
476
  var init_role_permissions = __esm({
390
477
  "src/server/entities/role-permissions.ts"() {
391
478
  "use strict";
392
479
  init_roles();
393
480
  init_permissions();
394
- schema8 = createFunctionSchema8("@spfn/auth");
395
- rolePermissions = schema8.table(
481
+ init_schema();
482
+ rolePermissions = authSchema.table(
396
483
  "role_permissions",
397
484
  {
398
485
  // Primary key
@@ -416,15 +503,15 @@ var init_role_permissions = __esm({
416
503
 
417
504
  // src/server/entities/user-permissions.ts
418
505
  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;
506
+ import { id as id9, timestamps as timestamps8 } from "@spfn/core/db";
507
+ var userPermissions;
421
508
  var init_user_permissions = __esm({
422
509
  "src/server/entities/user-permissions.ts"() {
423
510
  "use strict";
424
511
  init_users();
425
512
  init_permissions();
426
- schema9 = createFunctionSchema9("@spfn/auth");
427
- userPermissions = schema9.table(
513
+ init_schema();
514
+ userPermissions = authSchema.table(
428
515
  "user_permissions",
429
516
  {
430
517
  // Primary key
@@ -460,6 +547,7 @@ var init_user_permissions = __esm({
460
547
  // src/server/entities/index.ts
461
548
  var entities_exports = {};
462
549
  __export(entities_exports, {
550
+ authSchema: () => authSchema,
463
551
  invitations: () => invitations,
464
552
  permissions: () => permissions,
465
553
  rolePermissions: () => rolePermissions,
@@ -473,6 +561,7 @@ __export(entities_exports, {
473
561
  var init_entities = __esm({
474
562
  "src/server/entities/index.ts"() {
475
563
  "use strict";
564
+ init_schema();
476
565
  init_users();
477
566
  init_user_social_accounts();
478
567
  init_user_public_keys();
@@ -498,14 +587,14 @@ __export(role_service_exports, {
498
587
  setRolePermissions: () => setRolePermissions,
499
588
  updateRole: () => updateRole
500
589
  });
501
- import { getDatabase as getDatabase5 } from "@spfn/core/db";
502
- import { eq as eq5, and as and5 } from "drizzle-orm";
590
+ import { getDatabase as getDatabase3 } from "@spfn/core/db";
591
+ import { eq as eq3, and as and3 } from "drizzle-orm";
503
592
  async function createRole(data) {
504
- const db = getDatabase5();
593
+ const db = getDatabase3();
505
594
  if (!db) {
506
595
  throw new Error("[Auth] Database not initialized");
507
596
  }
508
- const existing = await db.select().from(roles).where(eq5(roles.name, data.name)).limit(1);
597
+ const existing = await db.select().from(roles).where(eq3(roles.name, data.name)).limit(1);
509
598
  if (existing.length > 0) {
510
599
  throw new Error(`Role with name '${data.name}' already exists`);
511
600
  }
@@ -529,28 +618,28 @@ async function createRole(data) {
529
618
  return newRole;
530
619
  }
531
620
  async function updateRole(roleId, data) {
532
- const db = getDatabase5();
621
+ const db = getDatabase3();
533
622
  if (!db) {
534
623
  throw new Error("[Auth] Database not initialized");
535
624
  }
536
625
  const roleIdNum = Number(roleId);
537
- const [role] = await db.select().from(roles).where(eq5(roles.id, roleIdNum)).limit(1);
626
+ const [role] = await db.select().from(roles).where(eq3(roles.id, roleIdNum)).limit(1);
538
627
  if (!role) {
539
628
  throw new Error("Role not found");
540
629
  }
541
630
  if (role.isBuiltin && data.priority !== void 0) {
542
631
  throw new Error("Cannot modify priority of built-in roles");
543
632
  }
544
- const [updated] = await db.update(roles).set(data).where(eq5(roles.id, roleIdNum)).returning();
633
+ const [updated] = await db.update(roles).set(data).where(eq3(roles.id, roleIdNum)).returning();
545
634
  return updated;
546
635
  }
547
636
  async function deleteRole(roleId) {
548
- const db = getDatabase5();
637
+ const db = getDatabase3();
549
638
  if (!db) {
550
639
  throw new Error("[Auth] Database not initialized");
551
640
  }
552
641
  const roleIdNum = Number(roleId);
553
- const [role] = await db.select().from(roles).where(eq5(roles.id, roleIdNum)).limit(1);
642
+ const [role] = await db.select().from(roles).where(eq3(roles.id, roleIdNum)).limit(1);
554
643
  if (!role) {
555
644
  throw new Error("Role not found");
556
645
  }
@@ -560,20 +649,20 @@ async function deleteRole(roleId) {
560
649
  if (role.isSystem) {
561
650
  throw new Error(`Cannot delete system role: ${role.name}. Deactivate it instead.`);
562
651
  }
563
- await db.delete(roles).where(eq5(roles.id, roleIdNum));
652
+ await db.delete(roles).where(eq3(roles.id, roleIdNum));
564
653
  console.log(`[Auth] \u{1F5D1}\uFE0F Deleted role: ${role.name}`);
565
654
  }
566
655
  async function addPermissionToRole(roleId, permissionId) {
567
- const db = getDatabase5();
656
+ const db = getDatabase3();
568
657
  if (!db) {
569
658
  throw new Error("[Auth] Database not initialized");
570
659
  }
571
660
  const roleIdNum = Number(roleId);
572
661
  const permissionIdNum = Number(permissionId);
573
662
  const existing = await db.select().from(rolePermissions).where(
574
- and5(
575
- eq5(rolePermissions.roleId, roleIdNum),
576
- eq5(rolePermissions.permissionId, permissionIdNum)
663
+ and3(
664
+ eq3(rolePermissions.roleId, roleIdNum),
665
+ eq3(rolePermissions.permissionId, permissionIdNum)
577
666
  )
578
667
  ).limit(1);
579
668
  if (existing.length > 0) {
@@ -585,26 +674,26 @@ async function addPermissionToRole(roleId, permissionId) {
585
674
  });
586
675
  }
587
676
  async function removePermissionFromRole(roleId, permissionId) {
588
- const db = getDatabase5();
677
+ const db = getDatabase3();
589
678
  if (!db) {
590
679
  throw new Error("[Auth] Database not initialized");
591
680
  }
592
681
  const roleIdNum = Number(roleId);
593
682
  const permissionIdNum = Number(permissionId);
594
683
  await db.delete(rolePermissions).where(
595
- and5(
596
- eq5(rolePermissions.roleId, roleIdNum),
597
- eq5(rolePermissions.permissionId, permissionIdNum)
684
+ and3(
685
+ eq3(rolePermissions.roleId, roleIdNum),
686
+ eq3(rolePermissions.permissionId, permissionIdNum)
598
687
  )
599
688
  );
600
689
  }
601
690
  async function setRolePermissions(roleId, permissionIds) {
602
- const db = getDatabase5();
691
+ const db = getDatabase3();
603
692
  if (!db) {
604
693
  throw new Error("[Auth] Database not initialized");
605
694
  }
606
695
  const roleIdNum = Number(roleId);
607
- await db.delete(rolePermissions).where(eq5(rolePermissions.roleId, roleIdNum));
696
+ await db.delete(rolePermissions).where(eq3(rolePermissions.roleId, roleIdNum));
608
697
  if (permissionIds.length > 0) {
609
698
  const mappings = permissionIds.map((permId) => ({
610
699
  roleId: roleIdNum,
@@ -614,31 +703,31 @@ async function setRolePermissions(roleId, permissionIds) {
614
703
  }
615
704
  }
616
705
  async function getAllRoles(includeInactive = false) {
617
- const db = getDatabase5();
706
+ const db = getDatabase3();
618
707
  if (!db) {
619
708
  throw new Error("[Auth] Database not initialized");
620
709
  }
621
710
  const query = db.select().from(roles);
622
711
  if (!includeInactive) {
623
- return query.where(eq5(roles.isActive, true));
712
+ return query.where(eq3(roles.isActive, true));
624
713
  }
625
714
  return query;
626
715
  }
627
716
  async function getRoleByName(name) {
628
- const db = getDatabase5();
717
+ const db = getDatabase3();
629
718
  if (!db) {
630
719
  throw new Error("[Auth] Database not initialized");
631
720
  }
632
- const [role] = await db.select().from(roles).where(eq5(roles.name, name)).limit(1);
721
+ const [role] = await db.select().from(roles).where(eq3(roles.name, name)).limit(1);
633
722
  return role || null;
634
723
  }
635
724
  async function getRolePermissions(roleId) {
636
- const db = getDatabase5();
725
+ const db = getDatabase3();
637
726
  if (!db) {
638
727
  throw new Error("[Auth] Database not initialized");
639
728
  }
640
729
  const roleIdNum = Number(roleId);
641
- const perms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq5(rolePermissions.permissionId, permissions.id)).where(eq5(rolePermissions.roleId, roleIdNum));
730
+ const perms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq3(rolePermissions.permissionId, permissions.id)).where(eq3(rolePermissions.roleId, roleIdNum));
642
731
  return perms.map((p) => p.name);
643
732
  }
644
733
  var init_role_service = __esm({
@@ -2243,8 +2332,8 @@ function Clone(value) {
2243
2332
  }
2244
2333
 
2245
2334
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs
2246
- function CloneType(schema10, options) {
2247
- return options === void 0 ? Clone(schema10) : Clone({ ...options, ...schema10 });
2335
+ function CloneType(schema, options) {
2336
+ return options === void 0 ? Clone(schema) : Clone({ ...options, ...schema });
2248
2337
  }
2249
2338
 
2250
2339
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/value/guard/guard.mjs
@@ -2321,8 +2410,8 @@ function Immutable(value) {
2321
2410
  }
2322
2411
 
2323
2412
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/create/type.mjs
2324
- function CreateType(schema10, options) {
2325
- const result = options !== void 0 ? { ...options, ...schema10 } : schema10;
2413
+ function CreateType(schema, options) {
2414
+ const result = options !== void 0 ? { ...options, ...schema } : schema;
2326
2415
  switch (TypeSystemPolicy.InstanceMode) {
2327
2416
  case "freeze":
2328
2417
  return Immutable(result);
@@ -2640,16 +2729,16 @@ function IsBoolean3(value) {
2640
2729
  return IsKindOf2(value, "Boolean") && value.type === "boolean" && IsOptionalString(value.$id);
2641
2730
  }
2642
2731
  function IsComputed2(value) {
2643
- return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10));
2732
+ return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema));
2644
2733
  }
2645
2734
  function IsConstructor2(value) {
2646
- return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10)) && IsSchema2(value.returns);
2735
+ return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
2647
2736
  }
2648
2737
  function IsDate3(value) {
2649
2738
  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);
2650
2739
  }
2651
2740
  function IsFunction3(value) {
2652
- return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10)) && IsSchema2(value.returns);
2741
+ return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
2653
2742
  }
2654
2743
  function IsImport(value) {
2655
2744
  return IsKindOf2(value, "Import") && HasPropertyKey(value, "$defs") && IsObject(value.$defs) && IsProperties(value.$defs) && HasPropertyKey(value, "$ref") && IsString(value.$ref) && value.$ref in value.$defs;
@@ -2658,10 +2747,10 @@ function IsInteger2(value) {
2658
2747
  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);
2659
2748
  }
2660
2749
  function IsProperties(value) {
2661
- return IsObject(value) && Object.entries(value).every(([key, schema10]) => IsControlCharacterFree(key) && IsSchema2(schema10));
2750
+ return IsObject(value) && Object.entries(value).every(([key, schema]) => IsControlCharacterFree(key) && IsSchema2(schema));
2662
2751
  }
2663
2752
  function IsIntersect2(value) {
2664
- 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);
2753
+ 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);
2665
2754
  }
2666
2755
  function IsIterator3(value) {
2667
2756
  return IsKindOf2(value, "Iterator") && value.type === "Iterator" && IsOptionalString(value.$id) && IsSchema2(value.items);
@@ -2709,9 +2798,9 @@ function IsPromise2(value) {
2709
2798
  return IsKindOf2(value, "Promise") && value.type === "Promise" && IsOptionalString(value.$id) && IsSchema2(value.item);
2710
2799
  }
2711
2800
  function IsRecord2(value) {
2712
- return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((schema10) => {
2713
- const keys = Object.getOwnPropertyNames(schema10.patternProperties);
2714
- return keys.length === 1 && IsPattern(keys[0]) && IsObject(schema10.patternProperties) && IsSchema2(schema10.patternProperties[keys[0]]);
2801
+ return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((schema) => {
2802
+ const keys = Object.getOwnPropertyNames(schema.patternProperties);
2803
+ return keys.length === 1 && IsPattern(keys[0]) && IsObject(schema.patternProperties) && IsSchema2(schema.patternProperties[keys[0]]);
2715
2804
  })(value);
2716
2805
  }
2717
2806
  function IsRecursive(value) {
@@ -2740,16 +2829,16 @@ function IsTransform2(value) {
2740
2829
  }
2741
2830
  function IsTuple2(value) {
2742
2831
  return IsKindOf2(value, "Tuple") && value.type === "array" && IsOptionalString(value.$id) && IsNumber(value.minItems) && IsNumber(value.maxItems) && value.minItems === value.maxItems && // empty
2743
- (IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((schema10) => IsSchema2(schema10)));
2832
+ (IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((schema) => IsSchema2(schema)));
2744
2833
  }
2745
2834
  function IsUndefined4(value) {
2746
2835
  return IsKindOf2(value, "Undefined") && value.type === "undefined" && IsOptionalString(value.$id);
2747
2836
  }
2748
2837
  function IsUnionLiteral(value) {
2749
- return IsUnion2(value) && value.anyOf.every((schema10) => IsLiteralString(schema10) || IsLiteralNumber(schema10));
2838
+ return IsUnion2(value) && value.anyOf.every((schema) => IsLiteralString(schema) || IsLiteralNumber(schema));
2750
2839
  }
2751
2840
  function IsUnion2(value) {
2752
- return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((schema10) => IsSchema2(schema10));
2841
+ return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((schema) => IsSchema2(schema));
2753
2842
  }
2754
2843
  function IsUint8Array3(value) {
2755
2844
  return IsKindOf2(value, "Uint8Array") && value.type === "Uint8Array" && IsOptionalString(value.$id) && IsOptionalNumber(value.minByteLength) && IsOptionalNumber(value.maxByteLength);
@@ -3031,8 +3120,8 @@ function IsTemplateLiteralExpressionFinite(expression) {
3031
3120
  throw new TemplateLiteralFiniteError(`Unknown expression type`);
3032
3121
  })();
3033
3122
  }
3034
- function IsTemplateLiteralFinite(schema10) {
3035
- const expression = TemplateLiteralParseExact(schema10.pattern);
3123
+ function IsTemplateLiteralFinite(schema) {
3124
+ const expression = TemplateLiteralParseExact(schema.pattern);
3036
3125
  return IsTemplateLiteralExpressionFinite(expression);
3037
3126
  }
3038
3127
 
@@ -3063,8 +3152,8 @@ function* TemplateLiteralExpressionGenerate(expression) {
3063
3152
  throw new TemplateLiteralGenerateError("Unknown expression");
3064
3153
  })();
3065
3154
  }
3066
- function TemplateLiteralGenerate(schema10) {
3067
- const expression = TemplateLiteralParseExact(schema10.pattern);
3155
+ function TemplateLiteralGenerate(schema) {
3156
+ const expression = TemplateLiteralParseExact(schema.pattern);
3068
3157
  return IsTemplateLiteralExpressionFinite(expression) ? [...TemplateLiteralExpressionGenerate(expression)] : [];
3069
3158
  }
3070
3159
 
@@ -3140,18 +3229,18 @@ var TemplateLiteralPatternError = class extends TypeBoxError {
3140
3229
  function Escape(value) {
3141
3230
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3142
3231
  }
3143
- function Visit2(schema10, acc) {
3144
- 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}` : (() => {
3145
- throw new TemplateLiteralPatternError(`Unexpected Kind '${schema10[Kind]}'`);
3232
+ function Visit2(schema, acc) {
3233
+ 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}` : (() => {
3234
+ throw new TemplateLiteralPatternError(`Unexpected Kind '${schema[Kind]}'`);
3146
3235
  })();
3147
3236
  }
3148
3237
  function TemplateLiteralPattern(kinds) {
3149
- return `^${kinds.map((schema10) => Visit2(schema10, "")).join("")}$`;
3238
+ return `^${kinds.map((schema) => Visit2(schema, "")).join("")}$`;
3150
3239
  }
3151
3240
 
3152
3241
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/template-literal/union.mjs
3153
- function TemplateLiteralToUnion(schema10) {
3154
- const R = TemplateLiteralGenerate(schema10);
3242
+ function TemplateLiteralToUnion(schema) {
3243
+ const R = TemplateLiteralGenerate(schema);
3155
3244
  const L = R.map((S) => Literal(S));
3156
3245
  return UnionEvaluated(L);
3157
3246
  }
@@ -3288,18 +3377,18 @@ function Promise2(item, options) {
3288
3377
  }
3289
3378
 
3290
3379
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly.mjs
3291
- function RemoveReadonly(schema10) {
3292
- return CreateType(Discard(schema10, [ReadonlyKind]));
3380
+ function RemoveReadonly(schema) {
3381
+ return CreateType(Discard(schema, [ReadonlyKind]));
3293
3382
  }
3294
- function AddReadonly(schema10) {
3295
- return CreateType({ ...schema10, [ReadonlyKind]: "Readonly" });
3383
+ function AddReadonly(schema) {
3384
+ return CreateType({ ...schema, [ReadonlyKind]: "Readonly" });
3296
3385
  }
3297
- function ReadonlyWithFlag(schema10, F) {
3298
- return F === false ? RemoveReadonly(schema10) : AddReadonly(schema10);
3386
+ function ReadonlyWithFlag(schema, F) {
3387
+ return F === false ? RemoveReadonly(schema) : AddReadonly(schema);
3299
3388
  }
3300
- function Readonly(schema10, enable) {
3389
+ function Readonly(schema, enable) {
3301
3390
  const F = enable ?? true;
3302
- return IsMappedResult(schema10) ? ReadonlyFromMappedResult(schema10, F) : ReadonlyWithFlag(schema10, F);
3391
+ return IsMappedResult(schema) ? ReadonlyFromMappedResult(schema, F) : ReadonlyWithFlag(schema, F);
3303
3392
  }
3304
3393
 
3305
3394
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly-from-mapped-result.mjs
@@ -3378,18 +3467,18 @@ function Mapped(key, map, options) {
3378
3467
  }
3379
3468
 
3380
3469
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional.mjs
3381
- function RemoveOptional(schema10) {
3382
- return CreateType(Discard(schema10, [OptionalKind]));
3470
+ function RemoveOptional(schema) {
3471
+ return CreateType(Discard(schema, [OptionalKind]));
3383
3472
  }
3384
- function AddOptional(schema10) {
3385
- return CreateType({ ...schema10, [OptionalKind]: "Optional" });
3473
+ function AddOptional(schema) {
3474
+ return CreateType({ ...schema, [OptionalKind]: "Optional" });
3386
3475
  }
3387
- function OptionalWithFlag(schema10, F) {
3388
- return F === false ? RemoveOptional(schema10) : AddOptional(schema10);
3476
+ function OptionalWithFlag(schema, F) {
3477
+ return F === false ? RemoveOptional(schema) : AddOptional(schema);
3389
3478
  }
3390
- function Optional(schema10, enable) {
3479
+ function Optional(schema, enable) {
3391
3480
  const F = enable ?? true;
3392
- return IsMappedResult(schema10) ? OptionalFromMappedResult(schema10, F) : OptionalWithFlag(schema10, F);
3481
+ return IsMappedResult(schema) ? OptionalFromMappedResult(schema, F) : OptionalWithFlag(schema, F);
3393
3482
  }
3394
3483
 
3395
3484
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional-from-mapped-result.mjs
@@ -3409,7 +3498,7 @@ function OptionalFromMappedResult(R, F) {
3409
3498
 
3410
3499
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/intersect/intersect-create.mjs
3411
3500
  function IntersectCreate(T, options = {}) {
3412
- const allObjects = T.every((schema10) => IsObject3(schema10));
3501
+ const allObjects = T.every((schema) => IsObject3(schema));
3413
3502
  const clonedUnevaluatedProperties = IsSchema(options.unevaluatedProperties) ? { unevaluatedProperties: options.unevaluatedProperties } : {};
3414
3503
  return CreateType(options.unevaluatedProperties === false || IsSchema(options.unevaluatedProperties) || allObjects ? { ...clonedUnevaluatedProperties, [Kind]: "Intersect", type: "object", allOf: T } : { ...clonedUnevaluatedProperties, [Kind]: "Intersect", allOf: T }, options);
3415
3504
  }
@@ -3432,7 +3521,7 @@ function IntersectEvaluated(types, options = {}) {
3432
3521
  return CreateType(types[0], options);
3433
3522
  if (types.length === 0)
3434
3523
  return Never(options);
3435
- if (types.some((schema10) => IsTransform(schema10)))
3524
+ if (types.some((schema) => IsTransform(schema)))
3436
3525
  throw new Error("Cannot intersect transform types");
3437
3526
  return ResolveIntersect(types, options);
3438
3527
  }
@@ -3443,7 +3532,7 @@ function Intersect(types, options) {
3443
3532
  return CreateType(types[0], options);
3444
3533
  if (types.length === 0)
3445
3534
  return Never(options);
3446
- if (types.some((schema10) => IsTransform(schema10)))
3535
+ if (types.some((schema) => IsTransform(schema)))
3447
3536
  throw new Error("Cannot intersect transform types");
3448
3537
  return IntersectCreate(types, options);
3449
3538
  }
@@ -3634,8 +3723,8 @@ function Const(T, options) {
3634
3723
  }
3635
3724
 
3636
3725
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/constructor-parameters/constructor-parameters.mjs
3637
- function ConstructorParameters(schema10, options) {
3638
- return IsConstructor(schema10) ? Tuple(schema10.parameters, options) : Never(options);
3726
+ function ConstructorParameters(schema, options) {
3727
+ return IsConstructor(schema) ? Tuple(schema.parameters, options) : Never(options);
3639
3728
  }
3640
3729
 
3641
3730
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/enum/enum.mjs
@@ -3673,7 +3762,7 @@ function FromAnyRight(left, right) {
3673
3762
  return ExtendsResult.True;
3674
3763
  }
3675
3764
  function FromAny(left, right) {
3676
- 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;
3765
+ 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;
3677
3766
  }
3678
3767
  function FromArrayRight(left, right) {
3679
3768
  return type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : type_exports.IsNever(left) ? ExtendsResult.True : ExtendsResult.False;
@@ -3694,13 +3783,13 @@ function FromBoolean(left, right) {
3694
3783
  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;
3695
3784
  }
3696
3785
  function FromConstructor(left, right) {
3697
- 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));
3786
+ 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));
3698
3787
  }
3699
3788
  function FromDate(left, right) {
3700
3789
  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;
3701
3790
  }
3702
3791
  function FromFunction(left, right) {
3703
- 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));
3792
+ 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));
3704
3793
  }
3705
3794
  function FromIntegerRight(left, right) {
3706
3795
  return type_exports.IsLiteral(left) && value_exports.IsNumber(left.const) ? ExtendsResult.True : type_exports.IsNumber(left) || type_exports.IsInteger(left) ? ExtendsResult.True : ExtendsResult.False;
@@ -3709,10 +3798,10 @@ function FromInteger(left, right) {
3709
3798
  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;
3710
3799
  }
3711
3800
  function FromIntersectRight(left, right) {
3712
- return right.allOf.every((schema10) => Visit3(left, schema10) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3801
+ return right.allOf.every((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3713
3802
  }
3714
3803
  function FromIntersect4(left, right) {
3715
- return left.allOf.some((schema10) => Visit3(schema10, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3804
+ return left.allOf.some((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3716
3805
  }
3717
3806
  function FromIterator(left, right) {
3718
3807
  return IsStructuralRight(right) ? StructuralRight(left, right) : !type_exports.IsIterator(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.items, right.items));
@@ -3726,8 +3815,8 @@ function FromNeverRight(left, right) {
3726
3815
  function FromNever(left, right) {
3727
3816
  return ExtendsResult.True;
3728
3817
  }
3729
- function UnwrapTNot(schema10) {
3730
- let [current, depth] = [schema10, 0];
3818
+ function UnwrapTNot(schema) {
3819
+ let [current, depth] = [schema, 0];
3731
3820
  while (true) {
3732
3821
  if (!type_exports.IsNot(current))
3733
3822
  break;
@@ -3748,44 +3837,44 @@ function FromNumberRight(left, right) {
3748
3837
  function FromNumber(left, right) {
3749
3838
  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;
3750
3839
  }
3751
- function IsObjectPropertyCount(schema10, count) {
3752
- return Object.getOwnPropertyNames(schema10.properties).length === count;
3840
+ function IsObjectPropertyCount(schema, count) {
3841
+ return Object.getOwnPropertyNames(schema.properties).length === count;
3753
3842
  }
3754
- function IsObjectStringLike(schema10) {
3755
- return IsObjectArrayLike(schema10);
3843
+ function IsObjectStringLike(schema) {
3844
+ return IsObjectArrayLike(schema);
3756
3845
  }
3757
- function IsObjectSymbolLike(schema10) {
3758
- 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]));
3846
+ function IsObjectSymbolLike(schema) {
3847
+ 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]));
3759
3848
  }
3760
- function IsObjectNumberLike(schema10) {
3761
- return IsObjectPropertyCount(schema10, 0);
3849
+ function IsObjectNumberLike(schema) {
3850
+ return IsObjectPropertyCount(schema, 0);
3762
3851
  }
3763
- function IsObjectBooleanLike(schema10) {
3764
- return IsObjectPropertyCount(schema10, 0);
3852
+ function IsObjectBooleanLike(schema) {
3853
+ return IsObjectPropertyCount(schema, 0);
3765
3854
  }
3766
- function IsObjectBigIntLike(schema10) {
3767
- return IsObjectPropertyCount(schema10, 0);
3855
+ function IsObjectBigIntLike(schema) {
3856
+ return IsObjectPropertyCount(schema, 0);
3768
3857
  }
3769
- function IsObjectDateLike(schema10) {
3770
- return IsObjectPropertyCount(schema10, 0);
3858
+ function IsObjectDateLike(schema) {
3859
+ return IsObjectPropertyCount(schema, 0);
3771
3860
  }
3772
- function IsObjectUint8ArrayLike(schema10) {
3773
- return IsObjectArrayLike(schema10);
3861
+ function IsObjectUint8ArrayLike(schema) {
3862
+ return IsObjectArrayLike(schema);
3774
3863
  }
3775
- function IsObjectFunctionLike(schema10) {
3864
+ function IsObjectFunctionLike(schema) {
3776
3865
  const length = Number2();
3777
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "length" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["length"], length)) === ExtendsResult.True;
3866
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
3778
3867
  }
3779
- function IsObjectConstructorLike(schema10) {
3780
- return IsObjectPropertyCount(schema10, 0);
3868
+ function IsObjectConstructorLike(schema) {
3869
+ return IsObjectPropertyCount(schema, 0);
3781
3870
  }
3782
- function IsObjectArrayLike(schema10) {
3871
+ function IsObjectArrayLike(schema) {
3783
3872
  const length = Number2();
3784
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "length" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["length"], length)) === ExtendsResult.True;
3873
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
3785
3874
  }
3786
- function IsObjectPromiseLike(schema10) {
3875
+ function IsObjectPromiseLike(schema) {
3787
3876
  const then = Function([Any()], Any());
3788
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "then" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["then"], then)) === ExtendsResult.True;
3877
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "then" in schema.properties && IntoBooleanResult(Visit3(schema.properties["then"], then)) === ExtendsResult.True;
3789
3878
  }
3790
3879
  function Property(left, right) {
3791
3880
  return Visit3(left, right) === ExtendsResult.False ? ExtendsResult.False : type_exports.IsOptional(left) && !type_exports.IsOptional(right) ? ExtendsResult.False : ExtendsResult.True;
@@ -3816,11 +3905,11 @@ function FromObject(left, right) {
3816
3905
  function FromPromise2(left, right) {
3817
3906
  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));
3818
3907
  }
3819
- function RecordKey(schema10) {
3820
- return PatternNumberExact in schema10.patternProperties ? Number2() : PatternStringExact in schema10.patternProperties ? String2() : Throw("Unknown record key pattern");
3908
+ function RecordKey(schema) {
3909
+ return PatternNumberExact in schema.patternProperties ? Number2() : PatternStringExact in schema.patternProperties ? String2() : Throw("Unknown record key pattern");
3821
3910
  }
3822
- function RecordValue(schema10) {
3823
- return PatternNumberExact in schema10.patternProperties ? schema10.patternProperties[PatternNumberExact] : PatternStringExact in schema10.patternProperties ? schema10.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
3911
+ function RecordValue(schema) {
3912
+ return PatternNumberExact in schema.patternProperties ? schema.patternProperties[PatternNumberExact] : PatternStringExact in schema.patternProperties ? schema.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
3824
3913
  }
3825
3914
  function FromRecordRight(left, right) {
3826
3915
  const [Key, Value] = [RecordKey(right), RecordValue(right)];
@@ -3854,13 +3943,13 @@ function FromTemplateLiteral2(left, right) {
3854
3943
  return type_exports.IsTemplateLiteral(left) ? Visit3(TemplateLiteralToUnion(left), right) : type_exports.IsTemplateLiteral(right) ? Visit3(left, TemplateLiteralToUnion(right)) : Throw("Invalid fallthrough for TemplateLiteral");
3855
3944
  }
3856
3945
  function IsArrayOfTuple(left, right) {
3857
- return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((schema10) => Visit3(schema10, right.items) === ExtendsResult.True);
3946
+ return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((schema) => Visit3(schema, right.items) === ExtendsResult.True);
3858
3947
  }
3859
3948
  function FromTupleRight(left, right) {
3860
3949
  return type_exports.IsNever(left) ? ExtendsResult.True : type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : ExtendsResult.False;
3861
3950
  }
3862
3951
  function FromTuple3(left, right) {
3863
- 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;
3952
+ 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;
3864
3953
  }
3865
3954
  function FromUint8Array(left, right) {
3866
3955
  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;
@@ -3869,10 +3958,10 @@ function FromUndefined(left, right) {
3869
3958
  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;
3870
3959
  }
3871
3960
  function FromUnionRight(left, right) {
3872
- return right.anyOf.some((schema10) => Visit3(left, schema10) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3961
+ return right.anyOf.some((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3873
3962
  }
3874
3963
  function FromUnion6(left, right) {
3875
- return left.anyOf.every((schema10) => Visit3(schema10, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3964
+ return left.anyOf.every((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
3876
3965
  }
3877
3966
  function FromUnknownRight(left, right) {
3878
3967
  return ExtendsResult.True;
@@ -4009,13 +4098,13 @@ function ExtractFromMappedResult(R, T) {
4009
4098
  }
4010
4099
 
4011
4100
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/instance-type/instance-type.mjs
4012
- function InstanceType(schema10, options) {
4013
- return IsConstructor(schema10) ? CreateType(schema10.returns, options) : Never(options);
4101
+ function InstanceType(schema, options) {
4102
+ return IsConstructor(schema) ? CreateType(schema.returns, options) : Never(options);
4014
4103
  }
4015
4104
 
4016
4105
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly-optional/readonly-optional.mjs
4017
- function ReadonlyOptional(schema10) {
4018
- return Readonly(Optional(schema10));
4106
+ function ReadonlyOptional(schema) {
4107
+ return Readonly(Optional(schema));
4019
4108
  }
4020
4109
 
4021
4110
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/record/record.mjs
@@ -4188,11 +4277,11 @@ function ApplyUppercase(value) {
4188
4277
  function ApplyLowercase(value) {
4189
4278
  return value.toLowerCase();
4190
4279
  }
4191
- function FromTemplateLiteral3(schema10, mode, options) {
4192
- const expression = TemplateLiteralParseExact(schema10.pattern);
4280
+ function FromTemplateLiteral3(schema, mode, options) {
4281
+ const expression = TemplateLiteralParseExact(schema.pattern);
4193
4282
  const finite = IsTemplateLiteralExpressionFinite(expression);
4194
4283
  if (!finite)
4195
- return { ...schema10, pattern: FromLiteralValue(schema10.pattern, mode) };
4284
+ return { ...schema, pattern: FromLiteralValue(schema.pattern, mode) };
4196
4285
  const strings = [...TemplateLiteralExpressionGenerate(expression)];
4197
4286
  const literals = strings.map((value) => Literal(value));
4198
4287
  const mapped = FromRest5(literals, mode);
@@ -4205,14 +4294,14 @@ function FromLiteralValue(value, mode) {
4205
4294
  function FromRest5(T, M) {
4206
4295
  return T.map((L) => Intrinsic(L, M));
4207
4296
  }
4208
- function Intrinsic(schema10, mode, options = {}) {
4297
+ function Intrinsic(schema, mode, options = {}) {
4209
4298
  return (
4210
4299
  // Intrinsic-Mapped-Inference
4211
- IsMappedKey(schema10) ? IntrinsicFromMappedKey(schema10, mode, options) : (
4300
+ IsMappedKey(schema) ? IntrinsicFromMappedKey(schema, mode, options) : (
4212
4301
  // Standard-Inference
4213
- IsTemplateLiteral(schema10) ? FromTemplateLiteral3(schema10, mode, options) : IsUnion(schema10) ? Union(FromRest5(schema10.anyOf, mode), options) : IsLiteral(schema10) ? Literal(FromLiteralValue(schema10.const, mode), options) : (
4302
+ IsTemplateLiteral(schema) ? FromTemplateLiteral3(schema, mode, options) : IsUnion(schema) ? Union(FromRest5(schema.anyOf, mode), options) : IsLiteral(schema) ? Literal(FromLiteralValue(schema.const, mode), options) : (
4214
4303
  // Default Type
4215
- CreateType(schema10, options)
4304
+ CreateType(schema, options)
4216
4305
  )
4217
4306
  )
4218
4307
  );
@@ -4609,8 +4698,8 @@ function Not(type, options) {
4609
4698
  }
4610
4699
 
4611
4700
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/parameters/parameters.mjs
4612
- function Parameters(schema10, options) {
4613
- return IsFunction2(schema10) ? Tuple(schema10.parameters, options) : Never();
4701
+ function Parameters(schema, options) {
4702
+ return IsFunction2(schema) ? Tuple(schema.parameters, options) : Never();
4614
4703
  }
4615
4704
 
4616
4705
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/recursive/recursive.mjs
@@ -4638,40 +4727,40 @@ function Rest(T) {
4638
4727
  }
4639
4728
 
4640
4729
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs
4641
- function ReturnType(schema10, options) {
4642
- return IsFunction2(schema10) ? CreateType(schema10.returns, options) : Never(options);
4730
+ function ReturnType(schema, options) {
4731
+ return IsFunction2(schema) ? CreateType(schema.returns, options) : Never(options);
4643
4732
  }
4644
4733
 
4645
4734
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/transform/transform.mjs
4646
4735
  var TransformDecodeBuilder = class {
4647
- constructor(schema10) {
4648
- this.schema = schema10;
4736
+ constructor(schema) {
4737
+ this.schema = schema;
4649
4738
  }
4650
4739
  Decode(decode) {
4651
4740
  return new TransformEncodeBuilder(this.schema, decode);
4652
4741
  }
4653
4742
  };
4654
4743
  var TransformEncodeBuilder = class {
4655
- constructor(schema10, decode) {
4656
- this.schema = schema10;
4744
+ constructor(schema, decode) {
4745
+ this.schema = schema;
4657
4746
  this.decode = decode;
4658
4747
  }
4659
- EncodeTransform(encode, schema10) {
4660
- const Encode = (value) => schema10[TransformKind].Encode(encode(value));
4661
- const Decode = (value) => this.decode(schema10[TransformKind].Decode(value));
4748
+ EncodeTransform(encode, schema) {
4749
+ const Encode = (value) => schema[TransformKind].Encode(encode(value));
4750
+ const Decode = (value) => this.decode(schema[TransformKind].Decode(value));
4662
4751
  const Codec = { Encode, Decode };
4663
- return { ...schema10, [TransformKind]: Codec };
4752
+ return { ...schema, [TransformKind]: Codec };
4664
4753
  }
4665
- EncodeSchema(encode, schema10) {
4754
+ EncodeSchema(encode, schema) {
4666
4755
  const Codec = { Decode: this.decode, Encode: encode };
4667
- return { ...schema10, [TransformKind]: Codec };
4756
+ return { ...schema, [TransformKind]: Codec };
4668
4757
  }
4669
4758
  Encode(encode) {
4670
4759
  return IsTransform(this.schema) ? this.EncodeTransform(encode, this.schema) : this.EncodeSchema(encode, this.schema);
4671
4760
  }
4672
4761
  };
4673
- function Transform(schema10) {
4674
- return new TransformDecodeBuilder(schema10);
4762
+ function Transform(schema) {
4763
+ return new TransformDecodeBuilder(schema);
4675
4764
  }
4676
4765
 
4677
4766
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/unsafe/unsafe.mjs
@@ -5049,6 +5138,33 @@ var changePasswordContract = {
5049
5138
  })
5050
5139
  )
5051
5140
  };
5141
+ var getMeContract = {
5142
+ method: "GET",
5143
+ path: "/_auth/me",
5144
+ body: Type.Object({}),
5145
+ response: ApiResponseSchema(
5146
+ Type.Object({
5147
+ userId: Type.String({ description: "User ID" }),
5148
+ email: Type.Optional(Type.String({ description: "User email address" })),
5149
+ phone: Type.Optional(Type.String({ description: "User phone number" })),
5150
+ role: Type.Object({
5151
+ id: Type.Number({ description: "Role ID" }),
5152
+ name: Type.String({ description: "Role name (e.g., user, admin)" }),
5153
+ displayName: Type.String({ description: "Display name for UI" }),
5154
+ priority: Type.Number({ description: "Role priority level" })
5155
+ }, { description: "User role information" }),
5156
+ permissions: Type.Array(
5157
+ Type.Object({
5158
+ id: Type.Number({ description: "Permission ID" }),
5159
+ name: Type.String({ description: "Permission name (e.g., user:delete)" }),
5160
+ displayName: Type.String({ description: "Display name for UI" }),
5161
+ category: Type.Optional(Type.String({ description: "Permission category" }))
5162
+ }),
5163
+ { description: "List of permissions granted through role" }
5164
+ )
5165
+ })
5166
+ )
5167
+ };
5052
5168
 
5053
5169
  // src/lib/contracts/invitation.ts
5054
5170
  var UUID_PATTERN2 = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
@@ -5282,252 +5398,45 @@ var deleteInvitationContract = {
5282
5398
  )
5283
5399
  };
5284
5400
 
5285
- // src/server/helpers/jwt.ts
5286
- import jwt from "jsonwebtoken";
5287
- import crypto from "crypto";
5288
- var JWT_SECRET = process.env.SPFN_AUTH_JWT_SECRET || // New prefixed version (recommended)
5289
- process.env.JWT_SECRET || // Legacy fallback
5290
- "dev-secret-key-change-in-production";
5291
- var JWT_EXPIRES_IN = process.env.SPFN_AUTH_JWT_EXPIRES_IN || // New prefixed version (recommended)
5292
- process.env.JWT_EXPIRES_IN || // Legacy fallback
5293
- "7d";
5294
- function verifyClientToken(token, publicKeyB64, algorithm) {
5295
- try {
5296
- const publicKeyDER = Buffer.from(publicKeyB64, "base64");
5297
- const publicKeyObject = crypto.createPublicKey({
5298
- key: publicKeyDER,
5299
- format: "der",
5300
- type: "spki"
5301
- });
5302
- const decoded = jwt.verify(token, publicKeyObject, {
5303
- algorithms: [algorithm],
5304
- // Prevent algorithm confusion attacks
5305
- issuer: "spfn-client"
5306
- // Validate token issuer
5307
- });
5308
- if (typeof decoded === "string") {
5309
- throw new Error("Invalid token format: expected object payload");
5310
- }
5311
- return decoded;
5312
- } catch (error) {
5313
- if (error instanceof jwt.TokenExpiredError) {
5314
- throw new Error("Token has expired");
5315
- }
5316
- if (error instanceof jwt.JsonWebTokenError) {
5317
- throw new Error("Invalid token signature");
5318
- }
5319
- throw new Error(`Token verification failed: ${error instanceof Error ? error.message : "Unknown error"}`);
5401
+ // src/server/helpers/password.ts
5402
+ import bcrypt from "bcrypt";
5403
+ var SALT_ROUNDS = parseInt(
5404
+ process.env.SPFN_AUTH_BCRYPT_SALT_ROUNDS || // New prefixed version (recommended)
5405
+ process.env.BCRYPT_SALT_ROUNDS || // Legacy fallback
5406
+ "10",
5407
+ 10
5408
+ );
5409
+ async function hashPassword(password) {
5410
+ if (!password || password.length === 0) {
5411
+ throw new Error("Password cannot be empty");
5320
5412
  }
5413
+ return bcrypt.hash(password, SALT_ROUNDS);
5321
5414
  }
5322
- function verifyKeyFingerprint(publicKeyB64, expectedFingerprint) {
5323
- try {
5324
- const publicKeyDER = Buffer.from(publicKeyB64, "base64");
5325
- const fingerprint = crypto.createHash("sha256").update(publicKeyDER).digest("hex");
5326
- return fingerprint === expectedFingerprint;
5327
- } catch (error) {
5328
- console.error("Failed to verify key fingerprint:", error);
5329
- return false;
5415
+ async function verifyPassword(password, hash) {
5416
+ if (!password || password.length === 0) {
5417
+ throw new Error("Password cannot be empty");
5418
+ }
5419
+ if (!hash || hash.length === 0) {
5420
+ throw new Error("Hash cannot be empty");
5330
5421
  }
5422
+ return bcrypt.compare(password, hash);
5331
5423
  }
5332
5424
 
5333
- // src/server/middleware/authenticate.ts
5334
- init_entities();
5335
- import { findOne, getDatabase } from "@spfn/core/db";
5425
+ // src/server/helpers/index.ts
5426
+ init_jwt();
5336
5427
 
5337
- // src/server/errors/auth-errors.ts
5338
- import {
5339
- ValidationError,
5340
- UnauthorizedError,
5341
- ForbiddenError,
5342
- ConflictError
5343
- } from "@spfn/core/errors";
5344
- var InvalidCredentialsError = class extends UnauthorizedError {
5345
- constructor(message = "Invalid credentials") {
5346
- super(message);
5347
- this.name = "InvalidCredentialsError";
5348
- }
5349
- };
5350
- var InvalidTokenError = class extends UnauthorizedError {
5351
- constructor(message = "Invalid authentication token") {
5352
- super(message);
5353
- this.name = "InvalidTokenError";
5354
- }
5355
- };
5356
- var TokenExpiredError = class extends UnauthorizedError {
5357
- constructor(message = "Authentication token has expired") {
5358
- super(message);
5359
- this.name = "TokenExpiredError";
5360
- }
5361
- };
5362
- var KeyExpiredError = class extends UnauthorizedError {
5363
- constructor(message = "Public key has expired") {
5364
- super(message);
5365
- this.name = "KeyExpiredError";
5366
- }
5367
- };
5368
- var AccountDisabledError = class extends ForbiddenError {
5369
- constructor(status = "disabled") {
5370
- super(`Account is ${status}`);
5371
- this.name = "AccountDisabledError";
5372
- this.details = { status };
5373
- }
5374
- };
5375
- var AccountAlreadyExistsError = class extends ConflictError {
5376
- constructor(identifier, identifierType) {
5377
- super("Account already exists");
5378
- this.name = "AccountAlreadyExistsError";
5379
- this.details = { identifier, identifierType };
5380
- }
5381
- };
5382
- var InvalidVerificationCodeError = class extends ValidationError {
5383
- constructor(reason = "Invalid verification code") {
5384
- super(reason);
5385
- this.name = "InvalidVerificationCodeError";
5386
- }
5387
- };
5388
- var InvalidVerificationTokenError = class extends ValidationError {
5389
- constructor(message = "Invalid or expired verification token") {
5390
- super(message);
5391
- this.name = "InvalidVerificationTokenError";
5392
- }
5393
- };
5394
- var InvalidKeyFingerprintError = class extends ValidationError {
5395
- constructor(message = "Invalid key fingerprint") {
5396
- super(message);
5397
- this.name = "InvalidKeyFingerprintError";
5398
- }
5399
- };
5400
- var VerificationTokenPurposeMismatchError = class extends ValidationError {
5401
- constructor(expected, actual) {
5402
- super(`Verification token is for ${actual}, but ${expected} was expected`);
5403
- this.name = "VerificationTokenPurposeMismatchError";
5404
- this.details = { expected, actual };
5405
- }
5406
- };
5407
- var VerificationTokenTargetMismatchError = class extends ValidationError {
5408
- constructor() {
5409
- super("Verification token does not match provided email/phone");
5410
- this.name = "VerificationTokenTargetMismatchError";
5411
- }
5412
- };
5413
-
5414
- // src/server/middleware/authenticate.ts
5415
- import { UnauthorizedError as UnauthorizedError2 } from "@spfn/core/errors";
5416
- import { eq, and } from "drizzle-orm";
5417
- async function authenticate(c, next) {
5418
- const authHeader = c.req.header("Authorization");
5419
- const keyId = c.req.header("X-Key-Id");
5420
- if (!authHeader || !authHeader.startsWith("Bearer ")) {
5421
- throw new UnauthorizedError2("Missing or invalid authorization header");
5422
- }
5423
- if (!keyId) {
5424
- throw new UnauthorizedError2("Missing X-Key-Id header");
5425
- }
5426
- const token = authHeader.substring(7);
5427
- const db = getDatabase();
5428
- const [keyRecord] = await db.select().from(userPublicKeys).where(
5429
- and(
5430
- eq(userPublicKeys.keyId, keyId),
5431
- eq(userPublicKeys.isActive, true)
5432
- )
5433
- );
5434
- if (!keyRecord) {
5435
- throw new UnauthorizedError2("Invalid or revoked key");
5436
- }
5437
- if (keyRecord.expiresAt && /* @__PURE__ */ new Date() > keyRecord.expiresAt) {
5438
- throw new KeyExpiredError();
5439
- }
5440
- try {
5441
- verifyClientToken(
5442
- token,
5443
- keyRecord.publicKey,
5444
- keyRecord.algorithm
5445
- );
5446
- } catch (err) {
5447
- if (err instanceof Error) {
5448
- if (err.name === "TokenExpiredError") {
5449
- throw new TokenExpiredError();
5450
- }
5451
- if (err.name === "JsonWebTokenError") {
5452
- throw new InvalidTokenError("Invalid token signature");
5453
- }
5454
- }
5455
- throw new UnauthorizedError2("Authentication failed");
5456
- }
5457
- const user = await findOne(users, { id: keyRecord.userId });
5458
- if (!user) {
5459
- throw new UnauthorizedError2("User not found");
5460
- }
5461
- if (user.status !== "active") {
5462
- throw new AccountDisabledError(user.status);
5463
- }
5464
- db.update(userPublicKeys).set({ lastUsedAt: /* @__PURE__ */ new Date() }).where(eq(userPublicKeys.id, keyRecord.id)).execute().catch((err) => console.error("Failed to update lastUsedAt:", err));
5465
- c.set("auth", {
5466
- user,
5467
- userId: String(user.id),
5468
- keyId
5469
- });
5470
- await next();
5471
- }
5472
-
5473
- // src/server/helpers/context.ts
5474
- function getAuth(c) {
5475
- if ("raw" in c && c.raw) {
5476
- return c.raw.get("auth");
5477
- }
5478
- return c.get("auth");
5479
- }
5480
- function getUser(c) {
5481
- return getAuth(c).user;
5482
- }
5483
-
5484
- // src/server/services/permission.service.ts
5485
- init_entities();
5486
- import { getDatabase as getDatabase2 } from "@spfn/core/db";
5487
- import { eq as eq2, and as and2 } from "drizzle-orm";
5488
-
5489
- // src/server/middleware/require-permission.ts
5490
- import { ForbiddenError as ForbiddenError2 } from "@spfn/core/errors";
5491
-
5492
- // src/server/middleware/require-role.ts
5493
- import { ForbiddenError as ForbiddenError3 } from "@spfn/core/errors";
5494
-
5495
- // src/server/helpers/password.ts
5496
- import bcrypt from "bcrypt";
5497
- var SALT_ROUNDS = parseInt(
5498
- process.env.SPFN_AUTH_BCRYPT_SALT_ROUNDS || // New prefixed version (recommended)
5499
- process.env.BCRYPT_SALT_ROUNDS || // Legacy fallback
5500
- "10",
5501
- 10
5502
- );
5503
- async function hashPassword(password) {
5504
- if (!password || password.length === 0) {
5505
- throw new Error("Password cannot be empty");
5506
- }
5507
- return bcrypt.hash(password, SALT_ROUNDS);
5508
- }
5509
- async function verifyPassword(password, hash) {
5510
- if (!password || password.length === 0) {
5511
- throw new Error("Password cannot be empty");
5512
- }
5513
- if (!hash || hash.length === 0) {
5514
- throw new Error("Hash cannot be empty");
5515
- }
5516
- return bcrypt.compare(password, hash);
5517
- }
5518
-
5519
- // src/server/helpers/verification.ts
5520
- init_verification_codes();
5521
- import jwt2 from "jsonwebtoken";
5522
- import { getDatabase as getDatabase3, create } from "@spfn/core/db";
5523
- import { eq as eq3, and as and3 } from "drizzle-orm";
5524
- function getVerificationTokenSecret() {
5525
- const secret = process.env.SPFN_AUTH_VERIFICATION_TOKEN_SECRET || // New prefixed version (recommended)
5526
- process.env.VERIFICATION_TOKEN_SECRET || // Legacy fallback
5527
- process.env.SPFN_AUTH_JWT_SECRET || // New JWT secret fallback
5528
- process.env.JWT_SECRET;
5529
- if (!secret || secret.length < 32) {
5530
- throw new Error("SPFN_AUTH_VERIFICATION_TOKEN_SECRET must be at least 32 characters long");
5428
+ // src/server/helpers/verification.ts
5429
+ init_verification_codes();
5430
+ import jwt2 from "jsonwebtoken";
5431
+ import { getDatabase, create } from "@spfn/core/db";
5432
+ import { eq, and } from "drizzle-orm";
5433
+ function getVerificationTokenSecret() {
5434
+ const secret = process.env.SPFN_AUTH_VERIFICATION_TOKEN_SECRET || // New prefixed version (recommended)
5435
+ process.env.VERIFICATION_TOKEN_SECRET || // Legacy fallback
5436
+ process.env.SPFN_AUTH_JWT_SECRET || // New JWT secret fallback
5437
+ process.env.JWT_SECRET;
5438
+ if (!secret || secret.length < 32) {
5439
+ throw new Error("SPFN_AUTH_VERIFICATION_TOKEN_SECRET must be at least 32 characters long");
5531
5440
  }
5532
5441
  return secret;
5533
5442
  }
@@ -5539,7 +5448,7 @@ function generateVerificationCode() {
5539
5448
  return code;
5540
5449
  }
5541
5450
  async function storeVerificationCode(target, targetType, code, purpose) {
5542
- const db = getDatabase3();
5451
+ const db = getDatabase();
5543
5452
  if (!db) {
5544
5453
  throw new Error("Database not initialized");
5545
5454
  }
@@ -5556,16 +5465,16 @@ async function storeVerificationCode(target, targetType, code, purpose) {
5556
5465
  return record;
5557
5466
  }
5558
5467
  async function validateVerificationCode(target, targetType, code, purpose) {
5559
- const db = getDatabase3();
5468
+ const db = getDatabase();
5560
5469
  if (!db) {
5561
5470
  throw new Error("Database not initialized");
5562
5471
  }
5563
5472
  const records = await db.select().from(verificationCodes).where(
5564
- and3(
5565
- eq3(verificationCodes.target, target),
5566
- eq3(verificationCodes.targetType, targetType),
5567
- eq3(verificationCodes.code, code),
5568
- eq3(verificationCodes.purpose, purpose)
5473
+ and(
5474
+ eq(verificationCodes.target, target),
5475
+ eq(verificationCodes.targetType, targetType),
5476
+ eq(verificationCodes.code, code),
5477
+ eq(verificationCodes.purpose, purpose)
5569
5478
  )
5570
5479
  ).limit(1);
5571
5480
  if (records.length === 0) {
@@ -5582,15 +5491,15 @@ async function validateVerificationCode(target, targetType, code, purpose) {
5582
5491
  if (attempts >= MAX_VERIFICATION_ATTEMPTS) {
5583
5492
  return { valid: false, error: "Too many attempts, please request a new code" };
5584
5493
  }
5585
- await db.update(verificationCodes).set({ attempts: (attempts + 1).toString() }).where(eq3(verificationCodes.id, record.id));
5494
+ await db.update(verificationCodes).set({ attempts: (attempts + 1).toString() }).where(eq(verificationCodes.id, record.id));
5586
5495
  return { valid: true, codeId: record.id };
5587
5496
  }
5588
5497
  async function markCodeAsUsed(codeId) {
5589
- const db = getDatabase3();
5498
+ const db = getDatabase();
5590
5499
  if (!db) {
5591
5500
  throw new Error("Database not initialized");
5592
5501
  }
5593
- await db.update(verificationCodes).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq3(verificationCodes.id, codeId));
5502
+ await db.update(verificationCodes).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq(verificationCodes.id, codeId));
5594
5503
  }
5595
5504
  function createVerificationToken(payload) {
5596
5505
  const secret = getVerificationTokenSecret();
@@ -5623,15 +5532,101 @@ async function sendVerificationSMS(phone, code, purpose) {
5623
5532
  console.log(`[VERIFICATION SMS] To: ${phone}, Code: ${code}, Purpose: ${purpose}`);
5624
5533
  }
5625
5534
 
5535
+ // src/server/helpers/context.ts
5536
+ function getAuth(c) {
5537
+ if ("raw" in c && c.raw) {
5538
+ return c.raw.get("auth");
5539
+ }
5540
+ return c.get("auth");
5541
+ }
5542
+ function getUser(c) {
5543
+ return getAuth(c).user;
5544
+ }
5545
+
5626
5546
  // src/server/services/auth.service.ts
5627
5547
  init_entities();
5628
- import { findOne as findOne3, create as create3 } from "@spfn/core/db";
5548
+ import { findOne as findOne2, create as create3 } from "@spfn/core/db";
5629
5549
  import { ValidationError as ValidationError2 } from "@spfn/core/errors";
5630
5550
 
5551
+ // src/server/errors/auth-errors.ts
5552
+ import {
5553
+ ValidationError,
5554
+ UnauthorizedError,
5555
+ ForbiddenError,
5556
+ ConflictError
5557
+ } from "@spfn/core/errors";
5558
+ var InvalidCredentialsError = class extends UnauthorizedError {
5559
+ constructor(message = "Invalid credentials") {
5560
+ super(message);
5561
+ this.name = "InvalidCredentialsError";
5562
+ }
5563
+ };
5564
+ var InvalidTokenError = class extends UnauthorizedError {
5565
+ constructor(message = "Invalid authentication token") {
5566
+ super(message);
5567
+ this.name = "InvalidTokenError";
5568
+ }
5569
+ };
5570
+ var TokenExpiredError = class extends UnauthorizedError {
5571
+ constructor(message = "Authentication token has expired") {
5572
+ super(message);
5573
+ this.name = "TokenExpiredError";
5574
+ }
5575
+ };
5576
+ var KeyExpiredError = class extends UnauthorizedError {
5577
+ constructor(message = "Public key has expired") {
5578
+ super(message);
5579
+ this.name = "KeyExpiredError";
5580
+ }
5581
+ };
5582
+ var AccountDisabledError = class extends ForbiddenError {
5583
+ constructor(status = "disabled") {
5584
+ super(`Account is ${status}`, { details: { status } });
5585
+ this.name = "AccountDisabledError";
5586
+ }
5587
+ };
5588
+ var AccountAlreadyExistsError = class extends ConflictError {
5589
+ constructor(identifier, identifierType) {
5590
+ super("Account already exists", { details: { identifier, identifierType } });
5591
+ this.name = "AccountAlreadyExistsError";
5592
+ }
5593
+ };
5594
+ var InvalidVerificationCodeError = class extends ValidationError {
5595
+ constructor(reason = "Invalid verification code") {
5596
+ super(reason);
5597
+ this.name = "InvalidVerificationCodeError";
5598
+ }
5599
+ };
5600
+ var InvalidVerificationTokenError = class extends ValidationError {
5601
+ constructor(message = "Invalid or expired verification token") {
5602
+ super(message);
5603
+ this.name = "InvalidVerificationTokenError";
5604
+ }
5605
+ };
5606
+ var InvalidKeyFingerprintError = class extends ValidationError {
5607
+ constructor(message = "Invalid key fingerprint") {
5608
+ super(message);
5609
+ this.name = "InvalidKeyFingerprintError";
5610
+ }
5611
+ };
5612
+ var VerificationTokenPurposeMismatchError = class extends ValidationError {
5613
+ constructor(expected, actual) {
5614
+ super(`Verification token is for ${actual}, but ${expected} was expected`, { details: { expected, actual } });
5615
+ this.name = "VerificationTokenPurposeMismatchError";
5616
+ }
5617
+ };
5618
+ var VerificationTokenTargetMismatchError = class extends ValidationError {
5619
+ constructor() {
5620
+ super("Verification token does not match provided email/phone");
5621
+ this.name = "VerificationTokenTargetMismatchError";
5622
+ }
5623
+ };
5624
+
5631
5625
  // src/server/services/key.service.ts
5632
5626
  init_entities();
5633
- import { create as create2, getDatabase as getDatabase4 } from "@spfn/core/db";
5634
- import { eq as eq4, and as and4 } from "drizzle-orm";
5627
+ init_jwt();
5628
+ import { create as create2, getDatabase as getDatabase2 } from "@spfn/core/db";
5629
+ import { eq as eq2, and as and2 } from "drizzle-orm";
5635
5630
  function getKeyExpiryDate() {
5636
5631
  const expiresAt = /* @__PURE__ */ new Date();
5637
5632
  expiresAt.setDate(expiresAt.getDate() + 90);
@@ -5660,15 +5655,15 @@ async function rotateKeyService(params) {
5660
5655
  if (!isValidFingerprint) {
5661
5656
  throw new InvalidKeyFingerprintError();
5662
5657
  }
5663
- const db = getDatabase4();
5658
+ const db = getDatabase2();
5664
5659
  await db.update(userPublicKeys).set({
5665
5660
  isActive: false,
5666
5661
  revokedAt: /* @__PURE__ */ new Date(),
5667
5662
  revokedReason: "Replaced by key rotation"
5668
5663
  }).where(
5669
- and4(
5670
- eq4(userPublicKeys.keyId, oldKeyId),
5671
- eq4(userPublicKeys.userId, userId)
5664
+ and2(
5665
+ eq2(userPublicKeys.keyId, oldKeyId),
5666
+ eq2(userPublicKeys.userId, userId)
5672
5667
  )
5673
5668
  );
5674
5669
  await create2(userPublicKeys, {
@@ -5688,22 +5683,22 @@ async function rotateKeyService(params) {
5688
5683
  }
5689
5684
  async function revokeKeyService(params) {
5690
5685
  const { userId, keyId, reason } = params;
5691
- const db = getDatabase4();
5686
+ const db = getDatabase2();
5692
5687
  await db.update(userPublicKeys).set({
5693
5688
  isActive: false,
5694
5689
  revokedAt: /* @__PURE__ */ new Date(),
5695
5690
  revokedReason: reason
5696
5691
  }).where(
5697
- and4(
5698
- eq4(userPublicKeys.keyId, keyId),
5699
- eq4(userPublicKeys.userId, userId)
5692
+ and2(
5693
+ eq2(userPublicKeys.keyId, keyId),
5694
+ eq2(userPublicKeys.userId, userId)
5700
5695
  )
5701
5696
  );
5702
5697
  }
5703
5698
 
5704
5699
  // src/server/services/user.service.ts
5705
5700
  init_entities();
5706
- import { findOne as findOne2, updateOne } from "@spfn/core/db";
5701
+ import { findOne, updateOne } from "@spfn/core/db";
5707
5702
  async function updateLastLoginService(userId) {
5708
5703
  await updateOne(users, { id: userId }, {
5709
5704
  lastLoginAt: /* @__PURE__ */ new Date()
@@ -5719,11 +5714,11 @@ async function checkAccountExistsService(params) {
5719
5714
  if (email) {
5720
5715
  identifier = email;
5721
5716
  identifierType = "email";
5722
- user = await findOne3(users, { email });
5717
+ user = await findOne2(users, { email });
5723
5718
  } else if (phone) {
5724
5719
  identifier = phone;
5725
5720
  identifierType = "phone";
5726
- user = await findOne3(users, { phone });
5721
+ user = await findOne2(users, { phone });
5727
5722
  } else {
5728
5723
  throw new ValidationError2("Either email or phone must be provided");
5729
5724
  }
@@ -5752,9 +5747,9 @@ async function registerService(params) {
5752
5747
  }
5753
5748
  let existingUser;
5754
5749
  if (email) {
5755
- existingUser = await findOne3(users, { email });
5750
+ existingUser = await findOne2(users, { email });
5756
5751
  } else if (phone) {
5757
- existingUser = await findOne3(users, { phone });
5752
+ existingUser = await findOne2(users, { phone });
5758
5753
  } else {
5759
5754
  throw new ValidationError2("Either email or phone must be provided");
5760
5755
  }
@@ -5795,15 +5790,17 @@ async function loginService(params) {
5795
5790
  const { email, phone, password, publicKey, keyId, fingerprint, oldKeyId, algorithm } = params;
5796
5791
  let user;
5797
5792
  if (email) {
5798
- user = await findOne3(users, { email });
5793
+ user = await findOne2(users, { email });
5799
5794
  } else if (phone) {
5800
- user = await findOne3(users, { phone });
5795
+ user = await findOne2(users, { phone });
5801
5796
  } else {
5802
5797
  throw new ValidationError2("Either email or phone must be provided");
5803
5798
  }
5804
5799
  if (!user || !user.passwordHash) {
5805
5800
  throw new InvalidCredentialsError();
5806
5801
  }
5802
+ console.log("user", user);
5803
+ console.log("\uD328\uC2A4\uC6CC\uB4DC: ", password);
5807
5804
  const isValid = await verifyPassword(password, user.passwordHash);
5808
5805
  if (!isValid) {
5809
5806
  throw new InvalidCredentialsError();
@@ -5847,7 +5844,7 @@ async function changePasswordService(params) {
5847
5844
  if (providedHash) {
5848
5845
  passwordHash = providedHash;
5849
5846
  } else {
5850
- const user = await findOne3(users, { id: userId });
5847
+ const user = await findOne2(users, { id: userId });
5851
5848
  if (!user) {
5852
5849
  throw new ValidationError2("User not found");
5853
5850
  }
@@ -5903,10 +5900,132 @@ async function verifyCodeService(params) {
5903
5900
  };
5904
5901
  }
5905
5902
 
5903
+ // src/server/services/me.service.ts
5904
+ init_entities();
5905
+ import { getDatabase as getDatabase4 } from "@spfn/core/db";
5906
+ import { eq as eq4, and as and4 } from "drizzle-orm";
5907
+ async function getMeService(userId) {
5908
+ const db = getDatabase4();
5909
+ if (!db) {
5910
+ throw new Error("[Auth] Database not initialized");
5911
+ }
5912
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
5913
+ const [userWithRole] = await db.select({
5914
+ userId: users.id,
5915
+ email: users.email,
5916
+ phone: users.phone,
5917
+ roleId: roles.id,
5918
+ roleName: roles.name,
5919
+ roleDisplayName: roles.displayName,
5920
+ rolePriority: roles.priority
5921
+ }).from(users).innerJoin(roles, eq4(users.roleId, roles.id)).where(eq4(users.id, userIdNum)).limit(1);
5922
+ if (!userWithRole) {
5923
+ throw new Error("[Auth] User not found");
5924
+ }
5925
+ const rolePerms = await db.select({
5926
+ id: permissions.id,
5927
+ name: permissions.name,
5928
+ displayName: permissions.displayName,
5929
+ category: permissions.category
5930
+ }).from(rolePermissions).innerJoin(permissions, eq4(rolePermissions.permissionId, permissions.id)).where(
5931
+ and4(
5932
+ eq4(rolePermissions.roleId, userWithRole.roleId),
5933
+ eq4(permissions.isActive, true)
5934
+ )
5935
+ );
5936
+ return {
5937
+ userId: userWithRole.userId.toString(),
5938
+ email: userWithRole.email ?? void 0,
5939
+ phone: userWithRole.phone ?? void 0,
5940
+ role: {
5941
+ id: userWithRole.roleId,
5942
+ name: userWithRole.roleName,
5943
+ displayName: userWithRole.roleDisplayName,
5944
+ priority: userWithRole.rolePriority
5945
+ },
5946
+ permissions: rolePerms.map((perm) => ({
5947
+ id: perm.id,
5948
+ name: perm.name,
5949
+ displayName: perm.displayName,
5950
+ category: perm.category ?? void 0
5951
+ }))
5952
+ };
5953
+ }
5954
+
5906
5955
  // src/server/services/rbac.service.ts
5907
5956
  init_entities();
5957
+ import { getDatabase as getDatabase5 } from "@spfn/core/db";
5958
+ import { logger } from "@spfn/core/logger";
5959
+ import { eq as eq5, and as and5, inArray } from "drizzle-orm";
5960
+ var authLogger = logger.child("@spfn/auth");
5961
+
5962
+ // src/server/services/permission.service.ts
5963
+ init_entities();
5908
5964
  import { getDatabase as getDatabase6 } from "@spfn/core/db";
5909
- import { eq as eq6, and as and6, inArray } from "drizzle-orm";
5965
+ import { eq as eq6, and as and6 } from "drizzle-orm";
5966
+ async function getUserPermissions(userId) {
5967
+ const db = getDatabase6();
5968
+ if (!db) {
5969
+ throw new Error("[Auth] Database not initialized");
5970
+ }
5971
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
5972
+ const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq6(users.id, userIdNum)).limit(1);
5973
+ if (!user || !user.roleId) {
5974
+ return [];
5975
+ }
5976
+ const permSet = /* @__PURE__ */ new Set();
5977
+ const rolePerms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq6(rolePermissions.permissionId, permissions.id)).where(
5978
+ and6(
5979
+ eq6(rolePermissions.roleId, user.roleId),
5980
+ eq6(permissions.isActive, true)
5981
+ )
5982
+ );
5983
+ for (const perm of rolePerms) {
5984
+ permSet.add(perm.name);
5985
+ }
5986
+ const userPerms = await db.select({
5987
+ name: permissions.name,
5988
+ granted: userPermissions.granted,
5989
+ expiresAt: userPermissions.expiresAt
5990
+ }).from(userPermissions).innerJoin(permissions, eq6(userPermissions.permissionId, permissions.id)).where(eq6(userPermissions.userId, userIdNum));
5991
+ const now = /* @__PURE__ */ new Date();
5992
+ for (const userPerm of userPerms) {
5993
+ if (userPerm.expiresAt && userPerm.expiresAt < now) {
5994
+ continue;
5995
+ }
5996
+ if (userPerm.granted) {
5997
+ permSet.add(userPerm.name);
5998
+ } else {
5999
+ permSet.delete(userPerm.name);
6000
+ }
6001
+ }
6002
+ return Array.from(permSet);
6003
+ }
6004
+ async function hasAllPermissions(userId, permissionNames) {
6005
+ const perms = await getUserPermissions(userId);
6006
+ return permissionNames.every((p) => perms.includes(p));
6007
+ }
6008
+ async function hasRole(userId, roleName) {
6009
+ const db = getDatabase6();
6010
+ if (!db) {
6011
+ throw new Error("[Auth] Database not initialized");
6012
+ }
6013
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
6014
+ const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq6(users.id, userIdNum)).limit(1);
6015
+ if (!user || !user.roleId) {
6016
+ return false;
6017
+ }
6018
+ const [role] = await db.select({ name: roles.name }).from(roles).where(eq6(roles.id, user.roleId)).limit(1);
6019
+ return role?.name === roleName;
6020
+ }
6021
+ async function hasAnyRole(userId, roleNames) {
6022
+ for (const roleName of roleNames) {
6023
+ if (await hasRole(userId, roleName)) {
6024
+ return true;
6025
+ }
6026
+ }
6027
+ return false;
6028
+ }
5910
6029
 
5911
6030
  // src/server/services/index.ts
5912
6031
  init_role_service();
@@ -6202,12 +6321,16 @@ app.bind(loginContract, async (c) => {
6202
6321
  const result = await loginService(body);
6203
6322
  return c.success(result);
6204
6323
  });
6205
- app.bind(logoutContract, [authenticate], async (c) => {
6206
- const { keyId, userId } = getAuth(c);
6324
+ app.bind(logoutContract, async (c) => {
6325
+ const auth = getAuth(c);
6326
+ if (!auth) {
6327
+ return c.success({ success: true });
6328
+ }
6329
+ const { keyId, userId } = auth;
6207
6330
  await logoutService({ userId: Number(userId), keyId });
6208
6331
  return c.success({ success: true });
6209
6332
  });
6210
- app.bind(rotateKeyContract, [authenticate], async (c) => {
6333
+ app.bind(rotateKeyContract, async (c) => {
6211
6334
  const body = await c.data();
6212
6335
  const { keyId: oldKeyId, userId } = getAuth(c);
6213
6336
  const result = await rotateKeyService({
@@ -6220,7 +6343,7 @@ app.bind(rotateKeyContract, [authenticate], async (c) => {
6220
6343
  });
6221
6344
  return c.success(result);
6222
6345
  });
6223
- app.bind(changePasswordContract, [authenticate], async (c) => {
6346
+ app.bind(changePasswordContract, async (c) => {
6224
6347
  const body = await c.data();
6225
6348
  const user = getUser(c);
6226
6349
  await changePasswordService({
@@ -6231,10 +6354,119 @@ app.bind(changePasswordContract, [authenticate], async (c) => {
6231
6354
  });
6232
6355
  return c.success({ success: true });
6233
6356
  });
6357
+ app.bind(getMeContract, async (c) => {
6358
+ const { userId } = getAuth(c);
6359
+ const result = await getMeService(userId);
6360
+ return c.success(result);
6361
+ });
6234
6362
  var auth_default = app;
6235
6363
 
6236
6364
  // src/server/routes/invitations/index.ts
6237
6365
  import { createApp as createApp2 } from "@spfn/core/route";
6366
+
6367
+ // src/server/middleware/authenticate.ts
6368
+ init_jwt();
6369
+ init_entities();
6370
+ import { findOne as findOne3, getDatabase as getDatabase8 } from "@spfn/core/db";
6371
+ import { UnauthorizedError as UnauthorizedError2 } from "@spfn/core/errors";
6372
+ import { eq as eq8, and as and8 } from "drizzle-orm";
6373
+ async function authenticate(c, next) {
6374
+ const authHeader = c.req.header("Authorization");
6375
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
6376
+ throw new UnauthorizedError2("Missing or invalid authorization header");
6377
+ }
6378
+ const token = authHeader.substring(7);
6379
+ const { decodeToken: decodeToken2 } = await Promise.resolve().then(() => (init_jwt(), jwt_exports));
6380
+ const decoded = decodeToken2(token);
6381
+ if (!decoded || !decoded.keyId) {
6382
+ throw new UnauthorizedError2("Invalid token: missing keyId");
6383
+ }
6384
+ const keyId = decoded.keyId;
6385
+ const db = getDatabase8();
6386
+ const [keyRecord] = await db.select().from(userPublicKeys).where(
6387
+ and8(
6388
+ eq8(userPublicKeys.keyId, keyId),
6389
+ eq8(userPublicKeys.isActive, true)
6390
+ )
6391
+ );
6392
+ if (!keyRecord) {
6393
+ throw new UnauthorizedError2("Invalid or revoked key");
6394
+ }
6395
+ if (keyRecord.expiresAt && /* @__PURE__ */ new Date() > keyRecord.expiresAt) {
6396
+ throw new KeyExpiredError();
6397
+ }
6398
+ try {
6399
+ verifyClientToken(
6400
+ token,
6401
+ keyRecord.publicKey,
6402
+ keyRecord.algorithm
6403
+ );
6404
+ } catch (err) {
6405
+ if (err instanceof Error) {
6406
+ if (err.name === "TokenExpiredError") {
6407
+ throw new TokenExpiredError();
6408
+ }
6409
+ if (err.name === "JsonWebTokenError") {
6410
+ throw new InvalidTokenError("Invalid token signature");
6411
+ }
6412
+ }
6413
+ throw new UnauthorizedError2("Authentication failed");
6414
+ }
6415
+ const user = await findOne3(users, { id: keyRecord.userId });
6416
+ if (!user) {
6417
+ throw new UnauthorizedError2("User not found");
6418
+ }
6419
+ if (user.status !== "active") {
6420
+ throw new AccountDisabledError(user.status);
6421
+ }
6422
+ db.update(userPublicKeys).set({ lastUsedAt: /* @__PURE__ */ new Date() }).where(eq8(userPublicKeys.id, keyRecord.id)).execute().catch((err) => console.error("Failed to update lastUsedAt:", err));
6423
+ c.set("auth", {
6424
+ user,
6425
+ userId: String(user.id),
6426
+ keyId
6427
+ });
6428
+ await next();
6429
+ }
6430
+
6431
+ // src/server/middleware/require-permission.ts
6432
+ import { ForbiddenError as ForbiddenError2 } from "@spfn/core/errors";
6433
+ function requirePermissions(...permissionNames) {
6434
+ return async (c, next) => {
6435
+ const auth = getAuth(c);
6436
+ if (!auth) {
6437
+ throw new ForbiddenError2("Authentication required");
6438
+ }
6439
+ const { userId } = auth;
6440
+ const allowed = await hasAllPermissions(userId, permissionNames);
6441
+ if (!allowed) {
6442
+ throw new ForbiddenError2(
6443
+ `Missing required permissions: ${permissionNames.join(", ")}`
6444
+ );
6445
+ }
6446
+ await next();
6447
+ };
6448
+ }
6449
+
6450
+ // src/server/middleware/require-role.ts
6451
+ import { ForbiddenError as ForbiddenError3 } from "@spfn/core/errors";
6452
+ function requireRole(...roleNames) {
6453
+ return async (c, next) => {
6454
+ const auth = getAuth(c);
6455
+ if (!auth) {
6456
+ throw new ForbiddenError3("Authentication required");
6457
+ }
6458
+ const { userId } = auth;
6459
+ const allowed = await hasAnyRole(userId, roleNames);
6460
+ if (!allowed) {
6461
+ throw new ForbiddenError3(
6462
+ `Required roles: ${roleNames.join(", ")}`
6463
+ );
6464
+ }
6465
+ await next();
6466
+ };
6467
+ }
6468
+
6469
+ // src/server/routes/invitations/index.ts
6238
6470
  var app2 = createApp2();
6239
6471
  app2.bind(getInvitationContract, async (c) => {
6240
6472
  const params = await c.data();
@@ -6268,7 +6500,7 @@ app2.bind(acceptInvitationContract, async (c) => {
6268
6500
  });
6269
6501
  return c.success(result);
6270
6502
  });
6271
- app2.bind(createInvitationContract, [authenticate], async (c) => {
6503
+ app2.bind(createInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
6272
6504
  const body = await c.data();
6273
6505
  const { userId } = getAuth(c);
6274
6506
  const invitation = await createInvitation({
@@ -6289,7 +6521,7 @@ app2.bind(createInvitationContract, [authenticate], async (c) => {
6289
6521
  invitationUrl
6290
6522
  });
6291
6523
  });
6292
- app2.bind(listInvitationsContract, [authenticate], async (c) => {
6524
+ app2.bind(listInvitationsContract, [authenticate, requirePermissions("user:read")], async (c) => {
6293
6525
  const query = await c.data();
6294
6526
  const result = await listInvitations({
6295
6527
  status: query.status,
@@ -6308,7 +6540,7 @@ app2.bind(listInvitationsContract, [authenticate], async (c) => {
6308
6540
  invitations: formattedInvitations
6309
6541
  });
6310
6542
  });
6311
- app2.bind(cancelInvitationContract, [authenticate], async (c) => {
6543
+ app2.bind(cancelInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
6312
6544
  const data = await c.data();
6313
6545
  const { userId } = getAuth(c);
6314
6546
  await cancelInvitation(
@@ -6321,7 +6553,7 @@ app2.bind(cancelInvitationContract, [authenticate], async (c) => {
6321
6553
  cancelledAt: (/* @__PURE__ */ new Date()).toISOString()
6322
6554
  });
6323
6555
  });
6324
- app2.bind(resendInvitationContract, [authenticate], async (c) => {
6556
+ app2.bind(resendInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
6325
6557
  const data = await c.data();
6326
6558
  const updated = await resendInvitation(
6327
6559
  data.id,
@@ -6332,7 +6564,7 @@ app2.bind(resendInvitationContract, [authenticate], async (c) => {
6332
6564
  expiresAt: updated.expiresAt.toISOString()
6333
6565
  });
6334
6566
  });
6335
- app2.bind(deleteInvitationContract, [authenticate], async (c) => {
6567
+ app2.bind(deleteInvitationContract, [authenticate, requireRole("superadmin")], async (c) => {
6336
6568
  const data = await c.data();
6337
6569
  await deleteInvitation(data.id);
6338
6570
  return c.success({