@stacksjs/ts-cloud-core 0.1.3 → 0.1.6

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 (250) hide show
  1. package/README.md +98 -13
  2. package/package.json +12 -3
  3. package/src/advanced-features.test.ts +0 -465
  4. package/src/aws/cloudformation.ts +0 -421
  5. package/src/aws/cloudfront.ts +0 -158
  6. package/src/aws/credentials.test.ts +0 -132
  7. package/src/aws/credentials.ts +0 -545
  8. package/src/aws/index.ts +0 -87
  9. package/src/aws/s3.test.ts +0 -188
  10. package/src/aws/s3.ts +0 -1088
  11. package/src/aws/signature.test.ts +0 -670
  12. package/src/aws/signature.ts +0 -1155
  13. package/src/backup/disaster-recovery.test.ts +0 -726
  14. package/src/backup/disaster-recovery.ts +0 -500
  15. package/src/backup/index.ts +0 -34
  16. package/src/backup/manager.test.ts +0 -498
  17. package/src/backup/manager.ts +0 -432
  18. package/src/cicd/circleci.ts +0 -430
  19. package/src/cicd/github-actions.ts +0 -424
  20. package/src/cicd/gitlab-ci.ts +0 -255
  21. package/src/cicd/index.ts +0 -8
  22. package/src/cli/history.ts +0 -396
  23. package/src/cli/index.ts +0 -10
  24. package/src/cli/progress.ts +0 -458
  25. package/src/cli/repl.ts +0 -454
  26. package/src/cli/suggestions.ts +0 -327
  27. package/src/cli/table.test.ts +0 -319
  28. package/src/cli/table.ts +0 -332
  29. package/src/cloudformation/builder.test.ts +0 -327
  30. package/src/cloudformation/builder.ts +0 -378
  31. package/src/cloudformation/builders/api-gateway.ts +0 -449
  32. package/src/cloudformation/builders/cache.ts +0 -334
  33. package/src/cloudformation/builders/cdn.ts +0 -278
  34. package/src/cloudformation/builders/compute.ts +0 -485
  35. package/src/cloudformation/builders/database.ts +0 -392
  36. package/src/cloudformation/builders/functions.ts +0 -343
  37. package/src/cloudformation/builders/messaging.ts +0 -140
  38. package/src/cloudformation/builders/monitoring.ts +0 -300
  39. package/src/cloudformation/builders/network.ts +0 -264
  40. package/src/cloudformation/builders/queue.ts +0 -147
  41. package/src/cloudformation/builders/security.ts +0 -399
  42. package/src/cloudformation/builders/storage.ts +0 -285
  43. package/src/cloudformation/index.ts +0 -30
  44. package/src/cloudformation/types.ts +0 -173
  45. package/src/compliance/aws-config.ts +0 -543
  46. package/src/compliance/cloudtrail.ts +0 -376
  47. package/src/compliance/compliance.test.ts +0 -423
  48. package/src/compliance/guardduty.ts +0 -446
  49. package/src/compliance/index.ts +0 -66
  50. package/src/compliance/security-hub.ts +0 -456
  51. package/src/containers/build-optimization.ts +0 -416
  52. package/src/containers/containers.test.ts +0 -508
  53. package/src/containers/image-scanning.ts +0 -360
  54. package/src/containers/index.ts +0 -9
  55. package/src/containers/registry.ts +0 -293
  56. package/src/containers/service-mesh.ts +0 -520
  57. package/src/database/database.test.ts +0 -762
  58. package/src/database/index.ts +0 -9
  59. package/src/database/migrations.ts +0 -444
  60. package/src/database/performance.ts +0 -528
  61. package/src/database/replicas.ts +0 -534
  62. package/src/database/users.ts +0 -494
  63. package/src/dependency-graph.ts +0 -143
  64. package/src/deployment/ab-testing.ts +0 -582
  65. package/src/deployment/blue-green.ts +0 -452
  66. package/src/deployment/canary.ts +0 -500
  67. package/src/deployment/deployment.test.ts +0 -526
  68. package/src/deployment/index.ts +0 -61
  69. package/src/deployment/progressive.ts +0 -62
  70. package/src/dns/dns.test.ts +0 -641
  71. package/src/dns/dnssec.ts +0 -315
  72. package/src/dns/index.ts +0 -8
  73. package/src/dns/resolver.ts +0 -496
  74. package/src/dns/routing.ts +0 -593
  75. package/src/email/advanced/analytics.ts +0 -445
  76. package/src/email/advanced/index.ts +0 -11
  77. package/src/email/advanced/rules.ts +0 -465
  78. package/src/email/advanced/scheduling.ts +0 -352
  79. package/src/email/advanced/search.ts +0 -412
  80. package/src/email/advanced/shared-mailboxes.ts +0 -404
  81. package/src/email/advanced/templates.ts +0 -455
  82. package/src/email/advanced/threading.ts +0 -281
  83. package/src/email/analytics.ts +0 -467
  84. package/src/email/bounce-handling.ts +0 -425
  85. package/src/email/email.test.ts +0 -431
  86. package/src/email/handlers/__tests__/inbound.test.ts +0 -38
  87. package/src/email/handlers/__tests__/outbound.test.ts +0 -37
  88. package/src/email/handlers/converter.ts +0 -227
  89. package/src/email/handlers/feedback.ts +0 -228
  90. package/src/email/handlers/inbound.ts +0 -169
  91. package/src/email/handlers/outbound.ts +0 -178
  92. package/src/email/index.ts +0 -15
  93. package/src/email/reputation.ts +0 -303
  94. package/src/email/templates.ts +0 -352
  95. package/src/errors/index.test.ts +0 -434
  96. package/src/errors/index.ts +0 -416
  97. package/src/health-checks/index.ts +0 -40
  98. package/src/index.ts +0 -360
  99. package/src/intrinsic-functions.ts +0 -118
  100. package/src/lambda/concurrency.ts +0 -330
  101. package/src/lambda/destinations.ts +0 -345
  102. package/src/lambda/dlq.ts +0 -425
  103. package/src/lambda/index.ts +0 -11
  104. package/src/lambda/lambda.test.ts +0 -840
  105. package/src/lambda/layers.ts +0 -263
  106. package/src/lambda/versions.ts +0 -376
  107. package/src/lambda/vpc.ts +0 -399
  108. package/src/local/config.ts +0 -114
  109. package/src/local/index.ts +0 -6
  110. package/src/local/mock-aws.ts +0 -351
  111. package/src/modules/ai.ts +0 -340
  112. package/src/modules/api.ts +0 -478
  113. package/src/modules/auth.ts +0 -805
  114. package/src/modules/cache.ts +0 -417
  115. package/src/modules/cdn.ts +0 -1062
  116. package/src/modules/communication.ts +0 -1094
  117. package/src/modules/compute.ts +0 -3348
  118. package/src/modules/database.ts +0 -554
  119. package/src/modules/deployment.ts +0 -1079
  120. package/src/modules/dns.ts +0 -337
  121. package/src/modules/email.ts +0 -1538
  122. package/src/modules/filesystem.ts +0 -515
  123. package/src/modules/index.ts +0 -32
  124. package/src/modules/messaging.ts +0 -486
  125. package/src/modules/monitoring.ts +0 -2086
  126. package/src/modules/network.ts +0 -664
  127. package/src/modules/parameter-store.ts +0 -325
  128. package/src/modules/permissions.ts +0 -1081
  129. package/src/modules/phone.ts +0 -494
  130. package/src/modules/queue.ts +0 -1260
  131. package/src/modules/redirects.ts +0 -464
  132. package/src/modules/registry.ts +0 -699
  133. package/src/modules/search.ts +0 -401
  134. package/src/modules/secrets.ts +0 -416
  135. package/src/modules/security.ts +0 -731
  136. package/src/modules/sms.ts +0 -389
  137. package/src/modules/storage.ts +0 -1120
  138. package/src/modules/workflow.ts +0 -680
  139. package/src/multi-account/config.ts +0 -521
  140. package/src/multi-account/index.ts +0 -7
  141. package/src/multi-account/manager.ts +0 -427
  142. package/src/multi-region/cross-region.ts +0 -410
  143. package/src/multi-region/index.ts +0 -8
  144. package/src/multi-region/manager.ts +0 -483
  145. package/src/multi-region/regions.ts +0 -435
  146. package/src/network-security/index.ts +0 -48
  147. package/src/observability/index.ts +0 -9
  148. package/src/observability/logs.ts +0 -522
  149. package/src/observability/metrics.ts +0 -460
  150. package/src/observability/observability.test.ts +0 -782
  151. package/src/observability/synthetics.ts +0 -568
  152. package/src/observability/xray.ts +0 -358
  153. package/src/phone/advanced/analytics.ts +0 -349
  154. package/src/phone/advanced/callbacks.ts +0 -428
  155. package/src/phone/advanced/index.ts +0 -8
  156. package/src/phone/advanced/ivr-builder.ts +0 -504
  157. package/src/phone/advanced/recording.ts +0 -310
  158. package/src/phone/handlers/__tests__/incoming-call.test.ts +0 -40
  159. package/src/phone/handlers/incoming-call.ts +0 -117
  160. package/src/phone/handlers/missed-call.ts +0 -116
  161. package/src/phone/handlers/voicemail.ts +0 -179
  162. package/src/phone/index.ts +0 -9
  163. package/src/presets/api-backend.ts +0 -134
  164. package/src/presets/data-pipeline.ts +0 -204
  165. package/src/presets/extend.test.ts +0 -295
  166. package/src/presets/extend.ts +0 -297
  167. package/src/presets/fullstack-app.ts +0 -144
  168. package/src/presets/index.ts +0 -27
  169. package/src/presets/jamstack.ts +0 -135
  170. package/src/presets/microservices.ts +0 -167
  171. package/src/presets/ml-api.ts +0 -208
  172. package/src/presets/nodejs-server.ts +0 -104
  173. package/src/presets/nodejs-serverless.ts +0 -114
  174. package/src/presets/realtime-app.ts +0 -184
  175. package/src/presets/static-site.ts +0 -64
  176. package/src/presets/traditional-web-app.ts +0 -339
  177. package/src/presets/wordpress.ts +0 -138
  178. package/src/preview/github.test.ts +0 -249
  179. package/src/preview/github.ts +0 -297
  180. package/src/preview/index.ts +0 -37
  181. package/src/preview/manager.test.ts +0 -440
  182. package/src/preview/manager.ts +0 -326
  183. package/src/preview/notifications.test.ts +0 -582
  184. package/src/preview/notifications.ts +0 -341
  185. package/src/queue/batch-processing.ts +0 -402
  186. package/src/queue/dlq-monitoring.ts +0 -402
  187. package/src/queue/fifo.ts +0 -342
  188. package/src/queue/index.ts +0 -9
  189. package/src/queue/management.ts +0 -428
  190. package/src/queue/queue.test.ts +0 -429
  191. package/src/resource-mgmt/index.ts +0 -39
  192. package/src/resource-naming.ts +0 -62
  193. package/src/s3/index.ts +0 -523
  194. package/src/schema/cloud-config.schema.json +0 -554
  195. package/src/schema/index.ts +0 -68
  196. package/src/security/certificate-manager.ts +0 -492
  197. package/src/security/index.ts +0 -9
  198. package/src/security/scanning.ts +0 -545
  199. package/src/security/secrets-manager.ts +0 -476
  200. package/src/security/secrets-rotation.ts +0 -456
  201. package/src/security/security.test.ts +0 -738
  202. package/src/sms/advanced/ab-testing.ts +0 -389
  203. package/src/sms/advanced/analytics.ts +0 -336
  204. package/src/sms/advanced/campaigns.ts +0 -523
  205. package/src/sms/advanced/chatbot.ts +0 -224
  206. package/src/sms/advanced/index.ts +0 -10
  207. package/src/sms/advanced/link-tracking.ts +0 -248
  208. package/src/sms/advanced/mms.ts +0 -308
  209. package/src/sms/handlers/__tests__/send.test.ts +0 -40
  210. package/src/sms/handlers/delivery-status.ts +0 -133
  211. package/src/sms/handlers/receive.ts +0 -162
  212. package/src/sms/handlers/send.ts +0 -174
  213. package/src/sms/index.ts +0 -9
  214. package/src/stack-diff.ts +0 -389
  215. package/src/static-site/index.ts +0 -85
  216. package/src/template-builder.ts +0 -110
  217. package/src/template-validator.ts +0 -574
  218. package/src/utils/cache.ts +0 -291
  219. package/src/utils/diff.ts +0 -269
  220. package/src/utils/hash.ts +0 -227
  221. package/src/utils/index.ts +0 -8
  222. package/src/utils/parallel.ts +0 -294
  223. package/src/validators/credentials.test.ts +0 -274
  224. package/src/validators/credentials.ts +0 -233
  225. package/src/validators/quotas.test.ts +0 -434
  226. package/src/validators/quotas.ts +0 -217
  227. package/test/ai.test.ts +0 -327
  228. package/test/api.test.ts +0 -511
  229. package/test/auth.test.ts +0 -632
  230. package/test/cache.test.ts +0 -406
  231. package/test/cdn.test.ts +0 -247
  232. package/test/compute.test.ts +0 -861
  233. package/test/database.test.ts +0 -523
  234. package/test/deployment.test.ts +0 -499
  235. package/test/dns.test.ts +0 -270
  236. package/test/email.test.ts +0 -439
  237. package/test/filesystem.test.ts +0 -382
  238. package/test/integration.test.ts +0 -350
  239. package/test/messaging.test.ts +0 -514
  240. package/test/monitoring.test.ts +0 -634
  241. package/test/network.test.ts +0 -425
  242. package/test/permissions.test.ts +0 -488
  243. package/test/queue.test.ts +0 -484
  244. package/test/registry.test.ts +0 -306
  245. package/test/security.test.ts +0 -462
  246. package/test/storage.test.ts +0 -463
  247. package/test/template-validator.test.ts +0 -559
  248. package/test/workflow.test.ts +0 -592
  249. package/tsconfig.json +0 -16
  250. package/tsconfig.tsbuildinfo +0 -1
@@ -1,494 +0,0 @@
1
- /**
2
- * Database User Management
3
- * User creation, permissions, and access control
4
- */
5
-
6
- export interface DatabaseUser {
7
- id: string
8
- username: string
9
- database: string
10
- privileges: DatabasePrivilege[]
11
- passwordSecretArn?: string
12
- createdAt: Date
13
- lastRotated?: Date
14
- rotationEnabled?: boolean
15
- rotationDays?: number
16
- }
17
-
18
- export interface DatabasePrivilege {
19
- database?: string
20
- table?: string
21
- privileges: PrivilegeType[]
22
- }
23
-
24
- export type PrivilegeType =
25
- | 'SELECT'
26
- | 'INSERT'
27
- | 'UPDATE'
28
- | 'DELETE'
29
- | 'CREATE'
30
- | 'DROP'
31
- | 'ALTER'
32
- | 'INDEX'
33
- | 'EXECUTE'
34
- | 'ALL'
35
-
36
- export interface UserRole {
37
- id: string
38
- name: string
39
- description?: string
40
- privileges: DatabasePrivilege[]
41
- users: string[] // user IDs
42
- }
43
-
44
- export interface AccessAudit {
45
- id: string
46
- username: string
47
- action: 'LOGIN' | 'QUERY' | 'MODIFY' | 'GRANT' | 'REVOKE'
48
- database?: string
49
- table?: string
50
- query?: string
51
- timestamp: Date
52
- success: boolean
53
- ipAddress?: string
54
- }
55
-
56
- /**
57
- * Database user manager
58
- */
59
- export class DatabaseUserManager {
60
- private users: Map<string, DatabaseUser> = new Map()
61
- private roles: Map<string, UserRole> = new Map()
62
- private audits: Map<string, AccessAudit> = new Map()
63
- private userCounter = 0
64
- private roleCounter = 0
65
- private auditCounter = 0
66
-
67
- /**
68
- * Create database user
69
- */
70
- createUser(user: Omit<DatabaseUser, 'id' | 'createdAt'>): DatabaseUser {
71
- const id = `db-user-${Date.now()}-${this.userCounter++}`
72
-
73
- const dbUser: DatabaseUser = {
74
- id,
75
- createdAt: new Date(),
76
- ...user,
77
- }
78
-
79
- this.users.set(id, dbUser)
80
-
81
- return dbUser
82
- }
83
-
84
- /**
85
- * Create read-only user
86
- */
87
- createReadOnlyUser(options: {
88
- username: string
89
- database: string
90
- passwordSecretArn?: string
91
- tables?: string[]
92
- }): DatabaseUser {
93
- const privileges: DatabasePrivilege[] = options.tables
94
- ? options.tables.map(table => ({
95
- database: options.database,
96
- table,
97
- privileges: ['SELECT' as PrivilegeType],
98
- }))
99
- : [
100
- {
101
- database: options.database,
102
- privileges: ['SELECT' as PrivilegeType],
103
- },
104
- ]
105
-
106
- return this.createUser({
107
- username: options.username,
108
- database: options.database,
109
- privileges,
110
- passwordSecretArn: options.passwordSecretArn,
111
- rotationEnabled: true,
112
- rotationDays: 90,
113
- })
114
- }
115
-
116
- /**
117
- * Create read-write user
118
- */
119
- createReadWriteUser(options: {
120
- username: string
121
- database: string
122
- passwordSecretArn?: string
123
- tables?: string[]
124
- }): DatabaseUser {
125
- const privileges: DatabasePrivilege[] = options.tables
126
- ? options.tables.map(table => ({
127
- database: options.database,
128
- table,
129
- privileges: ['SELECT', 'INSERT', 'UPDATE', 'DELETE'] as PrivilegeType[],
130
- }))
131
- : [
132
- {
133
- database: options.database,
134
- privileges: ['SELECT', 'INSERT', 'UPDATE', 'DELETE'] as PrivilegeType[],
135
- },
136
- ]
137
-
138
- return this.createUser({
139
- username: options.username,
140
- database: options.database,
141
- privileges,
142
- passwordSecretArn: options.passwordSecretArn,
143
- rotationEnabled: true,
144
- rotationDays: 60,
145
- })
146
- }
147
-
148
- /**
149
- * Create admin user
150
- */
151
- createAdminUser(options: {
152
- username: string
153
- database: string
154
- passwordSecretArn?: string
155
- }): DatabaseUser {
156
- return this.createUser({
157
- username: options.username,
158
- database: options.database,
159
- privileges: [
160
- {
161
- database: options.database,
162
- privileges: ['ALL' as PrivilegeType],
163
- },
164
- ],
165
- passwordSecretArn: options.passwordSecretArn,
166
- rotationEnabled: true,
167
- rotationDays: 30,
168
- })
169
- }
170
-
171
- /**
172
- * Create application user with specific table access
173
- */
174
- createApplicationUser(options: {
175
- username: string
176
- database: string
177
- tables: { name: string; privileges: PrivilegeType[] }[]
178
- passwordSecretArn?: string
179
- }): DatabaseUser {
180
- const privileges: DatabasePrivilege[] = options.tables.map(table => ({
181
- database: options.database,
182
- table: table.name,
183
- privileges: table.privileges,
184
- }))
185
-
186
- return this.createUser({
187
- username: options.username,
188
- database: options.database,
189
- privileges,
190
- passwordSecretArn: options.passwordSecretArn,
191
- rotationEnabled: true,
192
- rotationDays: 90,
193
- })
194
- }
195
-
196
- /**
197
- * Create user role
198
- */
199
- createRole(role: Omit<UserRole, 'id' | 'users'>): UserRole {
200
- const id = `role-${Date.now()}-${this.roleCounter++}`
201
-
202
- const userRole: UserRole = {
203
- id,
204
- users: [],
205
- ...role,
206
- }
207
-
208
- this.roles.set(id, userRole)
209
-
210
- return userRole
211
- }
212
-
213
- /**
214
- * Assign user to role
215
- */
216
- assignUserToRole(userId: string, roleId: string): void {
217
- const user = this.users.get(userId)
218
- const role = this.roles.get(roleId)
219
-
220
- if (!user) {
221
- throw new Error(`User not found: ${userId}`)
222
- }
223
-
224
- if (!role) {
225
- throw new Error(`Role not found: ${roleId}`)
226
- }
227
-
228
- role.users.push(userId)
229
-
230
- // Merge role privileges with user privileges
231
- for (const privilege of role.privileges) {
232
- const existingPrivilege = user.privileges.find(
233
- p => p.database === privilege.database && p.table === privilege.table
234
- )
235
-
236
- if (existingPrivilege) {
237
- // Merge privileges
238
- existingPrivilege.privileges = Array.from(
239
- new Set([...existingPrivilege.privileges, ...privilege.privileges])
240
- )
241
- } else {
242
- user.privileges.push({ ...privilege })
243
- }
244
- }
245
- }
246
-
247
- /**
248
- * Grant privileges to user
249
- */
250
- grantPrivileges(
251
- userId: string,
252
- privileges: DatabasePrivilege[]
253
- ): { success: boolean; message: string } {
254
- const user = this.users.get(userId)
255
-
256
- if (!user) {
257
- return { success: false, message: 'User not found' }
258
- }
259
-
260
- for (const privilege of privileges) {
261
- const existing = user.privileges.find(
262
- p => p.database === privilege.database && p.table === privilege.table
263
- )
264
-
265
- if (existing) {
266
- existing.privileges = Array.from(new Set([...existing.privileges, ...privilege.privileges]))
267
- } else {
268
- user.privileges.push(privilege)
269
- }
270
- }
271
-
272
- this.auditAccess({
273
- username: user.username,
274
- action: 'GRANT',
275
- database: privileges[0]?.database,
276
- table: privileges[0]?.table,
277
- success: true,
278
- })
279
-
280
- return { success: true, message: 'Privileges granted successfully' }
281
- }
282
-
283
- /**
284
- * Revoke privileges from user
285
- */
286
- revokePrivileges(
287
- userId: string,
288
- privileges: DatabasePrivilege[]
289
- ): { success: boolean; message: string } {
290
- const user = this.users.get(userId)
291
-
292
- if (!user) {
293
- return { success: false, message: 'User not found' }
294
- }
295
-
296
- for (const privilege of privileges) {
297
- const existingIndex = user.privileges.findIndex(
298
- p => p.database === privilege.database && p.table === privilege.table
299
- )
300
-
301
- if (existingIndex !== -1) {
302
- const existing = user.privileges[existingIndex]
303
- existing.privileges = existing.privileges.filter(
304
- p => !privilege.privileges.includes(p)
305
- )
306
-
307
- // Remove privilege entry if no privileges left
308
- if (existing.privileges.length === 0) {
309
- user.privileges.splice(existingIndex, 1)
310
- }
311
- }
312
- }
313
-
314
- this.auditAccess({
315
- username: user.username,
316
- action: 'REVOKE',
317
- database: privileges[0]?.database,
318
- table: privileges[0]?.table,
319
- success: true,
320
- })
321
-
322
- return { success: true, message: 'Privileges revoked successfully' }
323
- }
324
-
325
- /**
326
- * Rotate user password
327
- */
328
- rotatePassword(userId: string): { success: boolean; newSecretArn?: string } {
329
- const user = this.users.get(userId)
330
-
331
- if (!user) {
332
- return { success: false }
333
- }
334
-
335
- // In production, this would trigger Secrets Manager rotation
336
- const newSecretArn = `arn:aws:secretsmanager:us-east-1:123456789012:secret:db-${user.username}-${Date.now()}`
337
-
338
- user.passwordSecretArn = newSecretArn
339
- user.lastRotated = new Date()
340
-
341
- console.log(`Password rotated for user: ${user.username}`)
342
-
343
- return { success: true, newSecretArn }
344
- }
345
-
346
- /**
347
- * Check if password rotation needed
348
- */
349
- needsPasswordRotation(userId: string): boolean {
350
- const user = this.users.get(userId)
351
-
352
- if (!user || !user.rotationEnabled || !user.lastRotated || !user.rotationDays) {
353
- return false
354
- }
355
-
356
- const daysSinceRotation =
357
- (Date.now() - user.lastRotated.getTime()) / (1000 * 60 * 60 * 24)
358
-
359
- return daysSinceRotation >= user.rotationDays
360
- }
361
-
362
- /**
363
- * Audit access
364
- */
365
- auditAccess(audit: Omit<AccessAudit, 'id' | 'timestamp'>): AccessAudit {
366
- const id = `audit-${Date.now()}-${this.auditCounter++}`
367
-
368
- const accessAudit: AccessAudit = {
369
- id,
370
- timestamp: new Date(),
371
- ...audit,
372
- }
373
-
374
- this.audits.set(id, accessAudit)
375
-
376
- return accessAudit
377
- }
378
-
379
- /**
380
- * Get user access history
381
- */
382
- getUserAccessHistory(username: string, limit: number = 100): AccessAudit[] {
383
- return Array.from(this.audits.values())
384
- .filter(audit => audit.username === username)
385
- .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
386
- .slice(0, limit)
387
- }
388
-
389
- /**
390
- * Get failed login attempts
391
- */
392
- getFailedLoginAttempts(username: string, hours: number = 24): AccessAudit[] {
393
- const cutoffTime = Date.now() - hours * 60 * 60 * 1000
394
-
395
- return Array.from(this.audits.values()).filter(
396
- audit =>
397
- audit.username === username &&
398
- audit.action === 'LOGIN' &&
399
- !audit.success &&
400
- audit.timestamp.getTime() > cutoffTime
401
- )
402
- }
403
-
404
- /**
405
- * Generate SQL for user creation
406
- */
407
- generateCreateUserSQL(user: DatabaseUser, engine: 'postgres' | 'mysql' = 'postgres'): string {
408
- const statements: string[] = []
409
-
410
- if (engine === 'postgres') {
411
- statements.push(`CREATE USER ${user.username} WITH PASSWORD '${user.passwordSecretArn}';`)
412
-
413
- for (const privilege of user.privileges) {
414
- if (privilege.privileges.includes('ALL')) {
415
- statements.push(`GRANT ALL PRIVILEGES ON DATABASE ${privilege.database} TO ${user.username};`)
416
- } else {
417
- const privs = privilege.privileges.join(', ')
418
- if (privilege.table) {
419
- statements.push(
420
- `GRANT ${privs} ON ${privilege.database}.${privilege.table} TO ${user.username};`
421
- )
422
- } else {
423
- statements.push(`GRANT ${privs} ON DATABASE ${privilege.database} TO ${user.username};`)
424
- }
425
- }
426
- }
427
- } else {
428
- // MySQL
429
- statements.push(
430
- `CREATE USER '${user.username}'@'%' IDENTIFIED BY '${user.passwordSecretArn}';`
431
- )
432
-
433
- for (const privilege of user.privileges) {
434
- const privs = privilege.privileges.includes('ALL')
435
- ? 'ALL PRIVILEGES'
436
- : privilege.privileges.join(', ')
437
- const target = privilege.table
438
- ? `${privilege.database}.${privilege.table}`
439
- : `${privilege.database}.*`
440
-
441
- statements.push(`GRANT ${privs} ON ${target} TO '${user.username}'@'%';`)
442
- }
443
-
444
- statements.push('FLUSH PRIVILEGES;')
445
- }
446
-
447
- return statements.join('\n')
448
- }
449
-
450
- /**
451
- * Get user
452
- */
453
- getUser(id: string): DatabaseUser | undefined {
454
- return this.users.get(id)
455
- }
456
-
457
- /**
458
- * List users
459
- */
460
- listUsers(): DatabaseUser[] {
461
- return Array.from(this.users.values())
462
- }
463
-
464
- /**
465
- * Get role
466
- */
467
- getRole(id: string): UserRole | undefined {
468
- return this.roles.get(id)
469
- }
470
-
471
- /**
472
- * List roles
473
- */
474
- listRoles(): UserRole[] {
475
- return Array.from(this.roles.values())
476
- }
477
-
478
- /**
479
- * Clear all data
480
- */
481
- clear(): void {
482
- this.users.clear()
483
- this.roles.clear()
484
- this.audits.clear()
485
- this.userCounter = 0
486
- this.roleCounter = 0
487
- this.auditCounter = 0
488
- }
489
- }
490
-
491
- /**
492
- * Global database user manager instance
493
- */
494
- export const databaseUserManager: DatabaseUserManager = new DatabaseUserManager()
@@ -1,143 +0,0 @@
1
- import type { CloudFormationResource } from '@stacksjs/ts-cloud-aws-types'
2
-
3
- export interface ResourceNode {
4
- logicalId: string
5
- resource: CloudFormationResource
6
- dependencies: Set<string>
7
- }
8
-
9
- /**
10
- * Dependency Graph for CloudFormation resources
11
- * Ensures resources are created in the correct order
12
- */
13
- export class DependencyGraph {
14
- private nodes: Map<string, ResourceNode> = new Map()
15
-
16
- /**
17
- * Add a resource to the dependency graph
18
- */
19
- addResource(logicalId: string, resource: CloudFormationResource): void {
20
- const dependencies = this.extractDependencies(resource)
21
-
22
- this.nodes.set(logicalId, {
23
- logicalId,
24
- resource,
25
- dependencies,
26
- })
27
- }
28
-
29
- /**
30
- * Extract dependencies from a resource
31
- */
32
- private extractDependencies(resource: CloudFormationResource): Set<string> {
33
- const dependencies = new Set<string>()
34
-
35
- // Add explicit DependsOn
36
- if (resource.DependsOn) {
37
- if (Array.isArray(resource.DependsOn)) {
38
- resource.DependsOn.forEach(dep => dependencies.add(dep))
39
- }
40
- else {
41
- dependencies.add(resource.DependsOn)
42
- }
43
- }
44
-
45
- // Extract Ref dependencies
46
- this.findReferences(resource.Properties || {}, dependencies)
47
-
48
- return dependencies
49
- }
50
-
51
- /**
52
- * Find all Ref references in an object
53
- */
54
- private findReferences(obj: any, dependencies: Set<string>): void {
55
- if (!obj || typeof obj !== 'object')
56
- return
57
-
58
- if ('Ref' in obj && typeof obj.Ref === 'string') {
59
- // Ignore pseudo parameters
60
- if (!obj.Ref.startsWith('AWS::')) {
61
- dependencies.add(obj.Ref)
62
- }
63
- }
64
-
65
- if ('Fn::GetAtt' in obj && Array.isArray(obj['Fn::GetAtt'])) {
66
- dependencies.add(obj['Fn::GetAtt'][0])
67
- }
68
-
69
- // Recursively search
70
- for (const value of Object.values(obj)) {
71
- if (typeof value === 'object') {
72
- this.findReferences(value, dependencies)
73
- }
74
- }
75
- }
76
-
77
- /**
78
- * Perform topological sort to determine resource creation order
79
- */
80
- topologicalSort(): string[] {
81
- const sorted: string[] = []
82
- const visited = new Set<string>()
83
- const visiting = new Set<string>()
84
-
85
- const visit = (nodeId: string): void => {
86
- if (visited.has(nodeId))
87
- return
88
-
89
- if (visiting.has(nodeId)) {
90
- throw new Error(`Circular dependency detected: ${nodeId}`)
91
- }
92
-
93
- visiting.add(nodeId)
94
-
95
- const node = this.nodes.get(nodeId)
96
- if (node) {
97
- for (const dep of node.dependencies) {
98
- visit(dep)
99
- }
100
- }
101
-
102
- visiting.delete(nodeId)
103
- visited.add(nodeId)
104
- sorted.push(nodeId)
105
- }
106
-
107
- for (const nodeId of this.nodes.keys()) {
108
- visit(nodeId)
109
- }
110
-
111
- return sorted
112
- }
113
-
114
- /**
115
- * Validate that all dependencies exist
116
- */
117
- validate(): void {
118
- for (const [nodeId, node] of this.nodes.entries()) {
119
- for (const dep of node.dependencies) {
120
- if (!this.nodes.has(dep)) {
121
- throw new Error(
122
- `Resource "${nodeId}" depends on "${dep}" which does not exist`,
123
- )
124
- }
125
- }
126
- }
127
- }
128
-
129
- /**
130
- * Get resources that depend on a given resource
131
- */
132
- getDependents(logicalId: string): string[] {
133
- const dependents: string[] = []
134
-
135
- for (const [nodeId, node] of this.nodes.entries()) {
136
- if (node.dependencies.has(logicalId)) {
137
- dependents.push(nodeId)
138
- }
139
- }
140
-
141
- return dependents
142
- }
143
- }