@kyro-cms/core 0.1.6 → 0.1.7

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 (170) hide show
  1. package/dist/WebhookService-BCgL1bLF.d.cts +112 -0
  2. package/dist/WebhookService-BPVJUgTl.d.ts +112 -0
  3. package/dist/{base-DlhVlwnN.d.cts → base-B0Y6isUJ.d.cts} +1 -1
  4. package/dist/{base-CQkFzqQl.d.ts → base-DaP-5PPG.d.ts} +1 -1
  5. package/dist/bootstrap-BMWVB2T6.cjs +31 -0
  6. package/dist/{bootstrap-WMWQ4DBX.cjs.map → bootstrap-BMWVB2T6.cjs.map} +1 -1
  7. package/dist/bootstrap-LL6O7PWO.js +6 -0
  8. package/dist/{bootstrap-WOVGAKZP.js.map → bootstrap-LL6O7PWO.js.map} +1 -1
  9. package/dist/{chunk-3VZCX4DF.cjs → chunk-42JPONZU.cjs} +77 -14
  10. package/dist/chunk-42JPONZU.cjs.map +1 -0
  11. package/dist/{chunk-3EVLFWH2.cjs → chunk-4M5PHMUE.cjs} +60 -346
  12. package/dist/chunk-4M5PHMUE.cjs.map +1 -0
  13. package/dist/chunk-4PWRCMTQ.cjs +15 -0
  14. package/dist/chunk-4PWRCMTQ.cjs.map +1 -0
  15. package/dist/chunk-6COM32WF.js +47 -0
  16. package/dist/chunk-6COM32WF.js.map +1 -0
  17. package/dist/chunk-6MSSF46R.js +941 -0
  18. package/dist/chunk-6MSSF46R.js.map +1 -0
  19. package/dist/{chunk-TZFJMPCH.cjs → chunk-7YITG2US.cjs} +9 -18
  20. package/dist/chunk-7YITG2US.cjs.map +1 -0
  21. package/dist/{chunk-A3RQWHKD.cjs → chunk-BLMFBDBG.cjs} +56 -6
  22. package/dist/chunk-BLMFBDBG.cjs.map +1 -0
  23. package/dist/{chunk-EINVJPFM.js → chunk-BTOE3VUK.js} +65 -3
  24. package/dist/chunk-BTOE3VUK.js.map +1 -0
  25. package/dist/chunk-E5X75WNB.js +497 -0
  26. package/dist/chunk-E5X75WNB.js.map +1 -0
  27. package/dist/chunk-E63IF3MD.cjs +951 -0
  28. package/dist/chunk-E63IF3MD.cjs.map +1 -0
  29. package/dist/{chunk-K7QF2QCM.cjs → chunk-FTSSDDZQ.cjs} +7 -3
  30. package/dist/chunk-FTSSDDZQ.cjs.map +1 -0
  31. package/dist/chunk-G7VZBCD6.cjs +35 -0
  32. package/dist/{chunk-5BLDMQED.cjs.map → chunk-G7VZBCD6.cjs.map} +1 -1
  33. package/dist/{chunk-VMSRTAH7.js → chunk-GLCPGZPM.js} +56 -6
  34. package/dist/chunk-GLCPGZPM.js.map +1 -0
  35. package/dist/{chunk-V3B25QOK.cjs → chunk-GVFB5C6O.cjs} +74 -2
  36. package/dist/chunk-GVFB5C6O.cjs.map +1 -0
  37. package/dist/chunk-HVSQDZZJ.cjs +765 -0
  38. package/dist/chunk-HVSQDZZJ.cjs.map +1 -0
  39. package/dist/chunk-HYC4GNHX.js +758 -0
  40. package/dist/chunk-HYC4GNHX.js.map +1 -0
  41. package/dist/chunk-KDVDIZ4Y.cjs +3479 -0
  42. package/dist/chunk-KDVDIZ4Y.cjs.map +1 -0
  43. package/dist/{chunk-OG3KX56O.js → chunk-KWGNR4HM.js} +7 -3
  44. package/dist/chunk-KWGNR4HM.js.map +1 -0
  45. package/dist/chunk-LIJVWQKU.cjs +256 -0
  46. package/dist/chunk-LIJVWQKU.cjs.map +1 -0
  47. package/dist/{chunk-XTZSUDSI.js → chunk-LTRCYJAG.js} +3 -18
  48. package/dist/chunk-LTRCYJAG.js.map +1 -0
  49. package/dist/{chunk-UEYC46RL.js → chunk-OUGKLCYF.js} +71 -8
  50. package/dist/chunk-OUGKLCYF.js.map +1 -0
  51. package/dist/chunk-RONAX6UU.js +3456 -0
  52. package/dist/chunk-RONAX6UU.js.map +1 -0
  53. package/dist/{chunk-5Y7QGIHD.js → chunk-RRYXQMZG.js} +60 -344
  54. package/dist/chunk-RRYXQMZG.js.map +1 -0
  55. package/dist/{chunk-QUJ4OLSC.js → chunk-U74F3YZU.js} +87 -7
  56. package/dist/chunk-U74F3YZU.js.map +1 -0
  57. package/dist/chunk-VIONYQ2K.cjs +517 -0
  58. package/dist/chunk-VIONYQ2K.cjs.map +1 -0
  59. package/dist/chunk-VSTRLXMQ.cjs +50 -0
  60. package/dist/chunk-VSTRLXMQ.cjs.map +1 -0
  61. package/dist/chunk-YT7HXXVN.js +13 -0
  62. package/dist/chunk-YT7HXXVN.js.map +1 -0
  63. package/dist/chunk-Z6ZWNWWR.js +30 -0
  64. package/dist/{chunk-NSBPE2FW.js.map → chunk-Z6ZWNWWR.js.map} +1 -1
  65. package/dist/cli/index.cjs +11 -7
  66. package/dist/cli/index.cjs.map +1 -1
  67. package/dist/cli/index.js +11 -7
  68. package/dist/cli/index.js.map +1 -1
  69. package/dist/drizzle/index.cjs +20 -17
  70. package/dist/drizzle/index.d.cts +4 -4
  71. package/dist/drizzle/index.d.ts +4 -4
  72. package/dist/drizzle/index.js +4 -5
  73. package/dist/graphql/index.cjs +4 -4
  74. package/dist/graphql/index.d.cts +3 -2
  75. package/dist/graphql/index.d.ts +3 -2
  76. package/dist/graphql/index.js +2 -2
  77. package/dist/{index-DI0DRPNv.d.cts → index-BwE4NueJ.d.cts} +1 -1
  78. package/dist/{index-CMUNCIWQ.d.ts → index-DUKmDSeC.d.cts} +96 -24
  79. package/dist/{index-BMySjW6o.d.cts → index-DtBi3zP0.d.ts} +96 -24
  80. package/dist/{index-4fJKLFK2.d.ts → index-DupWTmW6.d.ts} +1 -1
  81. package/dist/index.cjs +3317 -352
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.cts +379 -105
  84. package/dist/index.d.ts +379 -105
  85. package/dist/index.js +3211 -310
  86. package/dist/index.js.map +1 -1
  87. package/dist/media-HOT3O7RW.js +4 -0
  88. package/dist/media-HOT3O7RW.js.map +1 -0
  89. package/dist/media-WKP5AOX2.cjs +17 -0
  90. package/dist/media-WKP5AOX2.cjs.map +1 -0
  91. package/dist/mongodb/index.cjs +1 -1
  92. package/dist/mongodb/index.d.cts +2 -2
  93. package/dist/mongodb/index.d.ts +2 -2
  94. package/dist/mongodb/index.js +1 -1
  95. package/dist/mysql-media-AI6YK767.cjs +48 -0
  96. package/dist/mysql-media-AI6YK767.cjs.map +1 -0
  97. package/dist/mysql-media-CDZUS7YX.js +45 -0
  98. package/dist/mysql-media-CDZUS7YX.js.map +1 -0
  99. package/dist/postgres-auth-adapter-EVRPO7BQ.cjs +14 -0
  100. package/dist/{postgres-auth-adapter-VK6GY7LX.cjs.map → postgres-auth-adapter-EVRPO7BQ.cjs.map} +1 -1
  101. package/dist/postgres-auth-adapter-OTRWSTT5.js +5 -0
  102. package/dist/{postgres-auth-adapter-REJFUMP7.js.map → postgres-auth-adapter-OTRWSTT5.js.map} +1 -1
  103. package/dist/redis-adapter-2N6VA7BI.cjs +13 -0
  104. package/dist/{redis-adapter-LBLNKGNS.cjs.map → redis-adapter-2N6VA7BI.cjs.map} +1 -1
  105. package/dist/redis-adapter-RA24FNCX.js +4 -0
  106. package/dist/{redis-adapter-4YDY4LWE.js.map → redis-adapter-RA24FNCX.js.map} +1 -1
  107. package/dist/rest/index.cjs +7 -5
  108. package/dist/rest/index.d.cts +29 -3
  109. package/dist/rest/index.d.ts +29 -3
  110. package/dist/rest/index.js +5 -3
  111. package/dist/schema-CNB2DDTX.js +6 -0
  112. package/dist/schema-CNB2DDTX.js.map +1 -0
  113. package/dist/schema-Y777CQQS.cjs +67 -0
  114. package/dist/schema-Y777CQQS.cjs.map +1 -0
  115. package/dist/templates/index.cjs +24 -28
  116. package/dist/templates/index.d.cts +2 -4
  117. package/dist/templates/index.d.ts +2 -4
  118. package/dist/templates/index.js +2 -2
  119. package/dist/trpc/index.cjs +12 -12
  120. package/dist/trpc/index.d.cts +19 -14
  121. package/dist/trpc/index.d.ts +19 -14
  122. package/dist/trpc/index.js +3 -3
  123. package/dist/{types-BGM5MV_K.d.cts → types-BM0s_YOy.d.cts} +67 -35
  124. package/dist/{types-BGM5MV_K.d.ts → types-BM0s_YOy.d.ts} +67 -35
  125. package/dist/ws/index.cjs +1 -1
  126. package/dist/ws/index.js +1 -1
  127. package/package.json +11 -1
  128. package/dist/bootstrap-WMWQ4DBX.cjs +0 -29
  129. package/dist/bootstrap-WOVGAKZP.js +0 -4
  130. package/dist/chunk-3EVLFWH2.cjs.map +0 -1
  131. package/dist/chunk-3QX6KG2S.js +0 -2125
  132. package/dist/chunk-3QX6KG2S.js.map +0 -1
  133. package/dist/chunk-3VZCX4DF.cjs.map +0 -1
  134. package/dist/chunk-5BLDMQED.cjs +0 -18
  135. package/dist/chunk-5Y7QGIHD.js.map +0 -1
  136. package/dist/chunk-7G6EVYCU.cjs +0 -94
  137. package/dist/chunk-7G6EVYCU.cjs.map +0 -1
  138. package/dist/chunk-A3RQWHKD.cjs.map +0 -1
  139. package/dist/chunk-EINVJPFM.js.map +0 -1
  140. package/dist/chunk-F5B64H5S.cjs +0 -2149
  141. package/dist/chunk-F5B64H5S.cjs.map +0 -1
  142. package/dist/chunk-K7QF2QCM.cjs.map +0 -1
  143. package/dist/chunk-LRTZJJPD.js +0 -86
  144. package/dist/chunk-LRTZJJPD.js.map +0 -1
  145. package/dist/chunk-NSBPE2FW.js +0 -15
  146. package/dist/chunk-OG3KX56O.js.map +0 -1
  147. package/dist/chunk-QUJ4OLSC.js.map +0 -1
  148. package/dist/chunk-R3XIBBAW.cjs +0 -34
  149. package/dist/chunk-R3XIBBAW.cjs.map +0 -1
  150. package/dist/chunk-SDMNUYVU.js +0 -30
  151. package/dist/chunk-SDMNUYVU.js.map +0 -1
  152. package/dist/chunk-TZFJMPCH.cjs.map +0 -1
  153. package/dist/chunk-UEG7KMKC.cjs +0 -228
  154. package/dist/chunk-UEG7KMKC.cjs.map +0 -1
  155. package/dist/chunk-UEYC46RL.js.map +0 -1
  156. package/dist/chunk-V3B25QOK.cjs.map +0 -1
  157. package/dist/chunk-VMSRTAH7.js.map +0 -1
  158. package/dist/chunk-XTZSUDSI.js.map +0 -1
  159. package/dist/chunk-YD7Y25W7.cjs +0 -176
  160. package/dist/chunk-YD7Y25W7.cjs.map +0 -1
  161. package/dist/chunk-YPAFJ7EV.js +0 -225
  162. package/dist/chunk-YPAFJ7EV.js.map +0 -1
  163. package/dist/database-7CJOXEZR.js +0 -5
  164. package/dist/database-7CJOXEZR.js.map +0 -1
  165. package/dist/database-QOIV44GT.cjs +0 -22
  166. package/dist/database-QOIV44GT.cjs.map +0 -1
  167. package/dist/postgres-auth-adapter-REJFUMP7.js +0 -5
  168. package/dist/postgres-auth-adapter-VK6GY7LX.cjs +0 -14
  169. package/dist/redis-adapter-4YDY4LWE.js +0 -4
  170. package/dist/redis-adapter-LBLNKGNS.cjs +0 -13
@@ -1,5 +1,5 @@
1
- import { users, sessions, passwordHistory, lockouts } from './chunk-XTZSUDSI.js';
2
- import { eq, and, gt, desc } from 'drizzle-orm';
1
+ import { users, sessions, passwordHistory, lockouts, auditLogs } from './chunk-LTRCYJAG.js';
2
+ import { eq, and, gt, desc, sql } from 'drizzle-orm';
3
3
  import bcrypt from 'bcryptjs';
4
4
  import { randomBytes } from 'crypto';
5
5
 
@@ -15,9 +15,10 @@ var PostgresAuthAdapter = class {
15
15
  this.refreshTokenTTL = options.refreshTokenTTL || 604800;
16
16
  }
17
17
  async createUser(data) {
18
+ const passwordHash = await this.hashPassword(data.password);
18
19
  const [user] = await this.db.insert(users).values({
19
20
  email: data.email.toLowerCase(),
20
- passwordHash: data.passwordHash,
21
+ passwordHash,
21
22
  role: data.role || "customer",
22
23
  tenantId: data.tenantId
23
24
  }).returning();
@@ -52,8 +53,13 @@ var PostgresAuthAdapter = class {
52
53
  await this.db.delete(users).where(eq(users.id, id));
53
54
  return true;
54
55
  }
55
- async verifyPassword(password, hash) {
56
- return bcrypt.compare(password, hash);
56
+ async verifyPassword(email, password) {
57
+ const user = await this.findUserByEmail(email);
58
+ if (!user) return null;
59
+ const [stored] = await this.db.select().from(users).where(eq(users.email, email.toLowerCase())).limit(1);
60
+ if (!stored?.passwordHash) return null;
61
+ const valid = await bcrypt.compare(password, stored.passwordHash);
62
+ return valid ? user : null;
57
63
  }
58
64
  async hashPassword(password) {
59
65
  return bcrypt.hash(password, 12);
@@ -136,6 +142,80 @@ var PostgresAuthAdapter = class {
136
142
  async resetAttempts(userId) {
137
143
  await this.updateUser(userId, { failedLoginAttempts: 0 });
138
144
  }
145
+ async findAuditLogs(filter) {
146
+ const {
147
+ limit = 50,
148
+ offset = 0,
149
+ userId,
150
+ action,
151
+ resource,
152
+ resourceId,
153
+ success,
154
+ startDate,
155
+ endDate
156
+ } = filter;
157
+ const conditions = [];
158
+ if (userId) conditions.push(eq(auditLogs.userId, userId));
159
+ if (action) {
160
+ if (Array.isArray(action)) {
161
+ conditions.push(sql`${auditLogs.action} = ANY(${action})`);
162
+ } else {
163
+ conditions.push(eq(auditLogs.action, action));
164
+ }
165
+ }
166
+ if (resource) conditions.push(eq(auditLogs.resource, resource));
167
+ if (resourceId) conditions.push(eq(auditLogs.resourceId, resourceId));
168
+ if (success !== void 0) conditions.push(eq(auditLogs.success, success));
169
+ if (startDate) conditions.push(sql`${auditLogs.timestamp} >= ${startDate}`);
170
+ if (endDate) conditions.push(sql`${auditLogs.timestamp} <= ${endDate}`);
171
+ const whereClause = conditions.length > 0 ? and(...conditions) : void 0;
172
+ const countResult = await this.db.select({ count: sql`count(*)` }).from(auditLogs).where(whereClause);
173
+ const logs = await this.db.select().from(auditLogs).where(whereClause).orderBy(desc(auditLogs.timestamp)).limit(limit).offset(offset);
174
+ return {
175
+ logs: logs.map((log) => ({
176
+ id: log.id,
177
+ timestamp: log.timestamp,
178
+ action: log.action,
179
+ userId: log.userId || void 0,
180
+ userEmail: log.userEmail || void 0,
181
+ role: log.role || void 0,
182
+ resource: log.resource,
183
+ resourceId: log.resourceId || void 0,
184
+ changes: log.changes || void 0,
185
+ ipAddress: log.ipAddress || void 0,
186
+ userAgent: log.userAgent || void 0,
187
+ success: log.success,
188
+ error: log.error || void 0,
189
+ metadata: log.metadata || void 0
190
+ })),
191
+ total: Number(countResult[0]?.count || 0)
192
+ };
193
+ }
194
+ async createAuditLog(data) {
195
+ const id = crypto.randomUUID();
196
+ const timestamp = /* @__PURE__ */ new Date();
197
+ await this.db.insert(auditLogs).values({
198
+ id,
199
+ action: data.action,
200
+ userId: data.userId,
201
+ userEmail: data.userEmail,
202
+ role: data.role,
203
+ resource: data.resource,
204
+ resourceId: data.resourceId,
205
+ changes: data.changes,
206
+ ipAddress: data.ipAddress,
207
+ userAgent: data.userAgent,
208
+ success: data.success,
209
+ error: data.error,
210
+ metadata: data.metadata,
211
+ timestamp
212
+ });
213
+ return {
214
+ ...data,
215
+ id,
216
+ timestamp
217
+ };
218
+ }
139
219
  userToAuthUser(user) {
140
220
  return {
141
221
  id: user.id,
@@ -166,5 +246,5 @@ var PostgresAuthAdapter = class {
166
246
  };
167
247
 
168
248
  export { PostgresAuthAdapter };
169
- //# sourceMappingURL=chunk-QUJ4OLSC.js.map
170
- //# sourceMappingURL=chunk-QUJ4OLSC.js.map
249
+ //# sourceMappingURL=chunk-U74F3YZU.js.map
250
+ //# sourceMappingURL=chunk-U74F3YZU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/database/drizzle/postgres-auth-adapter.ts"],"names":[],"mappings":"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","file":"chunk-U74F3YZU.js","sourcesContent":["import type { PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport { eq, and, gt, desc, sql } from \"drizzle-orm\";\nimport bcrypt from \"bcryptjs\";\nimport { randomBytes } from \"crypto\";\nimport type {\n AuthAdapter,\n AuthUser,\n Session,\n UserRole,\n} from \"../../auth/types.js\";\nimport {\n users,\n sessions,\n passwordHistory,\n auditLogs,\n lockouts,\n type AuthUser as AuthUserRow,\n} from \"./schema/auth.js\";\nimport type {\n AuditLog,\n AuditLogFilter,\n} from \"../../auth/security/audit-log.js\";\n\nexport interface PostgresAuthAdapterOptions {\n db: PostgresJsDatabase;\n prefix?: string;\n sessionTTL?: number;\n refreshTokenTTL?: number;\n}\n\nexport class PostgresAuthAdapter implements AuthAdapter {\n private db: PostgresJsDatabase;\n private prefix: string;\n private sessionTTL: number;\n private refreshTokenTTL: number;\n\n constructor(options: PostgresAuthAdapterOptions) {\n this.db = options.db;\n this.prefix = options.prefix || \"kyro:\";\n this.sessionTTL = options.sessionTTL || 86400;\n this.refreshTokenTTL = options.refreshTokenTTL || 604800;\n }\n\n async createUser(data: {\n email: string;\n password: string;\n role?: UserRole;\n tenantId?: string;\n }): Promise<AuthUser> {\n const passwordHash = await this.hashPassword(data.password);\n const [user] = await this.db\n .insert(users)\n .values({\n email: data.email.toLowerCase(),\n passwordHash,\n role: (data.role || \"customer\") as string,\n tenantId: data.tenantId,\n })\n .returning();\n\n return this.userToAuthUser(user);\n }\n\n async findUserByEmail(email: string): Promise<AuthUser | null> {\n const [user] = await this.db\n .select()\n .from(users)\n .where(eq(users.email, email.toLowerCase()))\n .limit(1);\n\n return user ? this.userToAuthUser(user) : null;\n }\n\n async findUserById(id: string): Promise<AuthUser | null> {\n const [user] = await this.db\n .select()\n .from(users)\n .where(eq(users.id, id))\n .limit(1);\n\n return user ? this.userToAuthUser(user) : null;\n }\n\n async updateUser(\n id: string,\n data: Partial<AuthUser>,\n ): Promise<AuthUser | null> {\n const dbData: Record<string, unknown> = { updatedAt: new Date() };\n if (data.email !== undefined) dbData.email = data.email;\n if (data.passwordHash !== undefined)\n dbData.passwordHash = data.passwordHash;\n if (data.role !== undefined) dbData.role = data.role;\n if (data.tenantId !== undefined) dbData.tenantId = data.tenantId;\n if (data.emailVerified !== undefined)\n dbData.emailVerified = data.emailVerified;\n if (data.locked !== undefined) dbData.locked = data.locked;\n if (data.lastLogin !== undefined)\n dbData.lastLogin = data.lastLogin ? new Date(data.lastLogin) : null;\n if (data.failedLoginAttempts !== undefined)\n dbData.failedLoginAttempts = data.failedLoginAttempts;\n\n const [user] = await this.db\n .update(users)\n .set(dbData)\n .where(eq(users.id, id))\n .returning();\n\n return user ? this.userToAuthUser(user) : null;\n }\n\n async deleteUser(id: string): Promise<boolean> {\n await this.db.delete(users).where(eq(users.id, id));\n return true;\n }\n\n async verifyPassword(\n email: string,\n password: string,\n ): Promise<AuthUser | null> {\n const user = await this.findUserByEmail(email);\n if (!user) return null;\n const [stored] = await this.db\n .select()\n .from(users)\n .where(eq(users.email, email.toLowerCase()))\n .limit(1);\n if (!stored?.passwordHash) return null;\n const valid = await bcrypt.compare(password, stored.passwordHash);\n return valid ? user : null;\n }\n\n async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, 12);\n }\n\n async createSession(\n userId: string,\n data?: { ipAddress?: string; userAgent?: string },\n ): Promise<Session> {\n const token = randomBytes(32).toString(\"base64url\");\n const refreshToken = randomBytes(32).toString(\"base64url\");\n const expiresAt = new Date(Date.now() + this.sessionTTL * 1000);\n const refreshExpiresAt = new Date(Date.now() + this.refreshTokenTTL * 1000);\n\n const [session] = await this.db\n .insert(sessions)\n .values({\n userId,\n token,\n refreshToken,\n ipAddress: data?.ipAddress,\n userAgent: data?.userAgent,\n expiresAt,\n })\n .returning();\n\n return this.sessionToSession(session);\n }\n\n async findSessionByToken(token: string): Promise<Session | null> {\n const [session] = await this.db\n .select()\n .from(sessions)\n .where(and(eq(sessions.token, token), gt(sessions.expiresAt, new Date())))\n .limit(1);\n\n return session ? this.sessionToSession(session) : null;\n }\n\n async deleteSession(sessionId: string): Promise<boolean> {\n await this.db.delete(sessions).where(eq(sessions.id, sessionId));\n return true;\n }\n\n async deleteUserSessions(userId: string): Promise<number> {\n await this.db.delete(sessions).where(eq(sessions.userId, userId));\n return 1;\n }\n\n async addPasswordToHistory(\n userId: string,\n passwordHash: string,\n ): Promise<void> {\n await this.db.insert(passwordHistory).values({\n userId,\n passwordHash,\n });\n }\n\n async getPasswordHistory(\n userId: string,\n count: number = 5,\n ): Promise<string[]> {\n const history = await this.db\n .select({ passwordHash: passwordHistory.passwordHash })\n .from(passwordHistory)\n .where(eq(passwordHistory.userId, userId))\n .orderBy(desc(passwordHistory.createdAt))\n .limit(count);\n\n return history.map((h) => h.passwordHash);\n }\n\n async isPasswordInHistory(\n password: string,\n userId: string,\n historyCount: number = 5,\n ): Promise<boolean> {\n const history = await this.getPasswordHistory(userId, historyCount);\n\n for (const hash of history) {\n if (await this.verifyPassword(password, hash)) {\n return true;\n }\n }\n\n return false;\n }\n\n async isLocked(userId: string): Promise<boolean> {\n const [lockout] = await this.db\n .select()\n .from(lockouts)\n .where(\n and(eq(lockouts.userId, userId), gt(lockouts.lockedUntil, new Date())),\n )\n .limit(1);\n\n return !!lockout;\n }\n\n async getLockout(userId: string): Promise<{ lockedUntil: Date } | null> {\n const [lockout] = await this.db\n .select()\n .from(lockouts)\n .where(\n and(eq(lockouts.userId, userId), gt(lockouts.lockedUntil, new Date())),\n )\n .limit(1);\n\n return lockout ? { lockedUntil: lockout.lockedUntil } : null;\n }\n\n async recordFailedAttempt(\n userId: string,\n ipAddress?: string,\n ): Promise<{ attempts: number; locked: boolean }> {\n const user = await this.findUserById(userId);\n const attempts = (user?.failedLoginAttempts || 0) + 1;\n\n await this.updateUser(userId, { failedLoginAttempts: attempts });\n\n const maxAttempts = 5;\n const locked = attempts >= maxAttempts;\n\n if (locked) {\n const lockoutDuration = 15 * 60 * 1000;\n await this.db.insert(lockouts).values({\n userId,\n ipAddress,\n reason: \"Too many failed login attempts\",\n lockedUntil: new Date(Date.now() + lockoutDuration),\n });\n }\n\n return { attempts, locked };\n }\n\n async resetAttempts(userId: string): Promise<void> {\n await this.updateUser(userId, { failedLoginAttempts: 0 });\n }\n\n async findAuditLogs(\n filter: AuditLogFilter,\n ): Promise<{ logs: AuditLog[]; total: number }> {\n const {\n limit = 50,\n offset = 0,\n userId,\n action,\n resource,\n resourceId,\n success,\n startDate,\n endDate,\n } = filter;\n\n const conditions = [];\n if (userId) conditions.push(eq(auditLogs.userId, userId));\n if (action) {\n if (Array.isArray(action)) {\n conditions.push(sql`${auditLogs.action} = ANY(${action})`);\n } else {\n conditions.push(eq(auditLogs.action, action));\n }\n }\n if (resource) conditions.push(eq(auditLogs.resource, resource));\n if (resourceId) conditions.push(eq(auditLogs.resourceId, resourceId));\n if (success !== undefined) conditions.push(eq(auditLogs.success, success));\n if (startDate) conditions.push(sql`${auditLogs.timestamp} >= ${startDate}`);\n if (endDate) conditions.push(sql`${auditLogs.timestamp} <= ${endDate}`);\n\n const whereClause = conditions.length > 0 ? and(...conditions) : undefined;\n\n const countResult = await this.db\n .select({ count: sql<number>`count(*)` })\n .from(auditLogs)\n .where(whereClause);\n\n const logs = await this.db\n .select()\n .from(auditLogs)\n .where(whereClause)\n .orderBy(desc(auditLogs.timestamp))\n .limit(limit)\n .offset(offset);\n\n return {\n logs: logs.map((log) => ({\n id: log.id,\n timestamp: log.timestamp,\n action: log.action as AuditLog[\"action\"],\n userId: log.userId || undefined,\n userEmail: log.userEmail || undefined,\n role: log.role || undefined,\n resource: log.resource,\n resourceId: log.resourceId || undefined,\n changes: log.changes || undefined,\n ipAddress: log.ipAddress || undefined,\n userAgent: log.userAgent || undefined,\n success: log.success,\n error: log.error || undefined,\n metadata: log.metadata || undefined,\n })),\n total: Number(countResult[0]?.count || 0),\n };\n }\n\n async createAuditLog(\n data: Omit<AuditLog, \"id\" | \"timestamp\">,\n ): Promise<AuditLog> {\n const id = crypto.randomUUID();\n const timestamp = new Date();\n\n await this.db.insert(auditLogs).values({\n id,\n action: data.action,\n userId: data.userId,\n userEmail: data.userEmail,\n role: data.role,\n resource: data.resource,\n resourceId: data.resourceId,\n changes: data.changes,\n ipAddress: data.ipAddress,\n userAgent: data.userAgent,\n success: data.success,\n error: data.error,\n metadata: data.metadata,\n timestamp,\n });\n\n return {\n ...data,\n id,\n timestamp,\n };\n }\n\n private userToAuthUser(user: AuthUserRow): AuthUser {\n return {\n id: user.id,\n email: user.email,\n passwordHash: user.passwordHash || undefined,\n role: user.role as UserRole,\n tenantId: user.tenantId || undefined,\n emailVerified: user.emailVerified || false,\n locked: user.locked || false,\n lastLogin: user.lastLogin?.toISOString(),\n failedLoginAttempts: user.failedLoginAttempts || 0,\n createdAt: user.createdAt.toISOString(),\n updatedAt: user.updatedAt.toISOString(),\n };\n }\n\n private sessionToSession(session: typeof sessions.$inferSelect): Session {\n return {\n id: session.id,\n userId: session.userId,\n token: session.token,\n refreshToken: session.refreshToken || undefined,\n expiresAt: session.expiresAt.toISOString(),\n createdAt: session.createdAt.toISOString(),\n ipAddress: session.ipAddress || undefined,\n userAgent: session.userAgent || undefined,\n };\n }\n}\n"]}
@@ -0,0 +1,517 @@
1
+ 'use strict';
2
+
3
+ var crypto = require('crypto');
4
+
5
+ // src/access/types.ts
6
+ async function evaluateAccess(access, args) {
7
+ if (typeof access === "boolean") {
8
+ return access;
9
+ }
10
+ if (typeof access === "function") {
11
+ return await access(args);
12
+ }
13
+ return true;
14
+ }
15
+ function mergeWhereClauses(...whereClauses) {
16
+ const result = {};
17
+ for (const clause of whereClauses) {
18
+ if (clause && typeof clause === "object") {
19
+ Object.assign(result, clause);
20
+ }
21
+ }
22
+ return result;
23
+ }
24
+ function getWhereClause(access, args) {
25
+ return evaluateAccess(access, args).then((result) => {
26
+ if (result === true) return void 0;
27
+ if (result === false) return { _id: { $eq: null } };
28
+ return result;
29
+ });
30
+ }
31
+
32
+ // src/webhooks/types.ts
33
+ var WEBHOOK_EVENTS = {
34
+ COLLECTION_CREATE: "collection.create",
35
+ COLLECTION_UPDATE: "collection.update",
36
+ COLLECTION_DELETE: "collection.delete",
37
+ MEDIA_UPLOAD: "media.upload",
38
+ MEDIA_DELETE: "media.delete",
39
+ AUTH_LOGIN: "auth.login",
40
+ AUTH_REGISTER: "auth.register",
41
+ AUTH_LOGOUT: "auth.logout",
42
+ ORDER_CREATED: "order.created",
43
+ ORDER_PAID: "order.paid",
44
+ ORDER_SHIPPED: "order.shipped",
45
+ ORDER_DELIVERED: "order.delivered"
46
+ };
47
+ var ALL_WEBHOOK_EVENTS = Object.values(WEBHOOK_EVENTS);
48
+ var WEBHOOK_COLLECTION = "_webhooks";
49
+ var WEBHOOK_DELIVERY_COLLECTION = "_webhook_deliveries";
50
+ function signPayload(payload, secret) {
51
+ return `sha256=${crypto.createHmac("sha256", secret).update(payload).digest("hex")}`;
52
+ }
53
+ function generateWebhookSecret() {
54
+ return crypto.randomBytes(32).toString("hex");
55
+ }
56
+ async function deliverWebhook(webhook, payload, options = {}) {
57
+ const timeout = options.timeout || 3e4;
58
+ const startTime = Date.now();
59
+ const body = JSON.stringify(payload);
60
+ const headers = {
61
+ "Content-Type": "application/json",
62
+ "User-Agent": "Kyro-CMS-Webhook/1.0",
63
+ "X-Webhook-Event": payload.event,
64
+ "X-Webhook-Delivery": payload.id,
65
+ "X-Webhook-Timestamp": payload.timestamp,
66
+ ...webhook.headers || {}
67
+ };
68
+ if (webhook.secret) {
69
+ const signature = signPayload(body, webhook.secret);
70
+ headers["X-Webhook-Signature"] = signature;
71
+ }
72
+ const controller = new AbortController();
73
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
74
+ try {
75
+ const response = await fetch(webhook.url, {
76
+ method: "POST",
77
+ headers,
78
+ body,
79
+ signal: controller.signal
80
+ });
81
+ clearTimeout(timeoutId);
82
+ const duration = Date.now() - startTime;
83
+ let responseBody;
84
+ try {
85
+ const text = await response.text();
86
+ responseBody = text.slice(0, 1e3);
87
+ } catch {
88
+ }
89
+ const result = {
90
+ success: response.ok,
91
+ status: response.status,
92
+ statusText: response.statusText,
93
+ body: responseBody,
94
+ duration
95
+ };
96
+ if (result.success && options.onSuccess) {
97
+ options.onSuccess(result);
98
+ } else if (!result.success && options.onFailure) {
99
+ options.onFailure(`HTTP ${response.status}: ${response.statusText}`);
100
+ }
101
+ return result;
102
+ } catch (error) {
103
+ clearTimeout(timeoutId);
104
+ const duration = Date.now() - startTime;
105
+ const errorMessage = error.name === "AbortError" ? `Request timed out after ${timeout}ms` : error.message || "Unknown error";
106
+ if (options.onFailure) {
107
+ options.onFailure(errorMessage);
108
+ }
109
+ return {
110
+ success: false,
111
+ status: 0,
112
+ duration,
113
+ error: errorMessage
114
+ };
115
+ }
116
+ }
117
+ async function deliverWithRetry(webhook, payload, deliveryId, options = {}) {
118
+ const maxRetries = options.maxRetries ?? 5;
119
+ const baseDelay = options.retryDelay ?? 1e3;
120
+ let lastResult = null;
121
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
122
+ if (attempt > 0) {
123
+ const delay = Math.min(baseDelay * Math.pow(2, attempt - 1), 3e4);
124
+ if (options.onRetry) {
125
+ options.onRetry(attempt, `Retrying in ${delay}ms...`);
126
+ }
127
+ await sleep(delay);
128
+ }
129
+ if (options.onRetry && attempt > 0) {
130
+ options.onRetry(attempt, `Attempt ${attempt + 1}/${maxRetries + 1}`);
131
+ }
132
+ lastResult = await deliverWebhook(webhook, payload, {
133
+ ...options,
134
+ onRetry: void 0,
135
+ onSuccess: void 0,
136
+ onFailure: void 0
137
+ });
138
+ if (lastResult.success) {
139
+ return lastResult;
140
+ }
141
+ if (lastResult.error?.includes("timed out") && attempt < maxRetries) {
142
+ continue;
143
+ }
144
+ if (lastResult.status >= 400 && lastResult.status < 500) {
145
+ return lastResult;
146
+ }
147
+ }
148
+ return lastResult || {
149
+ success: false,
150
+ status: 0,
151
+ duration: 0,
152
+ error: "All delivery attempts failed"
153
+ };
154
+ }
155
+ function buildDeliveryRecord(deliveryId, webhookId, event, payload, attempt, result) {
156
+ return {
157
+ id: deliveryId,
158
+ webhookId,
159
+ event,
160
+ payload,
161
+ attempt,
162
+ status: result.success ? "success" : "failed",
163
+ responseStatus: result.status || void 0,
164
+ responseBody: result.body,
165
+ duration: result.duration,
166
+ error: result.error,
167
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
168
+ deliveredAt: result.success ? (/* @__PURE__ */ new Date()).toISOString() : void 0
169
+ };
170
+ }
171
+ function sleep(ms) {
172
+ return new Promise((resolve) => setTimeout(resolve, ms));
173
+ }
174
+ function createTestPayload() {
175
+ return {
176
+ id: `test_${Date.now()}`,
177
+ event: "collection.create",
178
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
179
+ collection: "test",
180
+ operation: "create",
181
+ data: { message: "This is a test webhook delivery" },
182
+ user: { id: "system", email: "system@kyro.dev", role: "super_admin" }
183
+ };
184
+ }
185
+ var WebhookService = class {
186
+ db;
187
+ constructor(db) {
188
+ this.db = db;
189
+ }
190
+ async getWebhooks(filters) {
191
+ const result = await this.db.find({
192
+ collection: WEBHOOK_COLLECTION,
193
+ where: filters?.status ? { status: { equals: filters.status } } : {},
194
+ limit: 100,
195
+ page: 1
196
+ });
197
+ const webhooks = result.docs;
198
+ if (filters?.event) {
199
+ return webhooks.filter(
200
+ (w) => w.events.includes(filters.event)
201
+ );
202
+ }
203
+ return webhooks;
204
+ }
205
+ async getWebhookById(id) {
206
+ return this.db.findByID({
207
+ collection: WEBHOOK_COLLECTION,
208
+ id
209
+ });
210
+ }
211
+ async createWebhook(data) {
212
+ const now = (/* @__PURE__ */ new Date()).toISOString();
213
+ const secret = data.secret || generateWebhookSecret();
214
+ const webhook = {
215
+ id: crypto.randomUUID(),
216
+ name: data.name,
217
+ url: data.url,
218
+ events: data.events,
219
+ status: data.status || "active",
220
+ secret,
221
+ headers: data.headers || {},
222
+ createdAt: now,
223
+ updatedAt: now
224
+ };
225
+ await this.db.create({
226
+ collection: WEBHOOK_COLLECTION,
227
+ data: webhook
228
+ });
229
+ return webhook;
230
+ }
231
+ async updateWebhook(id, data) {
232
+ const existing = await this.getWebhookById(id);
233
+ if (!existing) return null;
234
+ const updated = {
235
+ ...existing,
236
+ ...data,
237
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
238
+ };
239
+ if (data.secret === "" && "secret" in data) {
240
+ delete updated.secret;
241
+ }
242
+ await this.db.update({
243
+ collection: WEBHOOK_COLLECTION,
244
+ id,
245
+ data: updated
246
+ });
247
+ return updated;
248
+ }
249
+ async deleteWebhook(id) {
250
+ await this.db.delete({
251
+ collection: WEBHOOK_COLLECTION,
252
+ id
253
+ });
254
+ }
255
+ async trigger(event, payloadData) {
256
+ const webhooks = await this.getWebhooks();
257
+ const activeWebhooks = webhooks.filter((w) => w.status === "active");
258
+ const matchingWebhooks = activeWebhooks.filter(
259
+ (w) => w.events.includes(event)
260
+ );
261
+ if (matchingWebhooks.length === 0) {
262
+ return [];
263
+ }
264
+ const payload = {
265
+ id: `wh_${Date.now()}_${crypto.randomUUID().slice(0, 8)}`,
266
+ event,
267
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
268
+ ...payloadData
269
+ };
270
+ const results = [];
271
+ for (const webhook of matchingWebhooks) {
272
+ const result = await this.triggerWebhook(webhook, payload);
273
+ results.push(result);
274
+ }
275
+ return results;
276
+ }
277
+ async triggerWebhook(webhook, payload) {
278
+ const deliveryId = `dlv_${Date.now()}_${crypto.randomUUID().slice(0, 8)}`;
279
+ try {
280
+ const result = await deliverWithRetry(webhook, payload, deliveryId, {
281
+ maxRetries: 5,
282
+ retryDelay: 1e3
283
+ });
284
+ const deliveryRecord = buildDeliveryRecord(
285
+ deliveryId,
286
+ webhook.id,
287
+ webhook.events[0],
288
+ payload,
289
+ 1,
290
+ result
291
+ );
292
+ try {
293
+ await this.db.create({
294
+ collection: WEBHOOK_DELIVERY_COLLECTION,
295
+ data: deliveryRecord
296
+ });
297
+ } catch {
298
+ console.warn(
299
+ "[WebhookService] Failed to save delivery record:",
300
+ deliveryId
301
+ );
302
+ }
303
+ if (!result.success) {
304
+ await this.updateWebhook(webhook.id, {
305
+ status: "error",
306
+ lastError: result.error
307
+ }).catch(() => {
308
+ });
309
+ } else {
310
+ await this.updateWebhook(webhook.id, {
311
+ status: "active",
312
+ lastTriggered: (/* @__PURE__ */ new Date()).toISOString()
313
+ }).catch(() => {
314
+ });
315
+ }
316
+ return {
317
+ deliveryId,
318
+ webhookId: webhook.id,
319
+ event: webhook.events[0],
320
+ status: result.success ? "success" : "failed",
321
+ responseStatus: result.status,
322
+ duration: result.duration,
323
+ error: result.error
324
+ };
325
+ } catch (error) {
326
+ return {
327
+ deliveryId,
328
+ webhookId: webhook.id,
329
+ event: webhook.events[0],
330
+ status: "failed",
331
+ error: error.message
332
+ };
333
+ }
334
+ }
335
+ async testWebhook(webhookId) {
336
+ const webhook = await this.getWebhookById(webhookId);
337
+ if (!webhook) return null;
338
+ const payload = {
339
+ id: `test_${Date.now()}`,
340
+ event: webhook.events[0] || "collection.create",
341
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
342
+ collection: "test",
343
+ operation: "create",
344
+ data: { message: "This is a test webhook delivery from Kyro CMS" },
345
+ user: {
346
+ id: "system",
347
+ email: "system@kyro.dev",
348
+ role: "super_admin"
349
+ }
350
+ };
351
+ return this.triggerWebhook(webhook, payload);
352
+ }
353
+ async getDeliveryHistory(webhookId, limit = 50) {
354
+ const result = await this.db.find({
355
+ collection: WEBHOOK_DELIVERY_COLLECTION,
356
+ where: { webhookId: { equals: webhookId } },
357
+ sort: "-createdAt",
358
+ limit,
359
+ page: 1
360
+ });
361
+ return result.docs;
362
+ }
363
+ async retryDelivery(deliveryId) {
364
+ const delivery = await this.db.findByID({
365
+ collection: WEBHOOK_DELIVERY_COLLECTION,
366
+ id: deliveryId
367
+ });
368
+ if (!delivery) return null;
369
+ const webhook = await this.getWebhookById(delivery.webhookId);
370
+ if (!webhook) return null;
371
+ return this.triggerWebhook(webhook, delivery.payload);
372
+ }
373
+ };
374
+ function createWebhookService(db) {
375
+ return new WebhookService(db);
376
+ }
377
+ var API_KEY_COLLECTION = "_api_keys";
378
+ function generateKeyPrefix(key) {
379
+ return key.substring(0, 8);
380
+ }
381
+ function constantTimeCompare(a, b) {
382
+ if (a.length !== b.length) {
383
+ return false;
384
+ }
385
+ try {
386
+ return crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
387
+ } catch {
388
+ return false;
389
+ }
390
+ }
391
+ async function validateApiKey(rawKey, db, userLookup) {
392
+ if (!rawKey || typeof rawKey !== "string") {
393
+ return { valid: false, error: "No API key provided" };
394
+ }
395
+ if (!rawKey.startsWith("kyro_")) {
396
+ return { valid: false, error: "Invalid API key format" };
397
+ }
398
+ const keyPrefix = generateKeyPrefix(rawKey);
399
+ try {
400
+ const result = await db.find({
401
+ collection: API_KEY_COLLECTION,
402
+ where: { keyPrefix: { equals: keyPrefix } },
403
+ limit: 100,
404
+ page: 1
405
+ });
406
+ if (!result.docs || result.docs.length === 0) {
407
+ return { valid: false, error: "Invalid API key" };
408
+ }
409
+ let matchedKey = null;
410
+ for (const doc of result.docs) {
411
+ const record = doc;
412
+ if (constantTimeCompare(record.key, rawKey)) {
413
+ matchedKey = record;
414
+ break;
415
+ }
416
+ }
417
+ if (!matchedKey) {
418
+ return { valid: false, error: "Invalid API key" };
419
+ }
420
+ if (matchedKey.expiresAt) {
421
+ const expiresAt = new Date(matchedKey.expiresAt);
422
+ if (expiresAt < /* @__PURE__ */ new Date()) {
423
+ return { valid: false, error: "API key has expired" };
424
+ }
425
+ }
426
+ try {
427
+ await db.update({
428
+ collection: API_KEY_COLLECTION,
429
+ id: matchedKey.id,
430
+ data: { lastUsedAt: (/* @__PURE__ */ new Date()).toISOString() }
431
+ });
432
+ } catch {
433
+ }
434
+ const user = {
435
+ id: matchedKey.userId,
436
+ role: matchedKey.role || "author",
437
+ tenantId: matchedKey.tenantId
438
+ };
439
+ if (userLookup) {
440
+ const dbUser = await userLookup(matchedKey.userId);
441
+ if (dbUser) {
442
+ Object.assign(user, dbUser);
443
+ }
444
+ }
445
+ return {
446
+ valid: true,
447
+ userId: matchedKey.userId,
448
+ user,
449
+ permissions: matchedKey.permissions || [],
450
+ apiKeyId: matchedKey.id,
451
+ tenantId: user.tenantId,
452
+ role: user.role
453
+ };
454
+ } catch (error) {
455
+ console.error("[ApiKey] Validation error:", error);
456
+ return { valid: false, error: "Failed to validate API key" };
457
+ }
458
+ }
459
+ function extractApiKeyFromRequest(request) {
460
+ const authHeader = request.headers.get("Authorization");
461
+ if (authHeader) {
462
+ if (authHeader.startsWith("ApiKey ")) {
463
+ return authHeader.slice(7).trim();
464
+ }
465
+ if (authHeader.startsWith("Bearer ")) {
466
+ return null;
467
+ }
468
+ }
469
+ const xApiKey = request.headers.get("X-API-Key");
470
+ if (xApiKey) {
471
+ return xApiKey.trim();
472
+ }
473
+ return null;
474
+ }
475
+ function createApiKeyContext(result) {
476
+ if (!result.valid || !result.userId) {
477
+ return null;
478
+ }
479
+ return {
480
+ userId: result.userId,
481
+ user: result.user || {},
482
+ permissions: result.permissions || [],
483
+ apiKeyId: result.apiKeyId || "",
484
+ tenantId: result.tenantId,
485
+ role: result.role
486
+ };
487
+ }
488
+ function hasApiKeyPermission(permissions, required) {
489
+ if (permissions.length === 0) return false;
490
+ if (permissions.includes("*")) return true;
491
+ if (permissions.includes(required)) return true;
492
+ const [resource, action] = required.split(":");
493
+ if (permissions.includes(`${resource}:*`)) return true;
494
+ return false;
495
+ }
496
+
497
+ exports.ALL_WEBHOOK_EVENTS = ALL_WEBHOOK_EVENTS;
498
+ exports.WEBHOOK_COLLECTION = WEBHOOK_COLLECTION;
499
+ exports.WEBHOOK_DELIVERY_COLLECTION = WEBHOOK_DELIVERY_COLLECTION;
500
+ exports.WEBHOOK_EVENTS = WEBHOOK_EVENTS;
501
+ exports.WebhookService = WebhookService;
502
+ exports.buildDeliveryRecord = buildDeliveryRecord;
503
+ exports.createApiKeyContext = createApiKeyContext;
504
+ exports.createTestPayload = createTestPayload;
505
+ exports.createWebhookService = createWebhookService;
506
+ exports.deliverWebhook = deliverWebhook;
507
+ exports.deliverWithRetry = deliverWithRetry;
508
+ exports.evaluateAccess = evaluateAccess;
509
+ exports.extractApiKeyFromRequest = extractApiKeyFromRequest;
510
+ exports.generateWebhookSecret = generateWebhookSecret;
511
+ exports.getWhereClause = getWhereClause;
512
+ exports.hasApiKeyPermission = hasApiKeyPermission;
513
+ exports.mergeWhereClauses = mergeWhereClauses;
514
+ exports.signPayload = signPayload;
515
+ exports.validateApiKey = validateApiKey;
516
+ //# sourceMappingURL=chunk-VIONYQ2K.cjs.map
517
+ //# sourceMappingURL=chunk-VIONYQ2K.cjs.map