@blackms/aistack 1.3.0 → 1.3.1

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 (144) hide show
  1. package/dist/agents/definitions/devops.d.ts +6 -0
  2. package/dist/agents/definitions/devops.d.ts.map +1 -0
  3. package/dist/agents/definitions/devops.js +65 -0
  4. package/dist/agents/definitions/devops.js.map +1 -0
  5. package/dist/agents/definitions/documentation.d.ts +6 -0
  6. package/dist/agents/definitions/documentation.d.ts.map +1 -0
  7. package/dist/agents/definitions/documentation.js +72 -0
  8. package/dist/agents/definitions/documentation.js.map +1 -0
  9. package/dist/agents/definitions/index.d.ts +3 -0
  10. package/dist/agents/definitions/index.d.ts.map +1 -1
  11. package/dist/agents/definitions/index.js +3 -0
  12. package/dist/agents/definitions/index.js.map +1 -1
  13. package/dist/agents/definitions/security-auditor.d.ts +6 -0
  14. package/dist/agents/definitions/security-auditor.d.ts.map +1 -0
  15. package/dist/agents/definitions/security-auditor.js +100 -0
  16. package/dist/agents/definitions/security-auditor.js.map +1 -0
  17. package/dist/agents/registry.d.ts.map +1 -1
  18. package/dist/agents/registry.js +4 -1
  19. package/dist/agents/registry.js.map +1 -1
  20. package/dist/agents/spawner.d.ts +26 -1
  21. package/dist/agents/spawner.d.ts.map +1 -1
  22. package/dist/agents/spawner.js +94 -1
  23. package/dist/agents/spawner.js.map +1 -1
  24. package/dist/auth/index.d.ts +6 -0
  25. package/dist/auth/index.d.ts.map +1 -0
  26. package/dist/auth/index.js +6 -0
  27. package/dist/auth/index.js.map +1 -0
  28. package/dist/auth/service.d.ts +79 -0
  29. package/dist/auth/service.d.ts.map +1 -0
  30. package/dist/auth/service.js +383 -0
  31. package/dist/auth/service.js.map +1 -0
  32. package/dist/auth/types.d.ts +48 -0
  33. package/dist/auth/types.d.ts.map +1 -0
  34. package/dist/auth/types.js +10 -0
  35. package/dist/auth/types.js.map +1 -0
  36. package/dist/coordination/review-loop.d.ts +4 -0
  37. package/dist/coordination/review-loop.d.ts.map +1 -1
  38. package/dist/coordination/review-loop.js +54 -19
  39. package/dist/coordination/review-loop.js.map +1 -1
  40. package/dist/integrations/slack-notifier.d.ts +63 -0
  41. package/dist/integrations/slack-notifier.d.ts.map +1 -0
  42. package/dist/integrations/slack-notifier.js +224 -0
  43. package/dist/integrations/slack-notifier.js.map +1 -0
  44. package/dist/integrations/slack.d.ts +50 -0
  45. package/dist/integrations/slack.d.ts.map +1 -0
  46. package/dist/integrations/slack.js +225 -0
  47. package/dist/integrations/slack.js.map +1 -0
  48. package/dist/memory/index.d.ts +75 -0
  49. package/dist/memory/index.d.ts.map +1 -1
  50. package/dist/memory/index.js +101 -0
  51. package/dist/memory/index.js.map +1 -1
  52. package/dist/memory/sqlite-store.d.ts +85 -1
  53. package/dist/memory/sqlite-store.d.ts.map +1 -1
  54. package/dist/memory/sqlite-store.js +647 -15
  55. package/dist/memory/sqlite-store.js.map +1 -1
  56. package/dist/monitoring/health.d.ts +68 -0
  57. package/dist/monitoring/health.d.ts.map +1 -0
  58. package/dist/monitoring/health.js +220 -0
  59. package/dist/monitoring/health.js.map +1 -0
  60. package/dist/monitoring/metrics.d.ts +31 -0
  61. package/dist/monitoring/metrics.d.ts.map +1 -0
  62. package/dist/monitoring/metrics.js +230 -0
  63. package/dist/monitoring/metrics.js.map +1 -0
  64. package/dist/providers/index.d.ts.map +1 -1
  65. package/dist/providers/index.js +132 -94
  66. package/dist/providers/index.js.map +1 -1
  67. package/dist/types.d.ts +36 -2
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/types.js.map +1 -1
  70. package/dist/utils/config.d.ts.map +1 -1
  71. package/dist/utils/config.js +12 -0
  72. package/dist/utils/config.js.map +1 -1
  73. package/dist/utils/index.d.ts +1 -1
  74. package/dist/utils/index.d.ts.map +1 -1
  75. package/dist/utils/index.js +1 -1
  76. package/dist/utils/index.js.map +1 -1
  77. package/dist/utils/logger.d.ts +24 -7
  78. package/dist/utils/logger.d.ts.map +1 -1
  79. package/dist/utils/logger.js +128 -20
  80. package/dist/utils/logger.js.map +1 -1
  81. package/dist/utils/retry.d.ts +49 -0
  82. package/dist/utils/retry.d.ts.map +1 -0
  83. package/dist/utils/retry.js +160 -0
  84. package/dist/utils/retry.js.map +1 -0
  85. package/dist/utils/semaphore.d.ts +75 -0
  86. package/dist/utils/semaphore.d.ts.map +1 -0
  87. package/dist/utils/semaphore.js +185 -0
  88. package/dist/utils/semaphore.js.map +1 -0
  89. package/dist/utils/validation.d.ts +2 -2
  90. package/dist/web/middleware/auth.d.ts +16 -10
  91. package/dist/web/middleware/auth.d.ts.map +1 -1
  92. package/dist/web/middleware/auth.js +152 -12
  93. package/dist/web/middleware/auth.js.map +1 -1
  94. package/dist/web/routes/auth.d.ts +50 -0
  95. package/dist/web/routes/auth.d.ts.map +1 -0
  96. package/dist/web/routes/auth.js +216 -0
  97. package/dist/web/routes/auth.js.map +1 -0
  98. package/dist/web/routes/index.d.ts +2 -0
  99. package/dist/web/routes/index.d.ts.map +1 -1
  100. package/dist/web/routes/index.js +2 -0
  101. package/dist/web/routes/index.js.map +1 -1
  102. package/dist/web/routes/memory.d.ts.map +1 -1
  103. package/dist/web/routes/memory.js +188 -0
  104. package/dist/web/routes/memory.js.map +1 -1
  105. package/dist/web/routes/review-loops.d.ts +12 -0
  106. package/dist/web/routes/review-loops.d.ts.map +1 -0
  107. package/dist/web/routes/review-loops.js +157 -0
  108. package/dist/web/routes/review-loops.js.map +1 -0
  109. package/dist/web/routes/sessions.d.ts.map +1 -1
  110. package/dist/web/routes/sessions.js +14 -0
  111. package/dist/web/routes/sessions.js.map +1 -1
  112. package/dist/web/routes/system.d.ts.map +1 -1
  113. package/dist/web/routes/system.js +34 -23
  114. package/dist/web/routes/system.js.map +1 -1
  115. package/dist/web/routes/workflows.d.ts.map +1 -1
  116. package/dist/web/routes/workflows.js +13 -1
  117. package/dist/web/routes/workflows.js.map +1 -1
  118. package/dist/web/server.d.ts +1 -0
  119. package/dist/web/server.d.ts.map +1 -1
  120. package/dist/web/server.js +30 -2
  121. package/dist/web/server.js.map +1 -1
  122. package/dist/web/utils/request.d.ts +13 -0
  123. package/dist/web/utils/request.d.ts.map +1 -0
  124. package/dist/web/utils/request.js +49 -0
  125. package/dist/web/utils/request.js.map +1 -0
  126. package/dist/web/websocket/handler.d.ts +4 -0
  127. package/dist/web/websocket/handler.d.ts.map +1 -1
  128. package/dist/web/websocket/handler.js +59 -0
  129. package/dist/web/websocket/handler.js.map +1 -1
  130. package/dist/workflows/doc-sync.d.ts.map +1 -1
  131. package/dist/workflows/doc-sync.js +4 -0
  132. package/dist/workflows/doc-sync.js.map +1 -1
  133. package/dist/workflows/full-stack-feature.d.ts +74 -0
  134. package/dist/workflows/full-stack-feature.d.ts.map +1 -0
  135. package/dist/workflows/full-stack-feature.js +273 -0
  136. package/dist/workflows/full-stack-feature.js.map +1 -0
  137. package/dist/workflows/index.d.ts +1 -0
  138. package/dist/workflows/index.d.ts.map +1 -1
  139. package/dist/workflows/index.js +2 -0
  140. package/dist/workflows/index.js.map +1 -1
  141. package/dist/workflows/runner.js.map +1 -1
  142. package/dist/workflows/types.d.ts +6 -5
  143. package/dist/workflows/types.d.ts.map +1 -1
  144. package/package.json +12 -5
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Authentication service
3
+ */
4
+ import type Database from 'better-sqlite3';
5
+ import type { User, AuthTokens, JWTPayload, LoginCredentials, RegisterData, UserRole } from './types.js';
6
+ export declare class AuthService {
7
+ private db;
8
+ private jwtSecret;
9
+ private refreshSecret;
10
+ constructor(db: Database.Database, jwtSecret?: string, refreshSecret?: string);
11
+ /**
12
+ * Initialize database schema for authentication
13
+ */
14
+ private initDatabase;
15
+ /**
16
+ * Create default admin user
17
+ */
18
+ private createDefaultAdmin;
19
+ /**
20
+ * Generate a secure random secret
21
+ */
22
+ private generateSecret;
23
+ /**
24
+ * Register a new user
25
+ */
26
+ register(data: RegisterData, role?: UserRole): Promise<User>;
27
+ /**
28
+ * Authenticate user and generate tokens
29
+ */
30
+ login(credentials: LoginCredentials): Promise<{
31
+ user: User;
32
+ tokens: AuthTokens;
33
+ }>;
34
+ /**
35
+ * Generate access and refresh tokens
36
+ */
37
+ private generateTokens;
38
+ /**
39
+ * Store refresh token in database
40
+ */
41
+ private storeRefreshToken;
42
+ /**
43
+ * Verify access token
44
+ */
45
+ verifyAccessToken(token: string): JWTPayload;
46
+ /**
47
+ * Refresh access token using refresh token
48
+ */
49
+ refreshAccessToken(refreshToken: string): Promise<AuthTokens>;
50
+ /**
51
+ * Revoke refresh token (logout)
52
+ */
53
+ logout(refreshToken: string): Promise<void>;
54
+ /**
55
+ * Get user by ID
56
+ */
57
+ getUserById(userId: string): User | undefined;
58
+ /**
59
+ * Get user by email
60
+ */
61
+ getUserByEmail(email: string): User | undefined;
62
+ /**
63
+ * List all users (admin only)
64
+ */
65
+ listUsers(): Array<Omit<User, 'passwordHash'>>;
66
+ /**
67
+ * Update user role (admin only)
68
+ */
69
+ updateUserRole(userId: string, role: UserRole): void;
70
+ /**
71
+ * Delete user (admin only)
72
+ */
73
+ deleteUser(userId: string): void;
74
+ /**
75
+ * Change user password
76
+ */
77
+ changePassword(userId: string, oldPassword: string, newPassword: string): Promise<void>;
78
+ }
79
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/auth/service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EACV,IAAI,EACJ,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACT,MAAM,YAAY,CAAC;AAQpB,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;gBAG5B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,CAAC,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM;IAaxB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6CpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,GAAE,QAAkC,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC3F;;OAEG;IACG,KAAK,CAAC,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;IAiDvF;;OAEG;IACH,OAAO,CAAC,cAAc;IAuBtB;;OAEG;YACW,iBAAiB;IAuB/B;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAe5C;;OAEG;IACG,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAoDnE;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAejD;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAmB7C;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAmB/C;;OAEG;IACH,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAc9C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAQpD;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKhC;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAkC9F"}
@@ -0,0 +1,383 @@
1
+ /**
2
+ * Authentication service
3
+ */
4
+ import { randomUUID } from 'node:crypto';
5
+ import jwt from 'jsonwebtoken';
6
+ import bcrypt from 'bcrypt';
7
+ import { logger } from '../utils/logger.js';
8
+ const log = logger.child('auth');
9
+ const SALT_ROUNDS = 10;
10
+ const ACCESS_TOKEN_EXPIRY = '15m'; // 15 minutes
11
+ const REFRESH_TOKEN_EXPIRY = '7d'; // 7 days
12
+ export class AuthService {
13
+ db;
14
+ jwtSecret;
15
+ refreshSecret;
16
+ constructor(db, jwtSecret, refreshSecret) {
17
+ this.db = db;
18
+ this.jwtSecret = jwtSecret || process.env.JWT_SECRET || this.generateSecret();
19
+ this.refreshSecret = refreshSecret || process.env.REFRESH_SECRET || this.generateSecret();
20
+ if (!process.env.JWT_SECRET) {
21
+ log.warn('No JWT_SECRET set, using generated secret (not suitable for production)');
22
+ }
23
+ this.initDatabase();
24
+ }
25
+ /**
26
+ * Initialize database schema for authentication
27
+ */
28
+ initDatabase() {
29
+ this.db.exec(`
30
+ CREATE TABLE IF NOT EXISTS users (
31
+ id TEXT PRIMARY KEY,
32
+ email TEXT UNIQUE NOT NULL,
33
+ username TEXT UNIQUE NOT NULL,
34
+ password_hash TEXT NOT NULL,
35
+ role TEXT NOT NULL DEFAULT 'developer',
36
+ created_at TEXT NOT NULL,
37
+ updated_at TEXT NOT NULL,
38
+ last_login_at TEXT
39
+ );
40
+
41
+ CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
42
+ CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
43
+
44
+ CREATE TABLE IF NOT EXISTS refresh_tokens (
45
+ id TEXT PRIMARY KEY,
46
+ user_id TEXT NOT NULL,
47
+ token_hash TEXT NOT NULL,
48
+ expires_at TEXT NOT NULL,
49
+ created_at TEXT NOT NULL,
50
+ revoked INTEGER DEFAULT 0,
51
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
52
+ );
53
+
54
+ CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id);
55
+ CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires ON refresh_tokens(expires_at);
56
+ `);
57
+ // Create default admin user if no users exist
58
+ const userCount = this.db
59
+ .prepare('SELECT COUNT(*) as count FROM users')
60
+ .get();
61
+ if (userCount.count === 0) {
62
+ log.info('Creating default admin user');
63
+ try {
64
+ this.createDefaultAdmin();
65
+ }
66
+ catch (error) {
67
+ log.error('Failed to create default admin user', { error });
68
+ }
69
+ }
70
+ }
71
+ /**
72
+ * Create default admin user
73
+ */
74
+ createDefaultAdmin() {
75
+ const defaultPassword = process.env.ADMIN_PASSWORD || 'admin123';
76
+ const passwordHash = bcrypt.hashSync(defaultPassword, SALT_ROUNDS);
77
+ this.db
78
+ .prepare(`INSERT INTO users (id, email, username, password_hash, role, created_at, updated_at)
79
+ VALUES (?, ?, ?, ?, ?, ?, ?)`)
80
+ .run(randomUUID(), 'admin@aistack.local', 'admin', passwordHash, 'admin', new Date().toISOString(), new Date().toISOString());
81
+ log.info('Default admin user created', {
82
+ email: 'admin@aistack.local',
83
+ password: defaultPassword,
84
+ });
85
+ }
86
+ /**
87
+ * Generate a secure random secret
88
+ */
89
+ generateSecret() {
90
+ return randomUUID() + randomUUID();
91
+ }
92
+ /**
93
+ * Register a new user
94
+ */
95
+ async register(data, role = 'developer') {
96
+ // Validate input
97
+ if (!data.email || !data.username || !data.password) {
98
+ throw new Error('Email, username, and password are required');
99
+ }
100
+ if (data.password.length < 8) {
101
+ throw new Error('Password must be at least 8 characters');
102
+ }
103
+ // Check if user already exists
104
+ const existing = this.db
105
+ .prepare('SELECT id FROM users WHERE email = ? OR username = ?')
106
+ .get(data.email, data.username);
107
+ if (existing) {
108
+ throw new Error('User with this email or username already exists');
109
+ }
110
+ // Hash password
111
+ const passwordHash = await bcrypt.hash(data.password, SALT_ROUNDS);
112
+ // Create user
113
+ const userId = randomUUID();
114
+ const now = new Date().toISOString();
115
+ this.db
116
+ .prepare(`INSERT INTO users (id, email, username, password_hash, role, created_at, updated_at)
117
+ VALUES (?, ?, ?, ?, ?, ?, ?)`)
118
+ .run(userId, data.email, data.username, passwordHash, role, now, now);
119
+ log.info('User registered', { userId, email: data.email, username: data.username });
120
+ return this.getUserById(userId);
121
+ }
122
+ /**
123
+ * Authenticate user and generate tokens
124
+ */
125
+ async login(credentials) {
126
+ // Find user
127
+ const user = this.getUserByEmail(credentials.email);
128
+ if (!user) {
129
+ throw new Error('Invalid email or password');
130
+ }
131
+ // Verify password
132
+ const valid = await bcrypt.compare(credentials.password, user.passwordHash);
133
+ if (!valid) {
134
+ throw new Error('Invalid email or password');
135
+ }
136
+ // Generate tokens
137
+ const tokens = this.generateTokens(user);
138
+ // Use transaction to ensure atomic update of last login and token storage
139
+ const now = new Date().toISOString();
140
+ const tokenHash = await bcrypt.hash(tokens.refreshToken, SALT_ROUNDS);
141
+ const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString();
142
+ const transaction = this.db.transaction(() => {
143
+ // Update last login
144
+ this.db
145
+ .prepare('UPDATE users SET last_login_at = ? WHERE id = ?')
146
+ .run(now, user.id);
147
+ // Store refresh token
148
+ this.db
149
+ .prepare(`INSERT INTO refresh_tokens (id, user_id, token_hash, expires_at, created_at)
150
+ VALUES (?, ?, ?, ?, ?)`)
151
+ .run(randomUUID(), user.id, tokenHash, expiresAt, now);
152
+ // Clean up expired tokens
153
+ this.db
154
+ .prepare('DELETE FROM refresh_tokens WHERE expires_at < ? OR revoked = 1')
155
+ .run(now);
156
+ });
157
+ transaction();
158
+ log.info('User logged in', { userId: user.id, email: user.email });
159
+ return { user, tokens };
160
+ }
161
+ /**
162
+ * Generate access and refresh tokens
163
+ */
164
+ generateTokens(user) {
165
+ const payload = {
166
+ userId: user.id,
167
+ email: user.email,
168
+ username: user.username,
169
+ role: user.role,
170
+ };
171
+ const accessToken = jwt.sign(payload, this.jwtSecret, {
172
+ expiresIn: ACCESS_TOKEN_EXPIRY,
173
+ });
174
+ const refreshToken = jwt.sign({ userId: user.id }, this.refreshSecret, {
175
+ expiresIn: REFRESH_TOKEN_EXPIRY,
176
+ });
177
+ return {
178
+ accessToken,
179
+ refreshToken,
180
+ expiresIn: 15 * 60, // 15 minutes in seconds
181
+ };
182
+ }
183
+ /**
184
+ * Store refresh token in database
185
+ */
186
+ async storeRefreshToken(userId, token) {
187
+ const tokenHash = await bcrypt.hash(token, SALT_ROUNDS);
188
+ const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(); // 7 days
189
+ const now = new Date().toISOString();
190
+ // Use transaction to ensure atomic insert and cleanup
191
+ const transaction = this.db.transaction(() => {
192
+ this.db
193
+ .prepare(`INSERT INTO refresh_tokens (id, user_id, token_hash, expires_at, created_at)
194
+ VALUES (?, ?, ?, ?, ?)`)
195
+ .run(randomUUID(), userId, tokenHash, expiresAt, now);
196
+ // Clean up expired tokens
197
+ this.db
198
+ .prepare('DELETE FROM refresh_tokens WHERE expires_at < ? OR revoked = 1')
199
+ .run(now);
200
+ });
201
+ transaction();
202
+ }
203
+ /**
204
+ * Verify access token
205
+ */
206
+ verifyAccessToken(token) {
207
+ try {
208
+ const payload = jwt.verify(token, this.jwtSecret);
209
+ return payload;
210
+ }
211
+ catch (error) {
212
+ if (error instanceof jwt.TokenExpiredError) {
213
+ throw new Error('Token expired');
214
+ }
215
+ if (error instanceof jwt.JsonWebTokenError) {
216
+ throw new Error('Invalid token');
217
+ }
218
+ throw error;
219
+ }
220
+ }
221
+ /**
222
+ * Refresh access token using refresh token
223
+ */
224
+ async refreshAccessToken(refreshToken) {
225
+ try {
226
+ // Verify refresh token
227
+ const payload = jwt.verify(refreshToken, this.refreshSecret);
228
+ // Check if token exists and is not revoked
229
+ const storedTokens = this.db
230
+ .prepare(`SELECT * FROM refresh_tokens
231
+ WHERE user_id = ? AND revoked = 0 AND expires_at > ?`)
232
+ .all(payload.userId, new Date().toISOString());
233
+ // Verify at least one stored token matches
234
+ let tokenValid = false;
235
+ for (const stored of storedTokens) {
236
+ if (await bcrypt.compare(refreshToken, stored.token_hash)) {
237
+ tokenValid = true;
238
+ break;
239
+ }
240
+ }
241
+ if (!tokenValid) {
242
+ throw new Error('Invalid or revoked refresh token');
243
+ }
244
+ // Get user
245
+ const user = this.getUserById(payload.userId);
246
+ if (!user) {
247
+ throw new Error('User not found');
248
+ }
249
+ // Generate new tokens
250
+ const tokens = this.generateTokens(user);
251
+ // Store new refresh token
252
+ await this.storeRefreshToken(user.id, tokens.refreshToken);
253
+ return tokens;
254
+ }
255
+ catch (error) {
256
+ if (error instanceof jwt.TokenExpiredError) {
257
+ throw new Error('Refresh token expired');
258
+ }
259
+ if (error instanceof jwt.JsonWebTokenError) {
260
+ throw new Error('Invalid refresh token');
261
+ }
262
+ throw error;
263
+ }
264
+ }
265
+ /**
266
+ * Revoke refresh token (logout)
267
+ */
268
+ async logout(refreshToken) {
269
+ try {
270
+ const payload = jwt.verify(refreshToken, this.refreshSecret);
271
+ // Mark all tokens for this user as revoked
272
+ this.db
273
+ .prepare('UPDATE refresh_tokens SET revoked = 1 WHERE user_id = ?')
274
+ .run(payload.userId);
275
+ log.info('User logged out', { userId: payload.userId });
276
+ }
277
+ catch {
278
+ // Ignore errors - token might be invalid but that's okay for logout
279
+ }
280
+ }
281
+ /**
282
+ * Get user by ID
283
+ */
284
+ getUserById(userId) {
285
+ const row = this.db
286
+ .prepare('SELECT * FROM users WHERE id = ?')
287
+ .get(userId);
288
+ if (!row)
289
+ return undefined;
290
+ return {
291
+ id: row.id,
292
+ email: row.email,
293
+ username: row.username,
294
+ passwordHash: row.password_hash,
295
+ role: row.role,
296
+ createdAt: new Date(row.created_at),
297
+ updatedAt: new Date(row.updated_at),
298
+ lastLoginAt: row.last_login_at ? new Date(row.last_login_at) : undefined,
299
+ };
300
+ }
301
+ /**
302
+ * Get user by email
303
+ */
304
+ getUserByEmail(email) {
305
+ const row = this.db
306
+ .prepare('SELECT * FROM users WHERE email = ?')
307
+ .get(email);
308
+ if (!row)
309
+ return undefined;
310
+ return {
311
+ id: row.id,
312
+ email: row.email,
313
+ username: row.username,
314
+ passwordHash: row.password_hash,
315
+ role: row.role,
316
+ createdAt: new Date(row.created_at),
317
+ updatedAt: new Date(row.updated_at),
318
+ lastLoginAt: row.last_login_at ? new Date(row.last_login_at) : undefined,
319
+ };
320
+ }
321
+ /**
322
+ * List all users (admin only)
323
+ */
324
+ listUsers() {
325
+ const rows = this.db.prepare('SELECT * FROM users ORDER BY created_at DESC').all();
326
+ return rows.map((row) => ({
327
+ id: row.id,
328
+ email: row.email,
329
+ username: row.username,
330
+ role: row.role,
331
+ createdAt: new Date(row.created_at),
332
+ updatedAt: new Date(row.updated_at),
333
+ lastLoginAt: row.last_login_at ? new Date(row.last_login_at) : undefined,
334
+ }));
335
+ }
336
+ /**
337
+ * Update user role (admin only)
338
+ */
339
+ updateUserRole(userId, role) {
340
+ this.db
341
+ .prepare('UPDATE users SET role = ?, updated_at = ? WHERE id = ?')
342
+ .run(role, new Date().toISOString(), userId);
343
+ log.info('User role updated', { userId, role });
344
+ }
345
+ /**
346
+ * Delete user (admin only)
347
+ */
348
+ deleteUser(userId) {
349
+ this.db.prepare('DELETE FROM users WHERE id = ?').run(userId);
350
+ log.info('User deleted', { userId });
351
+ }
352
+ /**
353
+ * Change user password
354
+ */
355
+ async changePassword(userId, oldPassword, newPassword) {
356
+ const user = this.getUserById(userId);
357
+ if (!user) {
358
+ throw new Error('User not found');
359
+ }
360
+ // Verify old password
361
+ const valid = await bcrypt.compare(oldPassword, user.passwordHash);
362
+ if (!valid) {
363
+ throw new Error('Invalid old password');
364
+ }
365
+ if (newPassword.length < 8) {
366
+ throw new Error('Password must be at least 8 characters');
367
+ }
368
+ // Hash new password
369
+ const passwordHash = await bcrypt.hash(newPassword, SALT_ROUNDS);
370
+ // Use transaction to ensure password update and token revocation are atomic
371
+ const transaction = this.db.transaction(() => {
372
+ // Update password
373
+ this.db
374
+ .prepare('UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?')
375
+ .run(passwordHash, new Date().toISOString(), userId);
376
+ // Revoke all refresh tokens
377
+ this.db.prepare('UPDATE refresh_tokens SET revoked = 1 WHERE user_id = ?').run(userId);
378
+ });
379
+ transaction();
380
+ log.info('Password changed', { userId });
381
+ }
382
+ }
383
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/auth/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Authentication types
3
+ */
4
+ export interface User {
5
+ id: string;
6
+ email: string;
7
+ username: string;
8
+ passwordHash: string;
9
+ role: UserRole;
10
+ createdAt: Date;
11
+ updatedAt: Date;
12
+ lastLoginAt?: Date;
13
+ }
14
+ export declare enum UserRole {
15
+ ADMIN = "admin",
16
+ DEVELOPER = "developer",
17
+ VIEWER = "viewer"
18
+ }
19
+ export interface AuthTokens {
20
+ accessToken: string;
21
+ refreshToken: string;
22
+ expiresIn: number;
23
+ }
24
+ export interface JWTPayload {
25
+ userId: string;
26
+ email: string;
27
+ username: string;
28
+ role: UserRole;
29
+ iat: number;
30
+ exp: number;
31
+ }
32
+ export interface LoginCredentials {
33
+ email: string;
34
+ password: string;
35
+ }
36
+ export interface RegisterData {
37
+ email: string;
38
+ username: string;
39
+ password: string;
40
+ }
41
+ export interface AuthContext {
42
+ authenticated: boolean;
43
+ user?: Omit<User, 'passwordHash'>;
44
+ userId?: string;
45
+ role?: UserRole;
46
+ permissions?: string[];
47
+ }
48
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,oBAAY,QAAQ;IAClB,KAAK,UAAU;IACf,SAAS,cAAc;IACvB,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Authentication types
3
+ */
4
+ export var UserRole;
5
+ (function (UserRole) {
6
+ UserRole["ADMIN"] = "admin";
7
+ UserRole["DEVELOPER"] = "developer";
8
+ UserRole["VIEWER"] = "viewer";
9
+ })(UserRole || (UserRole = {}));
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,MAAM,CAAN,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,2BAAe,CAAA;IACf,mCAAuB,CAAA;IACvB,6BAAiB,CAAA;AACnB,CAAC,EAJW,QAAQ,KAAR,QAAQ,QAInB"}
@@ -25,6 +25,10 @@ export declare class ReviewLoopCoordinator extends EventEmitter {
25
25
  private state;
26
26
  private config;
27
27
  constructor(codeInput: string, config: AgentStackConfig, options?: ReviewLoopOptions);
28
+ /**
29
+ * Persist state to database
30
+ */
31
+ private persistState;
28
32
  /**
29
33
  * Get current state
30
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"review-loop.d.ts","sourceRoot":"","sources":["../../src/coordination/review-loop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,WAAW,EAGZ,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACtE,aAAa,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACtE,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACvF,eAAe,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAC9D;AAKD;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,MAAM,CAAmB;gBAErB,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAE,iBAAsB;IAwCxF;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC;IAuBvC;;OAEG;YACW,mBAAmB;IAajC;;OAEG;YACW,OAAO;IA+CrB;;OAEG;YACW,aAAa;IAyB3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8DzB;;OAEG;YACW,OAAO;IA8BrB;;OAEG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAI1B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAEtE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAEnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC"}
1
+ {"version":3,"file":"review-loop.d.ts","sourceRoot":"","sources":["../../src/coordination/review-loop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,WAAW,EAGZ,MAAM,aAAa,CAAC;AAYrB,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACtE,aAAa,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACtE,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACvF,eAAe,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAC9D;AAKD;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,MAAM,CAAmB;gBAErB,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAE,iBAAsB;IA2CxF;;OAEG;IACH,OAAO,CAAC,YAAY;IAYpB;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC;IA2BvC;;OAEG;YACW,mBAAmB;IAejC;;OAEG;YACW,OAAO;IAkDrB;;OAEG;YACW,aAAa;IA0B3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8DzB;;OAEG;YACW,OAAO;IAgCrB;;OAEG;IACH,KAAK,IAAI,IAAI;IAeb;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAI1B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAEtE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAEnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC"}