@kyro-cms/core 0.1.3 → 0.1.5

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 (77) hide show
  1. package/dist/bootstrap-BDTTUGY2.js +4 -0
  2. package/dist/{bootstrap-Q2TWUQF3.js.map → bootstrap-BDTTUGY2.js.map} +1 -1
  3. package/dist/bootstrap-X6TP3NKX.cjs +29 -0
  4. package/dist/{bootstrap-2WJK6PG7.cjs.map → bootstrap-X6TP3NKX.cjs.map} +1 -1
  5. package/dist/chunk-5BLDMQED.cjs +18 -0
  6. package/dist/{chunk-Q7SFCCGT.cjs.map → chunk-5BLDMQED.cjs.map} +1 -1
  7. package/dist/{chunk-U4CHJTWX.cjs → chunk-7G6EVYCU.cjs} +5 -5
  8. package/dist/{chunk-U4CHJTWX.cjs.map → chunk-7G6EVYCU.cjs.map} +1 -1
  9. package/dist/chunk-A3RQWHKD.cjs +263 -0
  10. package/dist/chunk-A3RQWHKD.cjs.map +1 -0
  11. package/dist/{chunk-V67YXRBT.js → chunk-C74MQIRL.js} +517 -203
  12. package/dist/chunk-C74MQIRL.js.map +1 -0
  13. package/dist/{chunk-XLMVCGXA.js → chunk-LRTZJJPD.js} +3 -3
  14. package/dist/{chunk-XLMVCGXA.js.map → chunk-LRTZJJPD.js.map} +1 -1
  15. package/dist/{chunk-I4BORBXT.cjs → chunk-MHS6CPO5.cjs} +517 -204
  16. package/dist/chunk-MHS6CPO5.cjs.map +1 -0
  17. package/dist/chunk-NSBPE2FW.js +15 -0
  18. package/dist/{chunk-PZ5AY32C.js.map → chunk-NSBPE2FW.js.map} +1 -1
  19. package/dist/{chunk-M4JFHQ5J.js → chunk-QUJ4OLSC.js} +3 -3
  20. package/dist/{chunk-M4JFHQ5J.js.map → chunk-QUJ4OLSC.js.map} +1 -1
  21. package/dist/{chunk-5AOILNGY.cjs → chunk-TZFJMPCH.cjs} +4 -4
  22. package/dist/{chunk-5AOILNGY.cjs.map → chunk-TZFJMPCH.cjs.map} +1 -1
  23. package/dist/chunk-VMSRTAH7.js +256 -0
  24. package/dist/chunk-VMSRTAH7.js.map +1 -0
  25. package/dist/{chunk-KA3UOIFC.js → chunk-XTZSUDSI.js} +3 -3
  26. package/dist/{chunk-KA3UOIFC.js.map → chunk-XTZSUDSI.js.map} +1 -1
  27. package/dist/{chunk-KWTKEBHM.cjs → chunk-YD7Y25W7.cjs} +19 -19
  28. package/dist/{chunk-KWTKEBHM.cjs.map → chunk-YD7Y25W7.cjs.map} +1 -1
  29. package/dist/cli/index.cjs +5 -5
  30. package/dist/cli/index.js +5 -5
  31. package/dist/database-7CJOXEZR.js +5 -0
  32. package/dist/{database-37KXWUER.js.map → database-7CJOXEZR.js.map} +1 -1
  33. package/dist/database-QOIV44GT.cjs +22 -0
  34. package/dist/{database-LJKD3HE4.cjs.map → database-QOIV44GT.cjs.map} +1 -1
  35. package/dist/drizzle/index.cjs +8 -8
  36. package/dist/drizzle/index.d.cts +1 -1
  37. package/dist/drizzle/index.d.ts +1 -1
  38. package/dist/drizzle/index.js +4 -4
  39. package/dist/graphql/index.cjs +1 -1
  40. package/dist/graphql/index.js +1 -1
  41. package/dist/{index-CzkEHKqu.d.cts → index-BMySjW6o.d.cts} +6 -0
  42. package/dist/{index-BVFlb7uU.d.ts → index-CMUNCIWQ.d.ts} +6 -0
  43. package/dist/index.cjs +727 -346
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.d.cts +229 -62
  46. package/dist/index.d.ts +229 -62
  47. package/dist/index.js +706 -331
  48. package/dist/index.js.map +1 -1
  49. package/dist/mongodb/index.cjs +1 -1
  50. package/dist/mongodb/index.js +1 -1
  51. package/dist/postgres-auth-adapter-REJFUMP7.js +5 -0
  52. package/dist/{postgres-auth-adapter-LTDUGBMB.js.map → postgres-auth-adapter-REJFUMP7.js.map} +1 -1
  53. package/dist/postgres-auth-adapter-VK6GY7LX.cjs +14 -0
  54. package/dist/{postgres-auth-adapter-CYZAVPPP.cjs.map → postgres-auth-adapter-VK6GY7LX.cjs.map} +1 -1
  55. package/dist/redis-adapter-4YDY4LWE.js +4 -0
  56. package/dist/redis-adapter-4YDY4LWE.js.map +1 -0
  57. package/dist/redis-adapter-LBLNKGNS.cjs +13 -0
  58. package/dist/redis-adapter-LBLNKGNS.cjs.map +1 -0
  59. package/dist/rest/index.cjs +1 -1
  60. package/dist/rest/index.js +1 -1
  61. package/dist/templates/index.cjs +1 -1
  62. package/dist/templates/index.js +1 -1
  63. package/dist/trpc/index.cjs +1 -1
  64. package/dist/trpc/index.js +1 -1
  65. package/dist/ws/index.cjs +1 -1
  66. package/dist/ws/index.js +1 -1
  67. package/package.json +2 -2
  68. package/dist/bootstrap-2WJK6PG7.cjs +0 -29
  69. package/dist/bootstrap-Q2TWUQF3.js +0 -4
  70. package/dist/chunk-I4BORBXT.cjs.map +0 -1
  71. package/dist/chunk-PZ5AY32C.js +0 -9
  72. package/dist/chunk-Q7SFCCGT.cjs +0 -11
  73. package/dist/chunk-V67YXRBT.js.map +0 -1
  74. package/dist/database-37KXWUER.js +0 -5
  75. package/dist/database-LJKD3HE4.cjs +0 -22
  76. package/dist/postgres-auth-adapter-CYZAVPPP.cjs +0 -14
  77. package/dist/postgres-auth-adapter-LTDUGBMB.js +0 -5
@@ -0,0 +1,4 @@
1
+ export { autoBootstrap, bootstrapAdmin, bootstrapWithRetry, checkBootstrapRequired, getBootstrapFromEnv } from './chunk-C74MQIRL.js';
2
+ import './chunk-NSBPE2FW.js';
3
+ //# sourceMappingURL=bootstrap-BDTTUGY2.js.map
4
+ //# sourceMappingURL=bootstrap-BDTTUGY2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"bootstrap-Q2TWUQF3.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"bootstrap-BDTTUGY2.js"}
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ var chunkMHS6CPO5_cjs = require('./chunk-MHS6CPO5.cjs');
4
+ require('./chunk-5BLDMQED.cjs');
5
+
6
+
7
+
8
+ Object.defineProperty(exports, "autoBootstrap", {
9
+ enumerable: true,
10
+ get: function () { return chunkMHS6CPO5_cjs.autoBootstrap; }
11
+ });
12
+ Object.defineProperty(exports, "bootstrapAdmin", {
13
+ enumerable: true,
14
+ get: function () { return chunkMHS6CPO5_cjs.bootstrapAdmin; }
15
+ });
16
+ Object.defineProperty(exports, "bootstrapWithRetry", {
17
+ enumerable: true,
18
+ get: function () { return chunkMHS6CPO5_cjs.bootstrapWithRetry; }
19
+ });
20
+ Object.defineProperty(exports, "checkBootstrapRequired", {
21
+ enumerable: true,
22
+ get: function () { return chunkMHS6CPO5_cjs.checkBootstrapRequired; }
23
+ });
24
+ Object.defineProperty(exports, "getBootstrapFromEnv", {
25
+ enumerable: true,
26
+ get: function () { return chunkMHS6CPO5_cjs.getBootstrapFromEnv; }
27
+ });
28
+ //# sourceMappingURL=bootstrap-X6TP3NKX.cjs.map
29
+ //# sourceMappingURL=bootstrap-X6TP3NKX.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"bootstrap-2WJK6PG7.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"bootstrap-X6TP3NKX.cjs"}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+
15
+ exports.__export = __export;
16
+ exports.__require = __require;
17
+ //# sourceMappingURL=chunk-5BLDMQED.cjs.map
18
+ //# sourceMappingURL=chunk-5BLDMQED.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-Q7SFCCGT.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-5BLDMQED.cjs"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk5AOILNGY_cjs = require('./chunk-5AOILNGY.cjs');
3
+ var chunkTZFJMPCH_cjs = require('./chunk-TZFJMPCH.cjs');
4
4
  var postgresJs = require('drizzle-orm/postgres-js');
5
5
  var postgres = require('postgres');
6
6
  var migrator = require('drizzle-orm/postgres-js/migrator');
@@ -28,7 +28,7 @@ async function createDatabase(config) {
28
28
  max: maxConnections,
29
29
  ssl: ssl ? "require" : false
30
30
  });
31
- const db = postgresJs.drizzle(client, { schema: chunk5AOILNGY_cjs.auth_exports });
31
+ const db = postgresJs.drizzle(client, { schema: chunkTZFJMPCH_cjs.auth_exports });
32
32
  return { client, db };
33
33
  }
34
34
  async function runMigrations(db) {
@@ -37,7 +37,7 @@ async function runMigrations(db) {
37
37
  console.log("Migrations complete");
38
38
  }
39
39
  async function seedDefaultRoles(db) {
40
- const { roles } = chunk5AOILNGY_cjs.auth_exports;
40
+ const { roles } = chunkTZFJMPCH_cjs.auth_exports;
41
41
  const defaultRoles = [
42
42
  {
43
43
  name: "super_admin",
@@ -90,5 +90,5 @@ async function seedDefaultRoles(db) {
90
90
  exports.createDatabase = createDatabase;
91
91
  exports.runMigrations = runMigrations;
92
92
  exports.seedDefaultRoles = seedDefaultRoles;
93
- //# sourceMappingURL=chunk-U4CHJTWX.cjs.map
94
- //# sourceMappingURL=chunk-U4CHJTWX.cjs.map
93
+ //# sourceMappingURL=chunk-7G6EVYCU.cjs.map
94
+ //# sourceMappingURL=chunk-7G6EVYCU.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/database/drizzle/database.ts"],"names":["postgres","drizzle","auth_exports","migrate"],"mappings":"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","file":"chunk-U4CHJTWX.cjs","sourcesContent":["import { drizzle } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\nimport { migrate } from \"drizzle-orm/postgres-js/migrator\";\nimport * as schema from \"./schema/auth.js\";\n\nfunction getEnv(key: string, fallback: string = \"\"): string {\n return process.env[key] || fallback;\n}\n\nfunction getEnvNum(key: string, fallback: number = 0): number {\n const val = process.env[key];\n if (!val) return fallback;\n return parseInt(val, 10);\n}\n\nexport interface DatabaseConfig {\n url: string;\n maxConnections: number;\n ssl: boolean;\n}\n\nexport async function createDatabase(config?: Partial<DatabaseConfig>) {\n const databaseUrl =\n config?.url ||\n getEnv(\n \"DATABASE_URL\",\n \"postgresql://postgres:postgres@localhost:5432/kyro_cms\",\n );\n const maxConnections =\n config?.maxConnections || getEnvNum(\"DATABASE_POOL_MAX\", 10);\n const ssl = config?.ssl || getEnv(\"DATABASE_SSL\", \"false\") === \"true\";\n\n const client = postgres(databaseUrl, {\n max: maxConnections,\n ssl: ssl ? \"require\" : false,\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = drizzle(client, { schema: schema as any });\n\n return { client, db };\n}\n\nexport async function runMigrations(db: ReturnType<typeof drizzle>) {\n console.log(\"Running migrations...\");\n await migrate(db, { migrationsFolder: \"./drizzle\" });\n console.log(\"Migrations complete\");\n}\n\nexport async function seedDefaultRoles(db: ReturnType<typeof drizzle>) {\n const { roles } = schema;\n\n const defaultRoles = [\n {\n name: \"super_admin\",\n level: 100,\n inherits: [],\n description: \"Full system access across all tenants\",\n isSystem: true,\n },\n {\n name: \"admin\",\n level: 90,\n inherits: [\"editor\"],\n description: \"Full tenant access with all content permissions\",\n isSystem: true,\n },\n {\n name: \"editor\",\n level: 70,\n inherits: [\"author\"],\n description: \"Edit and publish all content\",\n isSystem: true,\n },\n {\n name: \"author\",\n level: 50,\n inherits: [\"customer\"],\n description: \"Create and edit own content\",\n isSystem: true,\n },\n {\n name: \"customer\",\n level: 30,\n inherits: [],\n description: \"Access own data and make purchases\",\n isSystem: true,\n },\n {\n name: \"guest\",\n level: 10,\n inherits: [],\n description: \"Public read-only access\",\n isSystem: true,\n },\n ];\n\n for (const role of defaultRoles) {\n await db.insert(roles).values(role).onConflictDoNothing();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/database/drizzle/database.ts"],"names":["postgres","drizzle","auth_exports","migrate"],"mappings":"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","file":"chunk-7G6EVYCU.cjs","sourcesContent":["import { drizzle } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\nimport { migrate } from \"drizzle-orm/postgres-js/migrator\";\nimport * as schema from \"./schema/auth.js\";\n\nfunction getEnv(key: string, fallback: string = \"\"): string {\n return process.env[key] || fallback;\n}\n\nfunction getEnvNum(key: string, fallback: number = 0): number {\n const val = process.env[key];\n if (!val) return fallback;\n return parseInt(val, 10);\n}\n\nexport interface DatabaseConfig {\n url: string;\n maxConnections: number;\n ssl: boolean;\n}\n\nexport async function createDatabase(config?: Partial<DatabaseConfig>) {\n const databaseUrl =\n config?.url ||\n getEnv(\n \"DATABASE_URL\",\n \"postgresql://postgres:postgres@localhost:5432/kyro_cms\",\n );\n const maxConnections =\n config?.maxConnections || getEnvNum(\"DATABASE_POOL_MAX\", 10);\n const ssl = config?.ssl || getEnv(\"DATABASE_SSL\", \"false\") === \"true\";\n\n const client = postgres(databaseUrl, {\n max: maxConnections,\n ssl: ssl ? \"require\" : false,\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = drizzle(client, { schema: schema as any });\n\n return { client, db };\n}\n\nexport async function runMigrations(db: ReturnType<typeof drizzle>) {\n console.log(\"Running migrations...\");\n await migrate(db, { migrationsFolder: \"./drizzle\" });\n console.log(\"Migrations complete\");\n}\n\nexport async function seedDefaultRoles(db: ReturnType<typeof drizzle>) {\n const { roles } = schema;\n\n const defaultRoles = [\n {\n name: \"super_admin\",\n level: 100,\n inherits: [],\n description: \"Full system access across all tenants\",\n isSystem: true,\n },\n {\n name: \"admin\",\n level: 90,\n inherits: [\"editor\"],\n description: \"Full tenant access with all content permissions\",\n isSystem: true,\n },\n {\n name: \"editor\",\n level: 70,\n inherits: [\"author\"],\n description: \"Edit and publish all content\",\n isSystem: true,\n },\n {\n name: \"author\",\n level: 50,\n inherits: [\"customer\"],\n description: \"Create and edit own content\",\n isSystem: true,\n },\n {\n name: \"customer\",\n level: 30,\n inherits: [],\n description: \"Access own data and make purchases\",\n isSystem: true,\n },\n {\n name: \"guest\",\n level: 10,\n inherits: [],\n description: \"Public read-only access\",\n isSystem: true,\n },\n ];\n\n for (const role of defaultRoles) {\n await db.insert(roles).values(role).onConflictDoNothing();\n }\n}\n"]}
@@ -0,0 +1,263 @@
1
+ 'use strict';
2
+
3
+ var Redis = require('ioredis');
4
+ var bcrypt = require('bcryptjs');
5
+ var crypto = require('crypto');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var Redis__default = /*#__PURE__*/_interopDefault(Redis);
10
+ var bcrypt__default = /*#__PURE__*/_interopDefault(bcrypt);
11
+
12
+ // src/auth/redis-adapter.ts
13
+ var DEFAULT_PREFIX = "kyro:auth:";
14
+ var DEFAULT_TOKEN_EXPIRATION = 86400;
15
+ var DEFAULT_REFRESH_EXPIRATION = 604800;
16
+ var RedisAuthAdapter = class {
17
+ redis;
18
+ prefix;
19
+ tokenExpiration;
20
+ refreshExpiration;
21
+ constructor(options = {}) {
22
+ const url = options.url || `redis://${options.host || "localhost"}:${options.port || 6379}`;
23
+ this.redis = new Redis__default.default(url, {
24
+ password: options.password,
25
+ db: options.db,
26
+ lazyConnect: true,
27
+ tls: options.tls ? {} : void 0
28
+ });
29
+ this.prefix = options.keyPrefix || DEFAULT_PREFIX;
30
+ this.tokenExpiration = options.tokenExpiration || DEFAULT_TOKEN_EXPIRATION;
31
+ this.refreshExpiration = options.refreshTokenExpiration || DEFAULT_REFRESH_EXPIRATION;
32
+ }
33
+ async connect() {
34
+ await this.redis.connect();
35
+ }
36
+ async disconnect() {
37
+ await this.redis.quit();
38
+ }
39
+ userKey(userId) {
40
+ return `${this.prefix}users:${userId}`;
41
+ }
42
+ sessionKey(sessionId) {
43
+ return `${this.prefix}sessions:${sessionId}`;
44
+ }
45
+ refreshKey(token) {
46
+ return `${this.prefix}refresh:${token}`;
47
+ }
48
+ userByEmailKey(email) {
49
+ return `${this.prefix}users:email:${email.toLowerCase()}`;
50
+ }
51
+ passwordHistoryKey(userId) {
52
+ return `${this.prefix}users:${userId}:password_history`;
53
+ }
54
+ async createUser(data) {
55
+ const userId = crypto.randomBytes(16).toString("hex");
56
+ const now = (/* @__PURE__ */ new Date()).toISOString();
57
+ const user = {
58
+ id: userId,
59
+ email: data.email.toLowerCase(),
60
+ passwordHash: data.passwordHash,
61
+ role: data.role || "customer",
62
+ tenantId: data.tenantId,
63
+ createdAt: now,
64
+ updatedAt: now
65
+ };
66
+ const pipeline = this.redis.pipeline();
67
+ pipeline.hset(this.userKey(userId), this.userToHash(user));
68
+ pipeline.set(this.userByEmailKey(data.email), userId);
69
+ await pipeline.exec();
70
+ return user;
71
+ }
72
+ async findUserByEmail(email) {
73
+ const userId = await this.redis.get(
74
+ this.userByEmailKey(email.toLowerCase())
75
+ );
76
+ if (!userId) return null;
77
+ return this.findUserById(userId);
78
+ }
79
+ async findUserById(userId) {
80
+ const data = await this.redis.hgetall(this.userKey(userId));
81
+ if (!data || Object.keys(data).length === 0) return null;
82
+ return this.hashToUser(data);
83
+ }
84
+ async updateUser(userId, data) {
85
+ const existing = await this.findUserById(userId);
86
+ if (!existing) return null;
87
+ const updated = {
88
+ ...existing,
89
+ ...data,
90
+ id: userId,
91
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
92
+ };
93
+ if (data.email && data.email !== existing.email) {
94
+ const pipeline = this.redis.pipeline();
95
+ pipeline.del(this.userByEmailKey(existing.email));
96
+ pipeline.set(this.userByEmailKey(data.email), userId);
97
+ await pipeline.exec();
98
+ }
99
+ await this.redis.hset(this.userKey(userId), this.userToHash(updated));
100
+ return updated;
101
+ }
102
+ async deleteUser(userId) {
103
+ const user = await this.findUserById(userId);
104
+ if (!user) return false;
105
+ const pipeline = this.redis.pipeline();
106
+ pipeline.del(this.userKey(userId));
107
+ pipeline.del(this.userByEmailKey(user.email));
108
+ pipeline.del(this.passwordHistoryKey(userId));
109
+ await pipeline.exec();
110
+ return true;
111
+ }
112
+ async hashPassword(password) {
113
+ return bcrypt__default.default.hash(password, 12);
114
+ }
115
+ async verifyPassword(password, hash) {
116
+ return bcrypt__default.default.compare(password, hash);
117
+ }
118
+ async createSession(userId, data = {}) {
119
+ const sessionId = crypto.randomBytes(32).toString("hex");
120
+ const token = crypto.randomBytes(32).toString("base64url");
121
+ const refreshToken = crypto.randomBytes(32).toString("base64url");
122
+ const now = /* @__PURE__ */ new Date();
123
+ const session = {
124
+ id: sessionId,
125
+ userId,
126
+ token,
127
+ refreshToken,
128
+ expiresAt: new Date(
129
+ now.getTime() + this.tokenExpiration * 1e3
130
+ ).toISOString(),
131
+ createdAt: now.toISOString(),
132
+ ipAddress: data.ipAddress,
133
+ userAgent: data.userAgent
134
+ };
135
+ const pipeline = this.redis.pipeline();
136
+ pipeline.hset(this.sessionKey(sessionId), this.sessionToHash(session));
137
+ pipeline.setex(
138
+ this.refreshKey(refreshToken),
139
+ this.refreshExpiration,
140
+ sessionId
141
+ );
142
+ await pipeline.exec();
143
+ return session;
144
+ }
145
+ async findSessionByToken(token) {
146
+ const data = await this.redis.hgetall(this.sessionKey(token));
147
+ if (!data || Object.keys(data).length === 0) return null;
148
+ return this.hashToSession(data);
149
+ }
150
+ async deleteSession(sessionId) {
151
+ const session = await this.redis.hgetall(this.sessionKey(sessionId));
152
+ if (!session || Object.keys(session).length === 0) return false;
153
+ const pipeline = this.redis.pipeline();
154
+ pipeline.del(this.sessionKey(sessionId));
155
+ if (session.refreshToken) {
156
+ pipeline.del(this.refreshKey(session.refreshToken));
157
+ }
158
+ await pipeline.exec();
159
+ return true;
160
+ }
161
+ async deleteUserSessions(userId) {
162
+ const pattern = `${this.prefix}sessions:*`;
163
+ let cursor = "0";
164
+ let deleted = 0;
165
+ do {
166
+ const [nextCursor, keys] = await this.redis.scan(
167
+ cursor,
168
+ "MATCH",
169
+ pattern,
170
+ "COUNT",
171
+ 100
172
+ );
173
+ cursor = nextCursor;
174
+ for (const key of keys) {
175
+ const sessionData = await this.redis.hgetall(key);
176
+ if (sessionData.userId === userId) {
177
+ const sessionId = key.replace(`${this.prefix}sessions:`, "");
178
+ await this.deleteSession(sessionId);
179
+ deleted++;
180
+ }
181
+ }
182
+ } while (cursor !== "0");
183
+ return deleted;
184
+ }
185
+ async addPasswordToHistory(userId, passwordHash) {
186
+ await this.redis.lpush(this.passwordHistoryKey(userId), passwordHash);
187
+ await this.redis.ltrim(this.passwordHistoryKey(userId), 0, 4);
188
+ }
189
+ async getPasswordHistory(userId, count = 5) {
190
+ return this.redis.lrange(this.passwordHistoryKey(userId), 0, count - 1);
191
+ }
192
+ async isPasswordInHistory(password, userId, historyCount = 5) {
193
+ const history = await this.getPasswordHistory(userId, historyCount);
194
+ for (const hash of history) {
195
+ if (await this.verifyPassword(password, hash)) {
196
+ return true;
197
+ }
198
+ }
199
+ return false;
200
+ }
201
+ userToHash(user) {
202
+ const hash = {
203
+ id: user.id,
204
+ email: user.email,
205
+ passwordHash: user.passwordHash || "",
206
+ role: user.role,
207
+ createdAt: user.createdAt,
208
+ updatedAt: user.updatedAt
209
+ };
210
+ if (user.tenantId) hash.tenantId = user.tenantId;
211
+ if (user.emailVerified !== void 0)
212
+ hash.emailVerified = String(user.emailVerified);
213
+ if (user.locked !== void 0) hash.locked = String(user.locked);
214
+ if (user.lastLogin) hash.lastLogin = user.lastLogin;
215
+ if (user.failedLoginAttempts !== void 0)
216
+ hash.failedLoginAttempts = String(user.failedLoginAttempts);
217
+ return hash;
218
+ }
219
+ hashToUser(hash) {
220
+ return {
221
+ id: hash.id,
222
+ email: hash.email,
223
+ passwordHash: hash.passwordHash,
224
+ role: hash.role,
225
+ tenantId: hash.tenantId,
226
+ createdAt: hash.createdAt,
227
+ updatedAt: hash.updatedAt,
228
+ emailVerified: hash.emailVerified === "true",
229
+ locked: hash.locked === "true",
230
+ lastLogin: hash.lastLogin,
231
+ failedLoginAttempts: hash.failedLoginAttempts ? parseInt(hash.failedLoginAttempts, 10) : 0
232
+ };
233
+ }
234
+ sessionToHash(session) {
235
+ const hash = {
236
+ id: session.id,
237
+ userId: session.userId,
238
+ token: session.token,
239
+ expiresAt: session.expiresAt,
240
+ createdAt: session.createdAt
241
+ };
242
+ if (session.refreshToken) hash.refreshToken = session.refreshToken;
243
+ if (session.ipAddress) hash.ipAddress = session.ipAddress;
244
+ if (session.userAgent) hash.userAgent = session.userAgent;
245
+ return hash;
246
+ }
247
+ hashToSession(hash) {
248
+ return {
249
+ id: hash.id,
250
+ userId: hash.userId,
251
+ token: hash.token,
252
+ refreshToken: hash.refreshToken,
253
+ expiresAt: hash.expiresAt,
254
+ createdAt: hash.createdAt,
255
+ ipAddress: hash.ipAddress,
256
+ userAgent: hash.userAgent
257
+ };
258
+ }
259
+ };
260
+
261
+ exports.RedisAuthAdapter = RedisAuthAdapter;
262
+ //# sourceMappingURL=chunk-A3RQWHKD.cjs.map
263
+ //# sourceMappingURL=chunk-A3RQWHKD.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/redis-adapter.ts"],"names":["Redis","randomBytes","bcrypt"],"mappings":"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","file":"chunk-A3RQWHKD.cjs","sourcesContent":["import Redis from \"ioredis\";\nimport type { AuthAdapter, AuthUser, Session, UserRole } from \"./types.js\";\nimport bcrypt from \"bcryptjs\";\nimport { randomBytes } from \"crypto\";\n\nexport interface RedisAuthAdapterOptions {\n url?: string;\n host?: string;\n port?: number;\n password?: string;\n db?: number;\n keyPrefix?: string;\n tokenExpiration?: number;\n refreshTokenExpiration?: number;\n tls?: boolean;\n}\n\nconst DEFAULT_PREFIX = \"kyro:auth:\";\nconst DEFAULT_TOKEN_EXPIRATION = 86400;\nconst DEFAULT_REFRESH_EXPIRATION = 604800;\n\nexport class RedisAuthAdapter implements AuthAdapter {\n private redis: Redis;\n private prefix: string;\n private tokenExpiration: number;\n private refreshExpiration: number;\n\n constructor(options: RedisAuthAdapterOptions = {}) {\n const url =\n options.url ||\n `redis://${options.host || \"localhost\"}:${options.port || 6379}`;\n\n this.redis = new Redis(url, {\n password: options.password,\n db: options.db,\n lazyConnect: true,\n tls: options.tls ? {} : undefined,\n });\n\n this.prefix = options.keyPrefix || DEFAULT_PREFIX;\n this.tokenExpiration = options.tokenExpiration || DEFAULT_TOKEN_EXPIRATION;\n this.refreshExpiration =\n options.refreshTokenExpiration || DEFAULT_REFRESH_EXPIRATION;\n }\n\n async connect(): Promise<void> {\n await this.redis.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.redis.quit();\n }\n\n private userKey(userId: string): string {\n return `${this.prefix}users:${userId}`;\n }\n\n private sessionKey(sessionId: string): string {\n return `${this.prefix}sessions:${sessionId}`;\n }\n\n private refreshKey(token: string): string {\n return `${this.prefix}refresh:${token}`;\n }\n\n private userByEmailKey(email: string): string {\n return `${this.prefix}users:email:${email.toLowerCase()}`;\n }\n\n private passwordHistoryKey(userId: string): string {\n return `${this.prefix}users:${userId}:password_history`;\n }\n\n async createUser(data: {\n email: string;\n passwordHash: string;\n role?: UserRole;\n tenantId?: string;\n }): Promise<AuthUser> {\n const userId = randomBytes(16).toString(\"hex\");\n const now = new Date().toISOString();\n\n const user: AuthUser = {\n id: userId,\n email: data.email.toLowerCase(),\n passwordHash: data.passwordHash,\n role: (data.role || \"customer\") as UserRole,\n tenantId: data.tenantId,\n createdAt: now,\n updatedAt: now,\n };\n\n const pipeline = this.redis.pipeline();\n\n pipeline.hset(this.userKey(userId), this.userToHash(user));\n pipeline.set(this.userByEmailKey(data.email), userId);\n\n await pipeline.exec();\n\n return user;\n }\n\n async findUserByEmail(email: string): Promise<AuthUser | null> {\n const userId = await this.redis.get(\n this.userByEmailKey(email.toLowerCase()),\n );\n if (!userId) return null;\n return this.findUserById(userId);\n }\n\n async findUserById(userId: string): Promise<AuthUser | null> {\n const data = await this.redis.hgetall(this.userKey(userId));\n if (!data || Object.keys(data).length === 0) return null;\n return this.hashToUser(data);\n }\n\n async updateUser(\n userId: string,\n data: Partial<AuthUser>,\n ): Promise<AuthUser | null> {\n const existing = await this.findUserById(userId);\n if (!existing) return null;\n\n const updated: AuthUser = {\n ...existing,\n ...data,\n id: userId,\n updatedAt: new Date().toISOString(),\n };\n\n if (data.email && data.email !== existing.email) {\n const pipeline = this.redis.pipeline();\n pipeline.del(this.userByEmailKey(existing.email));\n pipeline.set(this.userByEmailKey(data.email), userId);\n await pipeline.exec();\n }\n\n await this.redis.hset(this.userKey(userId), this.userToHash(updated));\n return updated;\n }\n\n async deleteUser(userId: string): Promise<boolean> {\n const user = await this.findUserById(userId);\n if (!user) return false;\n\n const pipeline = this.redis.pipeline();\n pipeline.del(this.userKey(userId));\n pipeline.del(this.userByEmailKey(user.email));\n pipeline.del(this.passwordHistoryKey(userId));\n await pipeline.exec();\n\n return true;\n }\n\n async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, 12);\n }\n\n async verifyPassword(password: string, hash: string): Promise<boolean> {\n return bcrypt.compare(password, hash);\n }\n\n async createSession(\n userId: string,\n data: {\n ipAddress?: string;\n userAgent?: string;\n } = {},\n ): Promise<Session> {\n const sessionId = randomBytes(32).toString(\"hex\");\n const token = randomBytes(32).toString(\"base64url\");\n const refreshToken = randomBytes(32).toString(\"base64url\");\n const now = new Date();\n\n const session: Session = {\n id: sessionId,\n userId,\n token,\n refreshToken,\n expiresAt: new Date(\n now.getTime() + this.tokenExpiration * 1000,\n ).toISOString(),\n createdAt: now.toISOString(),\n ipAddress: data.ipAddress,\n userAgent: data.userAgent,\n };\n\n const pipeline = this.redis.pipeline();\n\n pipeline.hset(this.sessionKey(sessionId), this.sessionToHash(session));\n pipeline.setex(\n this.refreshKey(refreshToken),\n this.refreshExpiration,\n sessionId,\n );\n\n await pipeline.exec();\n\n return session;\n }\n\n async findSessionByToken(token: string): Promise<Session | null> {\n const data = await this.redis.hgetall(this.sessionKey(token));\n if (!data || Object.keys(data).length === 0) return null;\n return this.hashToSession(data);\n }\n\n async deleteSession(sessionId: string): Promise<boolean> {\n const session = await this.redis.hgetall(this.sessionKey(sessionId));\n if (!session || Object.keys(session).length === 0) return false;\n\n const pipeline = this.redis.pipeline();\n pipeline.del(this.sessionKey(sessionId));\n if (session.refreshToken) {\n pipeline.del(this.refreshKey(session.refreshToken));\n }\n await pipeline.exec();\n\n return true;\n }\n\n async deleteUserSessions(userId: string): Promise<number> {\n const pattern = `${this.prefix}sessions:*`;\n let cursor = \"0\";\n let deleted = 0;\n\n do {\n const [nextCursor, keys] = await this.redis.scan(\n cursor,\n \"MATCH\",\n pattern,\n \"COUNT\",\n 100,\n );\n cursor = nextCursor;\n\n for (const key of keys) {\n const sessionData = await this.redis.hgetall(key);\n if (sessionData.userId === userId) {\n const sessionId = key.replace(`${this.prefix}sessions:`, \"\");\n await this.deleteSession(sessionId);\n deleted++;\n }\n }\n } while (cursor !== \"0\");\n\n return deleted;\n }\n\n async addPasswordToHistory(\n userId: string,\n passwordHash: string,\n ): Promise<void> {\n await this.redis.lpush(this.passwordHistoryKey(userId), passwordHash);\n await this.redis.ltrim(this.passwordHistoryKey(userId), 0, 4);\n }\n\n async getPasswordHistory(\n userId: string,\n count: number = 5,\n ): Promise<string[]> {\n return this.redis.lrange(this.passwordHistoryKey(userId), 0, count - 1);\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 private userToHash(user: AuthUser): Record<string, string> {\n const hash: Record<string, string> = {\n id: user.id,\n email: user.email,\n passwordHash: user.passwordHash || \"\",\n role: user.role,\n createdAt: user.createdAt,\n updatedAt: user.updatedAt,\n };\n\n if (user.tenantId) hash.tenantId = user.tenantId;\n if (user.emailVerified !== undefined)\n hash.emailVerified = String(user.emailVerified);\n if (user.locked !== undefined) hash.locked = String(user.locked);\n if (user.lastLogin) hash.lastLogin = user.lastLogin;\n if (user.failedLoginAttempts !== undefined)\n hash.failedLoginAttempts = String(user.failedLoginAttempts);\n\n return hash;\n }\n\n private hashToUser(hash: Record<string, string>): AuthUser {\n return {\n id: hash.id,\n email: hash.email,\n passwordHash: hash.passwordHash,\n role: hash.role as UserRole,\n tenantId: hash.tenantId,\n createdAt: hash.createdAt,\n updatedAt: hash.updatedAt,\n emailVerified: hash.emailVerified === \"true\",\n locked: hash.locked === \"true\",\n lastLogin: hash.lastLogin,\n failedLoginAttempts: hash.failedLoginAttempts\n ? parseInt(hash.failedLoginAttempts, 10)\n : 0,\n };\n }\n\n private sessionToHash(session: Session): Record<string, string> {\n const hash: Record<string, string> = {\n id: session.id,\n userId: session.userId,\n token: session.token,\n expiresAt: session.expiresAt,\n createdAt: session.createdAt,\n };\n\n if (session.refreshToken) hash.refreshToken = session.refreshToken;\n if (session.ipAddress) hash.ipAddress = session.ipAddress;\n if (session.userAgent) hash.userAgent = session.userAgent;\n\n return hash;\n }\n\n private hashToSession(hash: Record<string, string>): Session {\n return {\n id: hash.id,\n userId: hash.userId,\n token: hash.token,\n refreshToken: hash.refreshToken,\n expiresAt: hash.expiresAt,\n createdAt: hash.createdAt,\n ipAddress: hash.ipAddress,\n userAgent: hash.userAgent,\n };\n }\n}\n"]}