@kyro-cms/core 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -6
- package/dist/{WebhookService-Yg2UEOB4.d.cts → WebhookService-BKszZlG0.d.cts} +1 -1
- package/dist/{WebhookService-CUTb9XOy.d.ts → WebhookService-Ccf1j-IN.d.ts} +1 -1
- package/dist/api-handler-graphql.cjs +17 -17
- package/dist/api-handler-graphql.js +13 -13
- package/dist/api-handler-trpc.cjs +15 -15
- package/dist/api-handler-trpc.js +13 -13
- package/dist/api-handler.cjs +16 -16
- package/dist/api-handler.js +13 -13
- package/dist/{base-DaqY2GhA.d.ts → base-CIuXkrH4.d.cts} +3 -5
- package/dist/{base-B71y_EAF.d.cts → base-fFo4lqER.d.ts} +3 -5
- package/dist/bootstrap-3PV3GJ3S.js +7 -0
- package/dist/{bootstrap-T5BK77LD.js.map → bootstrap-3PV3GJ3S.js.map} +1 -1
- package/dist/bootstrap-4CELFLJO.cjs +32 -0
- package/dist/{bootstrap-5NLASFOG.cjs.map → bootstrap-4CELFLJO.cjs.map} +1 -1
- package/dist/{chunk-Z6ZWNWWR.js → chunk-4CV4JOE5.js} +3 -9
- package/dist/{chunk-Z6ZWNWWR.js.map → chunk-4CV4JOE5.js.map} +1 -1
- package/dist/{chunk-5EPFQUQD.js → chunk-53NYVYVX.js} +6 -6
- package/dist/chunk-53NYVYVX.js.map +1 -0
- package/dist/{chunk-22M4O4ZJ.js → chunk-5H3MWQJS.js} +129 -143
- package/dist/chunk-5H3MWQJS.js.map +1 -0
- package/dist/{chunk-RAMGUDJN.cjs → chunk-5PMQQFRE.cjs} +5 -5
- package/dist/{chunk-RAMGUDJN.cjs.map → chunk-5PMQQFRE.cjs.map} +1 -1
- package/dist/{chunk-TXSZFA4G.js → chunk-6UNONDW7.js} +93 -9
- package/dist/chunk-6UNONDW7.js.map +1 -0
- package/dist/{chunk-C36TMDTY.cjs → chunk-7OS7TX2Q.cjs} +49 -48
- package/dist/chunk-7OS7TX2Q.cjs.map +1 -0
- package/dist/{chunk-3TPQ2BU6.js → chunk-BYBMTIMT.js} +2 -6
- package/dist/chunk-BYBMTIMT.js.map +1 -0
- package/dist/{chunk-FOPGUM27.js → chunk-CJX74IYK.js} +5 -4
- package/dist/chunk-CJX74IYK.js.map +1 -0
- package/dist/{chunk-RSF3UU7H.cjs → chunk-CNKT4PME.cjs} +196 -200
- package/dist/chunk-CNKT4PME.cjs.map +1 -0
- package/dist/{chunk-G7VZBCD6.cjs → chunk-CZLDE2OZ.cjs} +2 -9
- package/dist/{chunk-G7VZBCD6.cjs.map → chunk-CZLDE2OZ.cjs.map} +1 -1
- package/dist/{chunk-JOPVMWTM.cjs → chunk-DPA3KWPY.cjs} +3 -3
- package/dist/chunk-DPA3KWPY.cjs.map +1 -0
- package/dist/{chunk-ROJHKAQ4.cjs → chunk-E2763JUP.cjs} +143 -157
- package/dist/chunk-E2763JUP.cjs.map +1 -0
- package/dist/{chunk-FAXU7BMP.js → chunk-E5UJBLQ7.js} +2 -2
- package/dist/chunk-E5UJBLQ7.js.map +1 -0
- package/dist/{chunk-DVD5P72E.cjs → chunk-EEJUFDMF.cjs} +2 -6
- package/dist/chunk-EEJUFDMF.cjs.map +1 -0
- package/dist/{chunk-2HZRBATX.cjs → chunk-FSKONGCX.cjs} +2 -2
- package/dist/chunk-FSKONGCX.cjs.map +1 -0
- package/dist/{chunk-P2HKJ7P5.js → chunk-GAAHG2Z4.js} +3 -3
- package/dist/{chunk-P2HKJ7P5.js.map → chunk-GAAHG2Z4.js.map} +1 -1
- package/dist/{chunk-PI73NNOK.cjs → chunk-GUUB5EAG.cjs} +2 -2
- package/dist/chunk-GUUB5EAG.cjs.map +1 -0
- package/dist/{chunk-PU2Z5VWF.js → chunk-IPTZM3VE.js} +183 -187
- package/dist/chunk-IPTZM3VE.js.map +1 -0
- package/dist/{chunk-UERVXYVK.cjs → chunk-NWUEVLQT.cjs} +13 -13
- package/dist/{chunk-UERVXYVK.cjs.map → chunk-NWUEVLQT.cjs.map} +1 -1
- package/dist/{chunk-KPA4AN4R.js → chunk-OHC6UHFY.js} +86 -12
- package/dist/chunk-OHC6UHFY.js.map +1 -0
- package/dist/{chunk-DEVFAKCQ.cjs → chunk-PHJRNPHY.cjs} +6 -6
- package/dist/chunk-PHJRNPHY.cjs.map +1 -0
- package/dist/{chunk-VO35MNPH.js → chunk-PQ72Z6WC.js} +67 -105
- package/dist/chunk-PQ72Z6WC.js.map +1 -0
- package/dist/{chunk-KNRSROWB.cjs → chunk-PV2I2KMI.cjs} +86 -12
- package/dist/chunk-PV2I2KMI.cjs.map +1 -0
- package/dist/{chunk-V2TVSCV5.cjs → chunk-Q23GAMLE.cjs} +71 -109
- package/dist/chunk-Q23GAMLE.cjs.map +1 -0
- package/dist/{chunk-COIASRDK.cjs → chunk-RFFSZSCL.cjs} +107 -171
- package/dist/chunk-RFFSZSCL.cjs.map +1 -0
- package/dist/{chunk-AL5KX63J.js → chunk-UUDTPZX6.js} +3 -3
- package/dist/chunk-UUDTPZX6.js.map +1 -0
- package/dist/{chunk-EJN2PAOE.js → chunk-V7KZQIZ6.js} +102 -166
- package/dist/chunk-V7KZQIZ6.js.map +1 -0
- package/dist/{chunk-DYTZ6FQ7.js → chunk-WXVB364T.js} +2 -2
- package/dist/chunk-WXVB364T.js.map +1 -0
- package/dist/{chunk-WNCYAKF3.cjs → chunk-Y7AQK4R4.cjs} +93 -9
- package/dist/chunk-Y7AQK4R4.cjs.map +1 -0
- package/dist/{chunk-SPBTLUN6.js → chunk-YFAVQQTU.js} +7 -7
- package/dist/{chunk-SPBTLUN6.js.map → chunk-YFAVQQTU.js.map} +1 -1
- package/dist/cli/index.cjs +5 -5
- package/dist/cli/index.js +5 -5
- package/dist/client.cjs +4 -4
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -2
- package/dist/drizzle/index.cjs +14 -14
- package/dist/drizzle/index.d.cts +4 -10
- package/dist/drizzle/index.d.ts +4 -10
- package/dist/drizzle/index.js +5 -5
- package/dist/fields/index.cjs +22 -22
- package/dist/fields/index.d.cts +1 -1
- package/dist/fields/index.d.ts +1 -1
- package/dist/fields/index.js +2 -2
- package/dist/graphql/index.cjs +1 -1
- package/dist/graphql/index.d.cts +3 -3
- package/dist/graphql/index.d.ts +3 -3
- package/dist/graphql/index.js +1 -1
- package/dist/{index-CaTNnLGd.d.cts → index-BKta3cBH.d.cts} +3 -2
- package/dist/{index-CJXPB_ot.d.ts → index-ClOqnkTO.d.ts} +3 -2
- package/dist/index.cjs +117 -117
- package/dist/index.d.cts +10 -15
- package/dist/index.d.ts +10 -15
- package/dist/index.js +18 -18
- package/dist/integration.cjs +1 -1
- package/dist/integration.js +1 -1
- package/dist/media-7WDX4BDJ.js +4 -0
- package/dist/{media-GPPTZ43E.js.map → media-7WDX4BDJ.js.map} +1 -1
- package/dist/{media-XNTUFJZR.cjs → media-TUSLVRQ6.cjs} +3 -3
- package/dist/{media-XNTUFJZR.cjs.map → media-TUSLVRQ6.cjs.map} +1 -1
- package/dist/{mongo-auth-adapter-ISOM7FSS.cjs → mongo-auth-adapter-GT4S7SCU.cjs} +3 -3
- package/dist/{mongo-auth-adapter-ISOM7FSS.cjs.map → mongo-auth-adapter-GT4S7SCU.cjs.map} +1 -1
- package/dist/mongo-auth-adapter-M7VV4LNB.js +4 -0
- package/dist/{mongo-auth-adapter-MO6STCV3.js.map → mongo-auth-adapter-M7VV4LNB.js.map} +1 -1
- package/dist/mongodb/index.cjs +5 -5
- package/dist/mongodb/index.d.cts +4 -9
- package/dist/mongodb/index.d.ts +4 -9
- package/dist/mongodb/index.js +3 -3
- package/dist/postgres-auth-adapter-AFAPISH7.js +5 -0
- package/dist/{postgres-auth-adapter-DWDR7P5G.js.map → postgres-auth-adapter-AFAPISH7.js.map} +1 -1
- package/dist/postgres-auth-adapter-SFDTLONT.cjs +14 -0
- package/dist/{postgres-auth-adapter-WRWSJD4E.cjs.map → postgres-auth-adapter-SFDTLONT.cjs.map} +1 -1
- package/dist/{redis-adapter-KJ3YOOT6.cjs → redis-adapter-UQX4EE3B.cjs} +3 -3
- package/dist/{redis-adapter-KJ3YOOT6.cjs.map → redis-adapter-UQX4EE3B.cjs.map} +1 -1
- package/dist/redis-adapter-XALOGWY3.js +4 -0
- package/dist/{redis-adapter-HGTPWIGV.js.map → redis-adapter-XALOGWY3.js.map} +1 -1
- package/dist/rest/index.cjs +10 -10
- package/dist/rest/index.d.cts +4 -4
- package/dist/rest/index.d.ts +4 -4
- package/dist/rest/index.js +8 -8
- package/dist/{schema-TTFE4467.cjs → schema-6QL3USNB.cjs} +15 -15
- package/dist/{schema-TTFE4467.cjs.map → schema-6QL3USNB.cjs.map} +1 -1
- package/dist/{schema-6I5OFR4Z.js → schema-FNNWEAAW.js} +4 -4
- package/dist/{schema-6I5OFR4Z.js.map → schema-FNNWEAAW.js.map} +1 -1
- package/dist/{sqlite-adapter-CSIZE5SX.cjs → sqlite-adapter-AQB5TCGV.cjs} +3 -3
- package/dist/{sqlite-adapter-CSIZE5SX.cjs.map → sqlite-adapter-AQB5TCGV.cjs.map} +1 -1
- package/dist/sqlite-adapter-N5H6IM2X.js +4 -0
- package/dist/{sqlite-adapter-6GEUSVXQ.js.map → sqlite-adapter-N5H6IM2X.js.map} +1 -1
- package/dist/templates/index.cjs +49 -49
- package/dist/templates/index.d.cts +2 -2
- package/dist/templates/index.d.ts +2 -2
- package/dist/templates/index.js +2 -2
- package/dist/trpc/index.cjs +11 -11
- package/dist/trpc/index.d.cts +3 -3
- package/dist/trpc/index.d.ts +3 -3
- package/dist/trpc/index.js +2 -2
- package/dist/{types-Z6FBiqa2.d.cts → types-DeSApf9T.d.cts} +1 -0
- package/dist/{types-Z6FBiqa2.d.ts → types-DeSApf9T.d.ts} +1 -0
- package/dist/{types-CyCQ6SAI.d.ts → types-Dgzlftb7.d.ts} +6 -28
- package/dist/{types-DJxD9394.d.cts → types-Ds0tCA3L.d.cts} +6 -28
- package/dist/ws/index.cjs +6 -6
- package/dist/ws/index.js +2 -2
- package/package.json +1 -1
- package/dist/bootstrap-5NLASFOG.cjs +0 -32
- package/dist/bootstrap-T5BK77LD.js +0 -7
- package/dist/chunk-22M4O4ZJ.js.map +0 -1
- package/dist/chunk-2HZRBATX.cjs.map +0 -1
- package/dist/chunk-3TPQ2BU6.js.map +0 -1
- package/dist/chunk-5EPFQUQD.js.map +0 -1
- package/dist/chunk-AL5KX63J.js.map +0 -1
- package/dist/chunk-C36TMDTY.cjs.map +0 -1
- package/dist/chunk-COIASRDK.cjs.map +0 -1
- package/dist/chunk-DEVFAKCQ.cjs.map +0 -1
- package/dist/chunk-DVD5P72E.cjs.map +0 -1
- package/dist/chunk-DYTZ6FQ7.js.map +0 -1
- package/dist/chunk-EJN2PAOE.js.map +0 -1
- package/dist/chunk-FAXU7BMP.js.map +0 -1
- package/dist/chunk-FOPGUM27.js.map +0 -1
- package/dist/chunk-JOPVMWTM.cjs.map +0 -1
- package/dist/chunk-KNRSROWB.cjs.map +0 -1
- package/dist/chunk-KPA4AN4R.js.map +0 -1
- package/dist/chunk-PI73NNOK.cjs.map +0 -1
- package/dist/chunk-PU2Z5VWF.js.map +0 -1
- package/dist/chunk-ROJHKAQ4.cjs.map +0 -1
- package/dist/chunk-RSF3UU7H.cjs.map +0 -1
- package/dist/chunk-TXSZFA4G.js.map +0 -1
- package/dist/chunk-V2TVSCV5.cjs.map +0 -1
- package/dist/chunk-VO35MNPH.js.map +0 -1
- package/dist/chunk-WNCYAKF3.cjs.map +0 -1
- package/dist/media-GPPTZ43E.js +0 -4
- package/dist/mongo-auth-adapter-MO6STCV3.js +0 -4
- package/dist/postgres-auth-adapter-DWDR7P5G.js +0 -5
- package/dist/postgres-auth-adapter-WRWSJD4E.cjs +0 -14
- package/dist/redis-adapter-HGTPWIGV.js +0 -4
- package/dist/sqlite-adapter-6GEUSVXQ.js +0 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkDPA3KWPY_cjs = require('./chunk-DPA3KWPY.cjs');
|
|
4
4
|
var drizzleOrm = require('drizzle-orm');
|
|
5
5
|
var bcrypt = require('bcryptjs');
|
|
6
6
|
var crypto$1 = require('crypto');
|
|
@@ -68,7 +68,7 @@ var PostgresAuthAdapter = class {
|
|
|
68
68
|
"user_email" VARCHAR(255),
|
|
69
69
|
"role" VARCHAR(50),
|
|
70
70
|
"resource" VARCHAR(100) NOT NULL,
|
|
71
|
-
"resource_id"
|
|
71
|
+
"resource_id" VARCHAR(255),
|
|
72
72
|
"changes" JSONB,
|
|
73
73
|
"ip_address" VARCHAR(45),
|
|
74
74
|
"user_agent" TEXT,
|
|
@@ -78,6 +78,7 @@ var PostgresAuthAdapter = class {
|
|
|
78
78
|
"timestamp" TIMESTAMP NOT NULL DEFAULT NOW()
|
|
79
79
|
)
|
|
80
80
|
`);
|
|
81
|
+
await this.db.execute(drizzleOrm.sql`ALTER TABLE "audit_logs" ALTER COLUMN "resource_id" TYPE VARCHAR(255)`);
|
|
81
82
|
await this.db.execute(drizzleOrm.sql`CREATE INDEX IF NOT EXISTS "audit_logs_user_idx" ON "audit_logs" ("user_id")`);
|
|
82
83
|
await this.db.execute(drizzleOrm.sql`CREATE INDEX IF NOT EXISTS "audit_logs_action_idx" ON "audit_logs" ("action")`);
|
|
83
84
|
await this.db.execute(drizzleOrm.sql`CREATE INDEX IF NOT EXISTS "audit_logs_resource_idx" ON "audit_logs" ("resource")`);
|
|
@@ -167,7 +168,7 @@ var PostgresAuthAdapter = class {
|
|
|
167
168
|
}
|
|
168
169
|
async createUser(data) {
|
|
169
170
|
const passwordHash = await this.hashPassword(data.password);
|
|
170
|
-
const [user] = await this.db.insert(
|
|
171
|
+
const [user] = await this.db.insert(chunkDPA3KWPY_cjs.users).values({
|
|
171
172
|
email: data.email.toLowerCase(),
|
|
172
173
|
name: data.name,
|
|
173
174
|
passwordHash,
|
|
@@ -178,11 +179,11 @@ var PostgresAuthAdapter = class {
|
|
|
178
179
|
return this.userToAuthUser(user);
|
|
179
180
|
}
|
|
180
181
|
async findUserByEmail(email) {
|
|
181
|
-
const [user] = await this.db.select().from(
|
|
182
|
+
const [user] = await this.db.select().from(chunkDPA3KWPY_cjs.users).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.users.email, email.toLowerCase())).limit(1);
|
|
182
183
|
return user ? this.userToAuthUser(user) : null;
|
|
183
184
|
}
|
|
184
185
|
async findUserById(id) {
|
|
185
|
-
const [user] = await this.db.select().from(
|
|
186
|
+
const [user] = await this.db.select().from(chunkDPA3KWPY_cjs.users).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.users.id, id)).limit(1);
|
|
186
187
|
return user ? this.userToAuthUser(user) : null;
|
|
187
188
|
}
|
|
188
189
|
async updateUser(id, data) {
|
|
@@ -201,11 +202,11 @@ var PostgresAuthAdapter = class {
|
|
|
201
202
|
dbData.lastLogin = data.lastLogin ? new Date(data.lastLogin) : null;
|
|
202
203
|
if (data.failedLoginAttempts !== void 0)
|
|
203
204
|
dbData.failedLoginAttempts = data.failedLoginAttempts;
|
|
204
|
-
const [user] = await this.db.update(
|
|
205
|
+
const [user] = await this.db.update(chunkDPA3KWPY_cjs.users).set(dbData).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.users.id, id)).returning();
|
|
205
206
|
return user ? this.userToAuthUser(user) : null;
|
|
206
207
|
}
|
|
207
208
|
async deleteUser(id) {
|
|
208
|
-
await this.db.delete(
|
|
209
|
+
await this.db.delete(chunkDPA3KWPY_cjs.users).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.users.id, id));
|
|
209
210
|
return true;
|
|
210
211
|
}
|
|
211
212
|
async findUsers(options = {}) {
|
|
@@ -216,8 +217,8 @@ var PostgresAuthAdapter = class {
|
|
|
216
217
|
if (search) {
|
|
217
218
|
const pattern = `%${search}%`;
|
|
218
219
|
const [rows2, [{ count: count2 }]] = await Promise.all([
|
|
219
|
-
this.db.select().from(
|
|
220
|
-
this.db.select({ count: drizzleOrm.sql`count(*)` }).from(
|
|
220
|
+
this.db.select().from(chunkDPA3KWPY_cjs.users).where(drizzleOrm.sql`${chunkDPA3KWPY_cjs.users.email} ILIKE ${pattern}`).orderBy(drizzleOrm.desc(chunkDPA3KWPY_cjs.users.createdAt)).limit(limit).offset(offset),
|
|
221
|
+
this.db.select({ count: drizzleOrm.sql`count(*)` }).from(chunkDPA3KWPY_cjs.users).where(drizzleOrm.sql`${chunkDPA3KWPY_cjs.users.email} ILIKE ${pattern}`)
|
|
221
222
|
]);
|
|
222
223
|
return {
|
|
223
224
|
users: rows2.map((r) => this.userToAuthUser(r)),
|
|
@@ -225,8 +226,8 @@ var PostgresAuthAdapter = class {
|
|
|
225
226
|
};
|
|
226
227
|
}
|
|
227
228
|
const [rows, [{ count }]] = await Promise.all([
|
|
228
|
-
this.db.select().from(
|
|
229
|
-
this.db.select({ count: drizzleOrm.sql`count(*)` }).from(
|
|
229
|
+
this.db.select().from(chunkDPA3KWPY_cjs.users).orderBy(drizzleOrm.desc(chunkDPA3KWPY_cjs.users.createdAt)).limit(limit).offset(offset),
|
|
230
|
+
this.db.select({ count: drizzleOrm.sql`count(*)` }).from(chunkDPA3KWPY_cjs.users)
|
|
230
231
|
]);
|
|
231
232
|
return {
|
|
232
233
|
users: rows.map((r) => this.userToAuthUser(r)),
|
|
@@ -236,7 +237,7 @@ var PostgresAuthAdapter = class {
|
|
|
236
237
|
async verifyPassword(email, password) {
|
|
237
238
|
const user = await this.findUserByEmail(email);
|
|
238
239
|
if (!user) return null;
|
|
239
|
-
const [stored] = await this.db.select().from(
|
|
240
|
+
const [stored] = await this.db.select().from(chunkDPA3KWPY_cjs.users).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.users.email, email.toLowerCase())).limit(1);
|
|
240
241
|
if (!stored?.passwordHash) return null;
|
|
241
242
|
const valid = await bcrypt__default.default.compare(password, stored.passwordHash);
|
|
242
243
|
return valid ? user : null;
|
|
@@ -249,7 +250,7 @@ var PostgresAuthAdapter = class {
|
|
|
249
250
|
const refreshToken = crypto$1.randomBytes(32).toString("base64url");
|
|
250
251
|
const expiresAt = new Date(Date.now() + this.sessionTTL * 1e3);
|
|
251
252
|
new Date(Date.now() + this.refreshTokenTTL * 1e3);
|
|
252
|
-
const [session] = await this.db.insert(
|
|
253
|
+
const [session] = await this.db.insert(chunkDPA3KWPY_cjs.sessions).values({
|
|
253
254
|
userId,
|
|
254
255
|
token,
|
|
255
256
|
refreshToken,
|
|
@@ -260,34 +261,34 @@ var PostgresAuthAdapter = class {
|
|
|
260
261
|
return this.sessionToSession(session);
|
|
261
262
|
}
|
|
262
263
|
async findSessionByToken(token) {
|
|
263
|
-
const [session] = await this.db.select().from(
|
|
264
|
+
const [session] = await this.db.select().from(chunkDPA3KWPY_cjs.sessions).where(drizzleOrm.and(drizzleOrm.eq(chunkDPA3KWPY_cjs.sessions.token, token), drizzleOrm.gt(chunkDPA3KWPY_cjs.sessions.expiresAt, /* @__PURE__ */ new Date()))).limit(1);
|
|
264
265
|
return session ? this.sessionToSession(session) : null;
|
|
265
266
|
}
|
|
266
267
|
async findSessionByRefreshToken(refreshToken) {
|
|
267
|
-
const [session] = await this.db.select().from(
|
|
268
|
+
const [session] = await this.db.select().from(chunkDPA3KWPY_cjs.sessions).where(
|
|
268
269
|
drizzleOrm.and(
|
|
269
|
-
drizzleOrm.eq(
|
|
270
|
-
drizzleOrm.gt(
|
|
270
|
+
drizzleOrm.eq(chunkDPA3KWPY_cjs.sessions.refreshToken, refreshToken),
|
|
271
|
+
drizzleOrm.gt(chunkDPA3KWPY_cjs.sessions.expiresAt, /* @__PURE__ */ new Date())
|
|
271
272
|
)
|
|
272
273
|
).limit(1);
|
|
273
274
|
return session ? this.sessionToSession(session) : null;
|
|
274
275
|
}
|
|
275
276
|
async deleteSession(sessionId) {
|
|
276
|
-
await this.db.delete(
|
|
277
|
+
await this.db.delete(chunkDPA3KWPY_cjs.sessions).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.sessions.id, sessionId));
|
|
277
278
|
return true;
|
|
278
279
|
}
|
|
279
280
|
async deleteUserSessions(userId) {
|
|
280
|
-
await this.db.delete(
|
|
281
|
+
await this.db.delete(chunkDPA3KWPY_cjs.sessions).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.sessions.userId, userId));
|
|
281
282
|
return 1;
|
|
282
283
|
}
|
|
283
284
|
async addPasswordToHistory(userId, passwordHash) {
|
|
284
|
-
await this.db.insert(
|
|
285
|
+
await this.db.insert(chunkDPA3KWPY_cjs.passwordHistory).values({
|
|
285
286
|
userId,
|
|
286
287
|
passwordHash
|
|
287
288
|
});
|
|
288
289
|
}
|
|
289
290
|
async getPasswordHistory(userId, count = 5) {
|
|
290
|
-
const history = await this.db.select({ passwordHash:
|
|
291
|
+
const history = await this.db.select({ passwordHash: chunkDPA3KWPY_cjs.passwordHistory.passwordHash }).from(chunkDPA3KWPY_cjs.passwordHistory).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.passwordHistory.userId, userId)).orderBy(drizzleOrm.desc(chunkDPA3KWPY_cjs.passwordHistory.createdAt)).limit(count);
|
|
291
292
|
return history.map((h) => h.passwordHash);
|
|
292
293
|
}
|
|
293
294
|
async isPasswordInHistory(password, userId, historyCount = 5) {
|
|
@@ -300,14 +301,14 @@ var PostgresAuthAdapter = class {
|
|
|
300
301
|
return false;
|
|
301
302
|
}
|
|
302
303
|
async isLocked(userId) {
|
|
303
|
-
const [lockout] = await this.db.select().from(
|
|
304
|
-
drizzleOrm.and(drizzleOrm.eq(
|
|
304
|
+
const [lockout] = await this.db.select().from(chunkDPA3KWPY_cjs.lockouts).where(
|
|
305
|
+
drizzleOrm.and(drizzleOrm.eq(chunkDPA3KWPY_cjs.lockouts.userId, userId), drizzleOrm.gt(chunkDPA3KWPY_cjs.lockouts.lockedUntil, /* @__PURE__ */ new Date()))
|
|
305
306
|
).limit(1);
|
|
306
307
|
return !!lockout;
|
|
307
308
|
}
|
|
308
309
|
async getLockout(userId) {
|
|
309
|
-
const [lockout] = await this.db.select().from(
|
|
310
|
-
drizzleOrm.and(drizzleOrm.eq(
|
|
310
|
+
const [lockout] = await this.db.select().from(chunkDPA3KWPY_cjs.lockouts).where(
|
|
311
|
+
drizzleOrm.and(drizzleOrm.eq(chunkDPA3KWPY_cjs.lockouts.userId, userId), drizzleOrm.gt(chunkDPA3KWPY_cjs.lockouts.lockedUntil, /* @__PURE__ */ new Date()))
|
|
311
312
|
).limit(1);
|
|
312
313
|
return lockout ? { lockedUntil: lockout.lockedUntil } : null;
|
|
313
314
|
}
|
|
@@ -319,7 +320,7 @@ var PostgresAuthAdapter = class {
|
|
|
319
320
|
const locked = attempts >= maxAttempts;
|
|
320
321
|
if (locked) {
|
|
321
322
|
const lockoutDuration = 15 * 60 * 1e3;
|
|
322
|
-
await this.db.insert(
|
|
323
|
+
await this.db.insert(chunkDPA3KWPY_cjs.lockouts).values({
|
|
323
324
|
userId,
|
|
324
325
|
ipAddress,
|
|
325
326
|
reason: "Too many failed login attempts",
|
|
@@ -344,22 +345,22 @@ var PostgresAuthAdapter = class {
|
|
|
344
345
|
endDate
|
|
345
346
|
} = filter;
|
|
346
347
|
const conditions = [];
|
|
347
|
-
if (userId) conditions.push(drizzleOrm.eq(
|
|
348
|
+
if (userId) conditions.push(drizzleOrm.eq(chunkDPA3KWPY_cjs.auditLogs.userId, userId));
|
|
348
349
|
if (action) {
|
|
349
350
|
if (Array.isArray(action)) {
|
|
350
|
-
conditions.push(drizzleOrm.sql`${
|
|
351
|
+
conditions.push(drizzleOrm.sql`${chunkDPA3KWPY_cjs.auditLogs.action} = ANY(${action})`);
|
|
351
352
|
} else {
|
|
352
|
-
conditions.push(drizzleOrm.eq(
|
|
353
|
+
conditions.push(drizzleOrm.eq(chunkDPA3KWPY_cjs.auditLogs.action, action));
|
|
353
354
|
}
|
|
354
355
|
}
|
|
355
|
-
if (resource) conditions.push(drizzleOrm.eq(
|
|
356
|
-
if (resourceId) conditions.push(drizzleOrm.eq(
|
|
357
|
-
if (success !== void 0) conditions.push(drizzleOrm.eq(
|
|
358
|
-
if (startDate) conditions.push(drizzleOrm.sql`${
|
|
359
|
-
if (endDate) conditions.push(drizzleOrm.sql`${
|
|
356
|
+
if (resource) conditions.push(drizzleOrm.eq(chunkDPA3KWPY_cjs.auditLogs.resource, resource));
|
|
357
|
+
if (resourceId) conditions.push(drizzleOrm.eq(chunkDPA3KWPY_cjs.auditLogs.resourceId, resourceId));
|
|
358
|
+
if (success !== void 0) conditions.push(drizzleOrm.eq(chunkDPA3KWPY_cjs.auditLogs.success, success));
|
|
359
|
+
if (startDate) conditions.push(drizzleOrm.sql`${chunkDPA3KWPY_cjs.auditLogs.timestamp} >= ${startDate}`);
|
|
360
|
+
if (endDate) conditions.push(drizzleOrm.sql`${chunkDPA3KWPY_cjs.auditLogs.timestamp} <= ${endDate}`);
|
|
360
361
|
const whereClause = conditions.length > 0 ? drizzleOrm.and(...conditions) : void 0;
|
|
361
|
-
const countResult = await this.db.select({ count: drizzleOrm.sql`count(*)` }).from(
|
|
362
|
-
const logs = await this.db.select().from(
|
|
362
|
+
const countResult = await this.db.select({ count: drizzleOrm.sql`count(*)` }).from(chunkDPA3KWPY_cjs.auditLogs).where(whereClause);
|
|
363
|
+
const logs = await this.db.select().from(chunkDPA3KWPY_cjs.auditLogs).where(whereClause).orderBy(drizzleOrm.desc(chunkDPA3KWPY_cjs.auditLogs.timestamp)).limit(limit).offset(offset);
|
|
363
364
|
return {
|
|
364
365
|
logs: logs.map((log) => ({
|
|
365
366
|
id: log.id,
|
|
@@ -383,7 +384,7 @@ var PostgresAuthAdapter = class {
|
|
|
383
384
|
async createAuditLog(data) {
|
|
384
385
|
const id = crypto.randomUUID();
|
|
385
386
|
const timestamp = /* @__PURE__ */ new Date();
|
|
386
|
-
await this.db.insert(
|
|
387
|
+
await this.db.insert(chunkDPA3KWPY_cjs.auditLogs).values({
|
|
387
388
|
id,
|
|
388
389
|
action: data.action,
|
|
389
390
|
userId: data.userId ?? null,
|
|
@@ -437,7 +438,7 @@ var PostgresAuthAdapter = class {
|
|
|
437
438
|
async createEmailVerificationToken(userId) {
|
|
438
439
|
const token = crypto$1.randomBytes(32).toString("hex");
|
|
439
440
|
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1e3);
|
|
440
|
-
await this.db.insert(
|
|
441
|
+
await this.db.insert(chunkDPA3KWPY_cjs.emailVerifications).values({
|
|
441
442
|
userId,
|
|
442
443
|
token,
|
|
443
444
|
expiresAt
|
|
@@ -445,15 +446,15 @@ var PostgresAuthAdapter = class {
|
|
|
445
446
|
return { token, expiresAt };
|
|
446
447
|
}
|
|
447
448
|
async verifyEmailToken(token) {
|
|
448
|
-
const [verification] = await this.db.select().from(
|
|
449
|
+
const [verification] = await this.db.select().from(chunkDPA3KWPY_cjs.emailVerifications).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.emailVerifications.token, token)).limit(1);
|
|
449
450
|
if (!verification) {
|
|
450
451
|
return { success: false, error: "Invalid verification token" };
|
|
451
452
|
}
|
|
452
453
|
if (verification.expiresAt < /* @__PURE__ */ new Date()) {
|
|
453
454
|
return { success: false, error: "Verification token has expired" };
|
|
454
455
|
}
|
|
455
|
-
await this.db.update(
|
|
456
|
-
await this.db.delete(
|
|
456
|
+
await this.db.update(chunkDPA3KWPY_cjs.users).set({ emailVerified: true }).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.users.id, verification.userId));
|
|
457
|
+
await this.db.delete(chunkDPA3KWPY_cjs.emailVerifications).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.emailVerifications.id, verification.id));
|
|
457
458
|
return { success: true, userId: verification.userId };
|
|
458
459
|
}
|
|
459
460
|
async createPasswordResetToken(email) {
|
|
@@ -463,7 +464,7 @@ var PostgresAuthAdapter = class {
|
|
|
463
464
|
}
|
|
464
465
|
const token = crypto$1.randomBytes(32).toString("hex");
|
|
465
466
|
const expiresAt = new Date(Date.now() + 60 * 60 * 1e3);
|
|
466
|
-
await this.db.insert(
|
|
467
|
+
await this.db.insert(chunkDPA3KWPY_cjs.passwordResets).values({
|
|
467
468
|
userId: user.id,
|
|
468
469
|
token,
|
|
469
470
|
expiresAt
|
|
@@ -471,7 +472,7 @@ var PostgresAuthAdapter = class {
|
|
|
471
472
|
return { token, expiresAt };
|
|
472
473
|
}
|
|
473
474
|
async resetPasswordWithToken(token, newPassword) {
|
|
474
|
-
const [reset] = await this.db.select().from(
|
|
475
|
+
const [reset] = await this.db.select().from(chunkDPA3KWPY_cjs.passwordResets).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.passwordResets.token, token)).limit(1);
|
|
475
476
|
if (!reset) {
|
|
476
477
|
return { success: false, error: "Invalid reset token" };
|
|
477
478
|
}
|
|
@@ -482,13 +483,13 @@ var PostgresAuthAdapter = class {
|
|
|
482
483
|
return { success: false, error: "Reset token has already been used" };
|
|
483
484
|
}
|
|
484
485
|
const passwordHash = await this.hashPassword(newPassword);
|
|
485
|
-
await this.db.update(
|
|
486
|
-
await this.db.update(
|
|
487
|
-
await this.db.delete(
|
|
486
|
+
await this.db.update(chunkDPA3KWPY_cjs.users).set({ passwordHash, updatedAt: /* @__PURE__ */ new Date() }).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.users.id, reset.userId));
|
|
487
|
+
await this.db.update(chunkDPA3KWPY_cjs.passwordResets).set({ usedAt: /* @__PURE__ */ new Date() }).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.passwordResets.id, reset.id));
|
|
488
|
+
await this.db.delete(chunkDPA3KWPY_cjs.sessions).where(drizzleOrm.eq(chunkDPA3KWPY_cjs.sessions.userId, reset.userId));
|
|
488
489
|
return { success: true };
|
|
489
490
|
}
|
|
490
491
|
};
|
|
491
492
|
|
|
492
493
|
exports.PostgresAuthAdapter = PostgresAuthAdapter;
|
|
493
|
-
//# sourceMappingURL=chunk-
|
|
494
|
-
//# sourceMappingURL=chunk-
|
|
494
|
+
//# sourceMappingURL=chunk-7OS7TX2Q.cjs.map
|
|
495
|
+
//# sourceMappingURL=chunk-7OS7TX2Q.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/database/drizzle/postgres-auth-adapter.ts"],"names":["sql","users","eq","rows","count","desc","bcrypt","randomBytes","sessions","and","gt","passwordHistory","lockouts","auditLogs","emailVerifications","passwordResets"],"mappings":"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","file":"chunk-7OS7TX2Q.cjs","sourcesContent":["import type { PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport { eq, and, gt, desc, sql } from \"drizzle-orm\";\nimport bcrypt from \"bcryptjs\";\nimport { randomBytes, randomUUID } 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 roles,\n permissions,\n tenants,\n apiKeys,\n emailVerifications,\n passwordResets,\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\nlet _tablesEnsured = false;\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 connect(): Promise<void> {\n if (_tablesEnsured) return;\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"users\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"name\" VARCHAR(255),\n \"email\" VARCHAR(255) NOT NULL,\n \"password_hash\" VARCHAR(255),\n \"role\" VARCHAR(50) NOT NULL DEFAULT 'customer',\n \"tenant_id\" UUID,\n \"email_verified\" BOOLEAN DEFAULT false,\n \"locked\" BOOLEAN DEFAULT false,\n \"last_login\" TIMESTAMP,\n \"failed_login_attempts\" INTEGER DEFAULT 0,\n \"metadata\" JSONB,\n \"avatar\" VARCHAR(255),\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW(),\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`ALTER TABLE \"users\" ADD COLUMN IF NOT EXISTS \"avatar\" VARCHAR(255)`);\n await this.db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS \"users_email_idx\" ON \"users\" (\"email\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"users_tenant_idx\" ON \"users\" (\"tenant_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"users_role_idx\" ON \"users\" (\"role\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"sessions\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"token\" VARCHAR(512) NOT NULL UNIQUE,\n \"refresh_token\" VARCHAR(512),\n \"ip_address\" VARCHAR(45),\n \"user_agent\" TEXT,\n \"expires_at\" TIMESTAMP NOT NULL,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"sessions_user_idx\" ON \"sessions\" (\"user_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"sessions_token_idx\" ON \"sessions\" (\"token\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"sessions_expires_idx\" ON \"sessions\" (\"expires_at\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"audit_logs\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"action\" VARCHAR(100) NOT NULL,\n \"user_id\" UUID REFERENCES \"users\"(\"id\") ON DELETE SET NULL,\n \"user_email\" VARCHAR(255),\n \"role\" VARCHAR(50),\n \"resource\" VARCHAR(100) NOT NULL,\n \"resource_id\" VARCHAR(255),\n \"changes\" JSONB,\n \"ip_address\" VARCHAR(45),\n \"user_agent\" TEXT,\n \"success\" BOOLEAN NOT NULL DEFAULT true,\n \"error\" TEXT,\n \"metadata\" JSONB,\n \"timestamp\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`ALTER TABLE \"audit_logs\" ALTER COLUMN \"resource_id\" TYPE VARCHAR(255)`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_user_idx\" ON \"audit_logs\" (\"user_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_action_idx\" ON \"audit_logs\" (\"action\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_resource_idx\" ON \"audit_logs\" (\"resource\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_timestamp_idx\" ON \"audit_logs\" (\"timestamp\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"password_history\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"password_hash\" VARCHAR(255) NOT NULL,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"password_history_user_idx\" ON \"password_history\" (\"user_id\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"lockouts\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"ip_address\" VARCHAR(45),\n \"reason\" VARCHAR(255),\n \"locked_until\" TIMESTAMP NOT NULL,\n \"released_at\" TIMESTAMP,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"lockouts_user_idx\" ON \"lockouts\" (\"user_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"lockouts_locked_until_idx\" ON \"lockouts\" (\"locked_until\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"roles\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"name\" VARCHAR(100) NOT NULL UNIQUE,\n \"level\" INTEGER NOT NULL DEFAULT 0,\n \"inherits\" TEXT[],\n \"description\" TEXT,\n \"permissions\" JSONB DEFAULT '[]',\n \"is_system\" BOOLEAN DEFAULT false,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW(),\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"roles_level_idx\" ON \"roles\" (\"level\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"tenants\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"name\" VARCHAR(255) NOT NULL,\n \"slug\" VARCHAR(100) NOT NULL UNIQUE,\n \"settings\" JSONB DEFAULT '{}',\n \"is_active\" BOOLEAN DEFAULT true,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW(),\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"api_keys\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"name\" VARCHAR(255) NOT NULL,\n \"key\" VARCHAR(64) NOT NULL UNIQUE,\n \"key_prefix\" VARCHAR(8) NOT NULL,\n \"permissions\" JSONB DEFAULT '[]',\n \"last_used_at\" TIMESTAMP,\n \"expires_at\" TIMESTAMP,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"email_verifications\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"token\" VARCHAR(64) NOT NULL UNIQUE,\n \"expires_at\" TIMESTAMP NOT NULL,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"password_resets\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"token\" VARCHAR(64) NOT NULL UNIQUE,\n \"expires_at\" TIMESTAMP NOT NULL,\n \"used_at\" TIMESTAMP,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n _tablesEnsured = true;\n }\n\n async disconnect(): Promise<void> {\n }\n\n async createUser(data: {\n email: string;\n password: string;\n name?: string;\n role?: UserRole;\n avatar?: string;\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 name: data.name,\n passwordHash,\n role: (data.role || \"customer\") as string,\n avatar: data.avatar,\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.name !== undefined) dbData.name = data.name;\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.avatar !== undefined) dbData.avatar = data.avatar;\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 findUsers(\n options: {\n page?: number;\n limit?: number;\n search?: string;\n } = {},\n ): Promise<{ users: AuthUser[]; total: number }> {\n const page = options.page ?? 1;\n const limit = options.limit ?? 10;\n const offset = (page - 1) * limit;\n const search = options.search;\n\n if (search) {\n const pattern = `%${search}%`;\n const [rows, [{ count }]] = await Promise.all([\n this.db\n .select()\n .from(users)\n .where(sql`${users.email} ILIKE ${pattern}`)\n .orderBy(desc(users.createdAt))\n .limit(limit)\n .offset(offset),\n this.db\n .select({ count: sql<number>`count(*)` })\n .from(users)\n .where(sql`${users.email} ILIKE ${pattern}`),\n ]);\n return {\n users: rows.map((r) => this.userToAuthUser(r)),\n total: Number(count),\n };\n }\n\n const [rows, [{ count }]] = await Promise.all([\n this.db\n .select()\n .from(users)\n .orderBy(desc(users.createdAt))\n .limit(limit)\n .offset(offset),\n this.db.select({ count: sql<number>`count(*)` }).from(users),\n ]);\n return {\n users: rows.map((r) => this.userToAuthUser(r)),\n total: Number(count),\n };\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 findSessionByRefreshToken(\n refreshToken: string,\n ): Promise<Session | null> {\n const [session] = await this.db\n .select()\n .from(sessions)\n .where(\n and(\n eq(sessions.refreshToken, refreshToken),\n gt(sessions.expiresAt, new Date()),\n ),\n )\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 ?? null,\n userEmail: data.userEmail ?? null,\n role: data.role ?? null,\n resource: data.resource,\n resourceId: data.resourceId ?? null,\n changes: data.changes ?? null,\n ipAddress: data.ipAddress ?? null,\n userAgent: data.userAgent ?? null,\n success: data.success,\n error: data.error ?? null,\n metadata: data.metadata ?? null,\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 name: user.name || undefined,\n email: user.email,\n passwordHash: user.passwordHash || undefined,\n role: user.role as UserRole,\n avatar: user.avatar && typeof user.avatar === \"object\"\n ? (user.avatar as any).id || undefined\n : (user.avatar || undefined),\n tenantId: user.tenantId || undefined,\n emailVerified: user.emailVerified || false,\n locked: user.locked || false,\n lastLogin: user.lastLogin ? new Date(user.lastLogin).toISOString() : undefined,\n failedLoginAttempts: user.failedLoginAttempts || 0,\n createdAt: new Date(user.createdAt).toISOString(),\n updatedAt: new Date(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: new Date(session.expiresAt).toISOString(),\n createdAt: new Date(session.createdAt).toISOString(),\n ipAddress: session.ipAddress || undefined,\n userAgent: session.userAgent || undefined,\n };\n }\n\n async createEmailVerificationToken(userId: string): Promise<{ token: string; expiresAt: Date }> {\n const token = randomBytes(32).toString(\"hex\");\n const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000);\n\n await this.db.insert(emailVerifications).values({\n userId,\n token,\n expiresAt,\n });\n\n return { token, expiresAt };\n }\n\n async verifyEmailToken(token: string): Promise<{ success: boolean; userId?: string; error?: string }> {\n const [verification] = await this.db\n .select()\n .from(emailVerifications)\n .where(eq(emailVerifications.token, token))\n .limit(1);\n\n if (!verification) {\n return { success: false, error: \"Invalid verification token\" };\n }\n\n if (verification.expiresAt < new Date()) {\n return { success: false, error: \"Verification token has expired\" };\n }\n\n await this.db\n .update(users)\n .set({ emailVerified: true })\n .where(eq(users.id, verification.userId));\n\n await this.db\n .delete(emailVerifications)\n .where(eq(emailVerifications.id, verification.id));\n\n return { success: true, userId: verification.userId };\n }\n\n async createPasswordResetToken(email: string): Promise<{ token: string; expiresAt: Date; error?: string }> {\n const user = await this.findUserByEmail(email);\n if (!user) {\n return { token: \"\", expiresAt: new Date(), error: \"User not found\" };\n }\n\n const token = randomBytes(32).toString(\"hex\");\n const expiresAt = new Date(Date.now() + 60 * 60 * 1000);\n\n await this.db.insert(passwordResets).values({\n userId: user.id,\n token,\n expiresAt,\n });\n\n return { token, expiresAt };\n }\n\n async resetPasswordWithToken(token: string, newPassword: string): Promise<{ success: boolean; error?: string }> {\n const [reset] = await this.db\n .select()\n .from(passwordResets)\n .where(eq(passwordResets.token, token))\n .limit(1);\n\n if (!reset) {\n return { success: false, error: \"Invalid reset token\" };\n }\n\n if (reset.expiresAt < new Date()) {\n return { success: false, error: \"Reset token has expired\" };\n }\n\n if (reset.usedAt) {\n return { success: false, error: \"Reset token has already been used\" };\n }\n\n const passwordHash = await this.hashPassword(newPassword);\n\n await this.db\n .update(users)\n .set({ passwordHash, updatedAt: new Date() })\n .where(eq(users.id, reset.userId));\n\n await this.db\n .update(passwordResets)\n .set({ usedAt: new Date() })\n .where(eq(passwordResets.id, reset.id));\n\n await this.db.delete(sessions).where(eq(sessions.userId, reset.userId));\n\n return { success: true };\n }\n}\n"]}
|
|
@@ -164,7 +164,6 @@ var KyroWSServer = class {
|
|
|
164
164
|
lastActivity: /* @__PURE__ */ new Date()
|
|
165
165
|
};
|
|
166
166
|
this.clients.set(clientId, client);
|
|
167
|
-
console.log(`[WS] Client connected: ${clientId} (total: ${this.clients.size})`);
|
|
168
167
|
this.sendToClient(client, {
|
|
169
168
|
type: "connected",
|
|
170
169
|
clientId,
|
|
@@ -350,7 +349,6 @@ var KyroWSServer = class {
|
|
|
350
349
|
subscription.unsubscribe();
|
|
351
350
|
}
|
|
352
351
|
this.clients.delete(client.id);
|
|
353
|
-
console.log(`[WS] Client disconnected: ${client.id} (total: ${this.clients.size})`);
|
|
354
352
|
}
|
|
355
353
|
sendToClient(client, data) {
|
|
356
354
|
if (client.ws.readyState === WebSocket.OPEN) {
|
|
@@ -367,7 +365,6 @@ var KyroWSServer = class {
|
|
|
367
365
|
if (client.ws.readyState === WebSocket.OPEN) {
|
|
368
366
|
const timeSinceLastActivity = Date.now() - client.lastActivity.getTime();
|
|
369
367
|
if (timeSinceLastActivity > this.options.pingInterval * 3) {
|
|
370
|
-
console.log(`[WS] Client ${id} timed out`);
|
|
371
368
|
client.ws.terminate();
|
|
372
369
|
this.handleDisconnect(client);
|
|
373
370
|
continue;
|
|
@@ -405,7 +402,6 @@ var KyroWSServer = class {
|
|
|
405
402
|
}
|
|
406
403
|
return new Promise((resolve) => {
|
|
407
404
|
this.wss.close(() => {
|
|
408
|
-
console.log("[WS] Server closed");
|
|
409
405
|
resolve();
|
|
410
406
|
});
|
|
411
407
|
});
|
|
@@ -419,5 +415,5 @@ function createWSServer(options) {
|
|
|
419
415
|
}
|
|
420
416
|
|
|
421
417
|
export { KyroPubSub, KyroWSServer, PubSub, createWSServer };
|
|
422
|
-
//# sourceMappingURL=chunk-
|
|
423
|
-
//# sourceMappingURL=chunk-
|
|
418
|
+
//# sourceMappingURL=chunk-BYBMTIMT.js.map
|
|
419
|
+
//# sourceMappingURL=chunk-BYBMTIMT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/api/ws/pubsub.ts","../src/api/ws/server.ts"],"names":[],"mappings":"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","file":"chunk-BYBMTIMT.js","sourcesContent":["// ============================================================================\n// Pub/Sub Event Emitter\n// ============================================================================\n\nexport type EventHandler = (data: any) => void | Promise<void>;\n\nexport class PubSub {\n private channels: Map<string, Set<EventHandler>> = new Map();\n private maxListeners: number;\n\n constructor(maxListeners = 100) {\n this.maxListeners = maxListeners;\n }\n\n subscribe(channel: string, handler: EventHandler): () => void {\n if (!this.channels.has(channel)) {\n this.channels.set(channel, new Set());\n }\n\n const handlers = this.channels.get(channel)!;\n if (handlers.size >= this.maxListeners) {\n throw new Error(`Max listeners (${this.maxListeners}) reached for channel \"${channel}\"`);\n }\n\n handlers.add(handler);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this.channels.delete(channel);\n }\n };\n }\n\n publish(channel: string, data: any): void {\n const handlers = this.channels.get(channel);\n if (handlers) {\n for (const handler of handlers) {\n try {\n const result = handler(data);\n if (result instanceof Promise) {\n result.catch((err) => {\n console.error(`[PubSub] Error in handler for channel \"${channel}\":`, err);\n });\n }\n } catch (err) {\n console.error(`[PubSub] Error in handler for channel \"${channel}\":`, err);\n }\n }\n }\n }\n\n hasSubscribers(channel: string): boolean {\n return this.channels.has(channel) && this.channels.get(channel)!.size > 0;\n }\n\n getSubscriberCount(channel: string): number {\n return this.channels.get(channel)?.size || 0;\n }\n\n getChannels(): string[] {\n return Array.from(this.channels.keys());\n }\n\n clear(): void {\n this.channels.clear();\n }\n}\n\n// ============================================================================\n// Kyro-specific Event Types\n// ============================================================================\n\nexport interface KyroEvent {\n type: 'create' | 'update' | 'delete';\n collection: string;\n doc?: any;\n originalDoc?: any;\n id?: string;\n tenantID?: string;\n timestamp: string;\n user?: any;\n}\n\n// ============================================================================\n// Kyro Pub/Sub with Hook Integration\n// ============================================================================\n\nexport class KyroPubSub extends PubSub {\n private registry: any;\n\n constructor(registry: any, maxListeners = 100) {\n super(maxListeners);\n this.registry = registry;\n }\n\n // Publish collection-level events\n publishCollectionEvent(collection: string, event: KyroEvent): void {\n // Publish to collection channel\n this.publish(`collection:${collection}`, event);\n\n // Publish to global events channel\n this.publish('events:collection', event);\n\n // Publish to tenant-specific channel if scoped\n if (event.tenantID) {\n this.publish(`tenant:${event.tenantID}:collection:${collection}`, event);\n this.publish(`tenant:${event.tenantID}:events`, event);\n }\n\n // Publish to type-specific channel\n this.publish(`collection:${collection}:${event.type}`, event);\n }\n\n // Subscribe to a collection\n subscribeToCollection(collection: string, handler: EventHandler): () => void {\n return this.subscribe(`collection:${collection}`, handler);\n }\n\n // Subscribe to a specific event type on a collection\n subscribeToCollectionEvent(\n collection: string,\n eventType: 'create' | 'update' | 'delete',\n handler: EventHandler\n ): () => void {\n return this.subscribe(`collection:${collection}:${eventType}`, handler);\n }\n\n // Subscribe to tenant-scoped events\n subscribeToTenant(tenantID: string, handler: EventHandler): () => void {\n return this.subscribe(`tenant:${tenantID}:events`, handler);\n }\n\n // Subscribe to tenant + collection events\n subscribeToTenantCollection(\n tenantID: string,\n collection: string,\n handler: EventHandler\n ): () => void {\n return this.subscribe(`tenant:${tenantID}:collection:${collection}`, handler);\n }\n\n // Subscribe to all collection events\n subscribeToAllCollections(handler: EventHandler): () => void {\n return this.subscribe('events:collection', handler);\n }\n\n // Create hooks for afterChange/afterDelete\n createAfterChangeHook(collection: string) {\n return async (args: any) => {\n this.publishCollectionEvent(collection, {\n type: args.operation === 'create' ? 'create' : 'update',\n collection,\n doc: args.doc,\n originalDoc: args.originalDoc,\n id: args.id || args.doc?.id,\n tenantID: args.tenantID,\n timestamp: new Date().toISOString(),\n user: args.user,\n });\n };\n }\n\n createAfterDeleteHook(collection: string) {\n return async (args: any) => {\n this.publishCollectionEvent(collection, {\n type: 'delete',\n collection,\n doc: args.doc,\n originalDoc: args.originalDoc,\n id: args.id || args.doc?.id,\n tenantID: args.tenantID,\n timestamp: new Date().toISOString(),\n user: args.user,\n });\n };\n }\n\n // Auto-register hooks for all collections\n autoRegisterHooks(): void {\n const collections = this.registry.getCollections();\n for (const collection of collections) {\n const config = this.registry.getCollection(collection.slug);\n if (config) {\n if (!config.hooks) config.hooks = {};\n if (!config.hooks.afterChange) config.hooks.afterChange = [];\n if (!config.hooks.afterDelete) config.hooks.afterDelete = [];\n\n config.hooks.afterChange.push(this.createAfterChangeHook(collection.slug));\n config.hooks.afterDelete.push(this.createAfterDeleteHook(collection.slug));\n }\n }\n }\n}\n","import { WebSocketServer, WebSocket } from 'ws';\nimport type { KyroPubSub, KyroEvent } from './pubsub.js';\n\n// ============================================================================\n// WebSocket Server\n// ============================================================================\n\nexport interface WSServerOptions {\n port?: number;\n pubsub: KyroPubSub;\n maxConnections?: number;\n pingInterval?: number;\n requireAuth?: boolean;\n verifyToken?: (token: string) => Promise<any>;\n}\n\nexport interface WSSubscription {\n channel: string;\n unsubscribe: () => void;\n}\n\nexport interface WSClient {\n id: string;\n ws: WebSocket;\n subscriptions: Map<string, WSSubscription>;\n authenticated: boolean;\n user?: any;\n tenantID?: string;\n connectedAt: Date;\n lastActivity: Date;\n}\n\nexport class KyroWSServer {\n private wss: WebSocketServer;\n private clients: Map<string, WSClient> = new Map();\n private pubsub: KyroPubSub;\n private options: WSServerOptions;\n private pingTimer?: NodeJS.Timer;\n\n constructor(options: WSServerOptions) {\n this.options = options;\n this.pubsub = options.pubsub;\n\n this.wss = new WebSocketServer({\n port: options.port || 8080,\n });\n\n this.setupServer();\n this.startPingInterval();\n }\n\n private setupServer(): void {\n this.wss.on('connection', (ws: WebSocket, req: any) => {\n const clientId = this.generateClientId();\n\n if (this.options.maxConnections && this.clients.size >= this.options.maxConnections) {\n ws.close(1013, 'Server at capacity');\n return;\n }\n\n const client: WSClient = {\n id: clientId,\n ws,\n subscriptions: new Map(),\n authenticated: false,\n connectedAt: new Date(),\n lastActivity: new Date(),\n };\n\n this.clients.set(clientId, client);\n\n\n // Send welcome message\n this.sendToClient(client, {\n type: 'connected',\n clientId,\n timestamp: new Date().toISOString(),\n });\n\n // Handle messages\n ws.on('message', (data: Buffer) => {\n this.handleMessage(client, data);\n });\n\n // Handle errors\n ws.on('error', (error: Error) => {\n console.error(`[WS] Client error ${clientId}:`, error);\n });\n\n // Handle close\n ws.on('close', () => {\n this.handleDisconnect(client);\n });\n\n // Handle pong\n ws.on('pong', () => {\n client.lastActivity = new Date();\n });\n });\n\n this.wss.on('error', (error: Error) => {\n console.error('[WS] Server error:', error);\n });\n }\n\n private handleMessage(client: WSClient, data: Buffer): void {\n client.lastActivity = new Date();\n\n let message: any;\n try {\n message = JSON.parse(data.toString());\n } catch {\n this.sendToClient(client, {\n type: 'error',\n error: 'Invalid JSON',\n });\n return;\n }\n\n switch (message.type) {\n case 'authenticate':\n this.handleAuthenticate(client, message);\n break;\n case 'subscribe':\n this.handleSubscribe(client, message);\n break;\n case 'unsubscribe':\n this.handleUnsubscribe(client, message);\n break;\n case 'unsubscribeAll':\n this.handleUnsubscribeAll(client);\n break;\n case 'list':\n this.handleList(client);\n break;\n case 'ping':\n this.sendToClient(client, { type: 'pong', timestamp: new Date().toISOString() });\n break;\n default:\n this.sendToClient(client, {\n type: 'error',\n error: `Unknown message type: ${message.type}`,\n });\n }\n }\n\n private async handleAuthenticate(client: WSClient, message: any): Promise<void> {\n if (!this.options.requireAuth) {\n client.authenticated = true;\n this.sendToClient(client, {\n type: 'authenticated',\n success: true,\n });\n return;\n }\n\n if (!this.options.verifyToken) {\n client.authenticated = true;\n this.sendToClient(client, {\n type: 'authenticated',\n success: true,\n });\n return;\n }\n\n try {\n const user = await this.options.verifyToken(message.token);\n client.authenticated = true;\n client.user = user;\n client.tenantID = user.tenantID;\n this.sendToClient(client, {\n type: 'authenticated',\n success: true,\n user: { id: user.id, email: user.email },\n });\n } catch (error: any) {\n this.sendToClient(client, {\n type: 'authenticated',\n success: false,\n error: error.message,\n });\n }\n }\n\n private handleSubscribe(client: WSClient, message: any): void {\n if (this.options.requireAuth && !client.authenticated) {\n this.sendToClient(client, {\n type: 'error',\n error: 'Not authenticated',\n });\n return;\n }\n\n const channel = message.channel;\n if (!channel) {\n this.sendToClient(client, {\n type: 'error',\n error: 'Channel is required',\n });\n return;\n }\n\n // Check if already subscribed\n if (client.subscriptions.has(channel)) {\n this.sendToClient(client, {\n type: 'subscribed',\n channel,\n success: true,\n message: 'Already subscribed',\n });\n return;\n }\n\n // Subscribe to channel\n const unsubscribe = this.pubsub.subscribe(channel, (data: any) => {\n this.sendToClient(client, {\n type: 'event',\n channel,\n data,\n timestamp: new Date().toISOString(),\n });\n });\n\n client.subscriptions.set(channel, { channel, unsubscribe });\n\n this.sendToClient(client, {\n type: 'subscribed',\n channel,\n success: true,\n });\n }\n\n private handleUnsubscribe(client: WSClient, message: any): void {\n const channel = message.channel;\n if (!channel) {\n this.sendToClient(client, {\n type: 'error',\n error: 'Channel is required',\n });\n return;\n }\n\n const subscription = client.subscriptions.get(channel);\n if (subscription) {\n subscription.unsubscribe();\n client.subscriptions.delete(channel);\n this.sendToClient(client, {\n type: 'unsubscribed',\n channel,\n success: true,\n });\n } else {\n this.sendToClient(client, {\n type: 'unsubscribed',\n channel,\n success: false,\n message: 'Not subscribed',\n });\n }\n }\n\n private handleUnsubscribeAll(client: WSClient): void {\n for (const [, subscription] of client.subscriptions) {\n subscription.unsubscribe();\n }\n client.subscriptions.clear();\n\n this.sendToClient(client, {\n type: 'unsubscribedAll',\n success: true,\n });\n }\n\n private handleList(client: WSClient): void {\n const channels = this.pubsub.getChannels();\n this.sendToClient(client, {\n type: 'channels',\n channels,\n count: channels.length,\n });\n }\n\n private handleDisconnect(client: WSClient): void {\n // Unsubscribe from all channels\n for (const [, subscription] of client.subscriptions) {\n subscription.unsubscribe();\n }\n\n this.clients.delete(client.id);\n\n }\n\n private sendToClient(client: WSClient, data: any): void {\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.send(JSON.stringify(data));\n }\n }\n\n private generateClientId(): string {\n return `ws_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n private startPingInterval(): void {\n if (!this.options.pingInterval) return;\n\n this.pingTimer = setInterval(() => {\n for (const [id, client] of this.clients) {\n if (client.ws.readyState === WebSocket.OPEN) {\n // Check if client responded to last ping\n const timeSinceLastActivity = Date.now() - client.lastActivity.getTime();\n if (timeSinceLastActivity > (this.options.pingInterval! * 3)) {\n\n client.ws.terminate();\n this.handleDisconnect(client);\n continue;\n }\n client.ws.ping();\n }\n }\n }, this.options.pingInterval);\n }\n\n // ============================================================================\n // Public API\n // ============================================================================\n\n broadcast(channel: string, data: any): void {\n this.pubsub.publish(channel, data);\n }\n\n getConnectedClients(): WSClient[] {\n return Array.from(this.clients.values());\n }\n\n getClientCount(): number {\n return this.clients.size;\n }\n\n getSubscriptionCount(): number {\n let count = 0;\n for (const client of this.clients.values()) {\n count += client.subscriptions.size;\n }\n return count;\n }\n\n async close(): Promise<void> {\n if (this.pingTimer) {\n clearInterval(this.pingTimer as any);\n }\n\n // Close all client connections\n for (const client of this.clients.values()) {\n client.ws.close(1001, 'Server shutting down');\n }\n\n // Close server\n return new Promise((resolve) => {\n this.wss.close(() => {\n\n resolve();\n });\n });\n }\n\n getServer(): WebSocketServer {\n return this.wss;\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createWSServer(options: WSServerOptions): KyroWSServer {\n return new KyroWSServer(options);\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { users, sessions, passwordHistory, lockouts, auditLogs, emailVerifications, passwordResets } from './chunk-
|
|
1
|
+
import { users, sessions, passwordHistory, lockouts, auditLogs, emailVerifications, passwordResets } from './chunk-UUDTPZX6.js';
|
|
2
2
|
import { sql, eq, desc, and, gt } from 'drizzle-orm';
|
|
3
3
|
import bcrypt from 'bcryptjs';
|
|
4
4
|
import { randomBytes } from 'crypto';
|
|
@@ -62,7 +62,7 @@ var PostgresAuthAdapter = class {
|
|
|
62
62
|
"user_email" VARCHAR(255),
|
|
63
63
|
"role" VARCHAR(50),
|
|
64
64
|
"resource" VARCHAR(100) NOT NULL,
|
|
65
|
-
"resource_id"
|
|
65
|
+
"resource_id" VARCHAR(255),
|
|
66
66
|
"changes" JSONB,
|
|
67
67
|
"ip_address" VARCHAR(45),
|
|
68
68
|
"user_agent" TEXT,
|
|
@@ -72,6 +72,7 @@ var PostgresAuthAdapter = class {
|
|
|
72
72
|
"timestamp" TIMESTAMP NOT NULL DEFAULT NOW()
|
|
73
73
|
)
|
|
74
74
|
`);
|
|
75
|
+
await this.db.execute(sql`ALTER TABLE "audit_logs" ALTER COLUMN "resource_id" TYPE VARCHAR(255)`);
|
|
75
76
|
await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "audit_logs_user_idx" ON "audit_logs" ("user_id")`);
|
|
76
77
|
await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "audit_logs_action_idx" ON "audit_logs" ("action")`);
|
|
77
78
|
await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "audit_logs_resource_idx" ON "audit_logs" ("resource")`);
|
|
@@ -484,5 +485,5 @@ var PostgresAuthAdapter = class {
|
|
|
484
485
|
};
|
|
485
486
|
|
|
486
487
|
export { PostgresAuthAdapter };
|
|
487
|
-
//# sourceMappingURL=chunk-
|
|
488
|
-
//# sourceMappingURL=chunk-
|
|
488
|
+
//# sourceMappingURL=chunk-CJX74IYK.js.map
|
|
489
|
+
//# sourceMappingURL=chunk-CJX74IYK.js.map
|