@friggframework/devtools 2.0.0-next.61 → 2.0.0-next.63

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 (142) hide show
  1. package/infrastructure/domains/shared/utilities/base-definition-factory.js +15 -1
  2. package/package.json +15 -7
  3. package/.eslintrc.json +0 -3
  4. package/CHANGELOG.md +0 -132
  5. package/layers/prisma/.build-complete +0 -3
  6. package/layers/prisma/nodejs/package.json +0 -8
  7. package/management-ui/.eslintrc.js +0 -22
  8. package/management-ui/components.json +0 -21
  9. package/management-ui/docs/phase2-integration-guide.md +0 -320
  10. package/management-ui/index.html +0 -13
  11. package/management-ui/package.json +0 -76
  12. package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +0 -302
  13. package/management-ui/postcss.config.js +0 -6
  14. package/management-ui/server/api/backend.js +0 -256
  15. package/management-ui/server/api/cli.js +0 -315
  16. package/management-ui/server/api/codegen.js +0 -663
  17. package/management-ui/server/api/connections.js +0 -857
  18. package/management-ui/server/api/discovery.js +0 -185
  19. package/management-ui/server/api/environment/index.js +0 -1
  20. package/management-ui/server/api/environment/router.js +0 -378
  21. package/management-ui/server/api/environment.js +0 -328
  22. package/management-ui/server/api/integrations.js +0 -876
  23. package/management-ui/server/api/logs.js +0 -248
  24. package/management-ui/server/api/monitoring.js +0 -282
  25. package/management-ui/server/api/open-ide.js +0 -31
  26. package/management-ui/server/api/project.js +0 -1029
  27. package/management-ui/server/api/users/sessions.js +0 -371
  28. package/management-ui/server/api/users/simulation.js +0 -254
  29. package/management-ui/server/api/users.js +0 -362
  30. package/management-ui/server/api-contract.md +0 -275
  31. package/management-ui/server/index.js +0 -873
  32. package/management-ui/server/middleware/errorHandler.js +0 -93
  33. package/management-ui/server/middleware/security.js +0 -32
  34. package/management-ui/server/processManager.js +0 -296
  35. package/management-ui/server/server.js +0 -346
  36. package/management-ui/server/services/aws-monitor.js +0 -413
  37. package/management-ui/server/services/npm-registry.js +0 -347
  38. package/management-ui/server/services/template-engine.js +0 -538
  39. package/management-ui/server/utils/cliIntegration.js +0 -220
  40. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  41. package/management-ui/server/utils/environment/awsParameterStore.js +0 -275
  42. package/management-ui/server/utils/environment/encryption.js +0 -278
  43. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  44. package/management-ui/server/utils/import-commonjs.js +0 -28
  45. package/management-ui/server/utils/response.js +0 -83
  46. package/management-ui/server/websocket/handler.js +0 -325
  47. package/management-ui/src/App.jsx +0 -25
  48. package/management-ui/src/assets/FriggLogo.svg +0 -1
  49. package/management-ui/src/components/AppRouter.jsx +0 -65
  50. package/management-ui/src/components/Button.jsx +0 -70
  51. package/management-ui/src/components/Card.jsx +0 -97
  52. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  53. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  54. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  55. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  56. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  57. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  58. package/management-ui/src/components/IntegrationCard.jsx +0 -481
  59. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -770
  60. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  61. package/management-ui/src/components/IntegrationStatus.jsx +0 -336
  62. package/management-ui/src/components/Layout.jsx +0 -716
  63. package/management-ui/src/components/LoadingSpinner.jsx +0 -113
  64. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  65. package/management-ui/src/components/SessionMonitor.jsx +0 -350
  66. package/management-ui/src/components/StatusBadge.jsx +0 -208
  67. package/management-ui/src/components/UserContextSwitcher.jsx +0 -212
  68. package/management-ui/src/components/UserSimulation.jsx +0 -327
  69. package/management-ui/src/components/Welcome.jsx +0 -434
  70. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  71. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  72. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  73. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  74. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  75. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  76. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  77. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  78. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  79. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  80. package/management-ui/src/components/codegen/index.js +0 -10
  81. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  82. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  83. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  84. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  85. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  86. package/management-ui/src/components/connections/index.js +0 -5
  87. package/management-ui/src/components/index.js +0 -21
  88. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  89. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  90. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  91. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  92. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  93. package/management-ui/src/components/monitoring/index.js +0 -6
  94. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  95. package/management-ui/src/components/theme-provider.jsx +0 -52
  96. package/management-ui/src/components/theme-toggle.jsx +0 -39
  97. package/management-ui/src/components/ui/badge.tsx +0 -36
  98. package/management-ui/src/components/ui/button.test.jsx +0 -56
  99. package/management-ui/src/components/ui/button.tsx +0 -57
  100. package/management-ui/src/components/ui/card.tsx +0 -76
  101. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  102. package/management-ui/src/components/ui/select.tsx +0 -157
  103. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  104. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  105. package/management-ui/src/hooks/useSocket.jsx +0 -58
  106. package/management-ui/src/index.css +0 -193
  107. package/management-ui/src/lib/utils.ts +0 -6
  108. package/management-ui/src/main.jsx +0 -10
  109. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  110. package/management-ui/src/pages/Connections.jsx +0 -252
  111. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -633
  112. package/management-ui/src/pages/Dashboard.jsx +0 -311
  113. package/management-ui/src/pages/Environment.jsx +0 -314
  114. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -669
  115. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -567
  116. package/management-ui/src/pages/IntegrationTest.jsx +0 -742
  117. package/management-ui/src/pages/Integrations.jsx +0 -253
  118. package/management-ui/src/pages/Monitoring.jsx +0 -17
  119. package/management-ui/src/pages/Simulation.jsx +0 -155
  120. package/management-ui/src/pages/Users.jsx +0 -492
  121. package/management-ui/src/services/api.js +0 -41
  122. package/management-ui/src/services/apiModuleService.js +0 -193
  123. package/management-ui/src/services/websocket-handlers.js +0 -120
  124. package/management-ui/src/test/api/project.test.js +0 -273
  125. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  126. package/management-ui/src/test/mocks/server.js +0 -178
  127. package/management-ui/src/test/setup.js +0 -61
  128. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  129. package/management-ui/src/utils/repository.js +0 -98
  130. package/management-ui/src/utils/repository.test.js +0 -118
  131. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  132. package/management-ui/tailwind.config.js +0 -63
  133. package/management-ui/tsconfig.json +0 -37
  134. package/management-ui/tsconfig.node.json +0 -10
  135. package/management-ui/vite.config.js +0 -26
  136. package/management-ui/vitest.config.js +0 -38
  137. package/test/auther-definition-method-tester.js +0 -45
  138. package/test/index.js +0 -9
  139. package/test/integration-validator.js +0 -2
  140. package/test/mock-api-readme.md +0 -102
  141. package/test/mock-api.js +0 -284
  142. package/test/mock-integration.js +0 -78
@@ -1,463 +0,0 @@
1
- import React, { useState, useEffect } from 'react'
2
- import api from '../services/api'
3
-
4
- const EnvironmentSecurity = ({ environment = 'local' }) => {
5
- const [securitySettings, setSecuritySettings] = useState({
6
- maskingEnabled: true,
7
- encryptionEnabled: false,
8
- auditLoggingEnabled: true,
9
- accessControl: {
10
- enabled: false,
11
- defaultPermission: 'read',
12
- rules: []
13
- }
14
- })
15
- const [maskingPatterns, setMaskingPatterns] = useState([
16
- { pattern: 'PASSWORD', enabled: true },
17
- { pattern: 'SECRET', enabled: true },
18
- { pattern: 'KEY', enabled: true },
19
- { pattern: 'TOKEN', enabled: true },
20
- { pattern: 'PRIVATE', enabled: true },
21
- { pattern: 'CREDENTIAL', enabled: true },
22
- { pattern: 'AUTH', enabled: true },
23
- { pattern: 'API_KEY', enabled: true }
24
- ])
25
- const [customPattern, setCustomPattern] = useState('')
26
- const [auditLogs, setAuditLogs] = useState([])
27
- const [showAuditLogs, setShowAuditLogs] = useState(false)
28
- const [accessRules, setAccessRules] = useState([])
29
- const [newRule, setNewRule] = useState({
30
- user: '',
31
- pattern: '',
32
- permission: 'read'
33
- })
34
-
35
- // Load security settings
36
- useEffect(() => {
37
- loadSecuritySettings()
38
- loadAuditLogs()
39
- }, [environment])
40
-
41
- const loadSecuritySettings = () => {
42
- // Load from localStorage for now
43
- const saved = localStorage.getItem(`security-settings-${environment}`)
44
- if (saved) {
45
- const parsed = JSON.parse(saved)
46
- setSecuritySettings(parsed.settings || securitySettings)
47
- setMaskingPatterns(parsed.patterns || maskingPatterns)
48
- setAccessRules(parsed.rules || [])
49
- }
50
- }
51
-
52
- const saveSecuritySettings = () => {
53
- const toSave = {
54
- settings: securitySettings,
55
- patterns: maskingPatterns,
56
- rules: accessRules
57
- }
58
- localStorage.setItem(`security-settings-${environment}`, JSON.stringify(toSave))
59
- }
60
-
61
- const loadAuditLogs = async () => {
62
- // Simulate loading audit logs
63
- const mockLogs = [
64
- {
65
- id: 1,
66
- timestamp: new Date().toISOString(),
67
- user: 'admin@example.com',
68
- action: 'update',
69
- variable: 'DATABASE_URL',
70
- environment,
71
- details: 'Updated variable value'
72
- },
73
- {
74
- id: 2,
75
- timestamp: new Date(Date.now() - 3600000).toISOString(),
76
- user: 'dev@example.com',
77
- action: 'create',
78
- variable: 'API_KEY',
79
- environment,
80
- details: 'Created new variable'
81
- },
82
- {
83
- id: 3,
84
- timestamp: new Date(Date.now() - 7200000).toISOString(),
85
- user: 'admin@example.com',
86
- action: 'delete',
87
- variable: 'OLD_SECRET',
88
- environment,
89
- details: 'Deleted variable'
90
- }
91
- ]
92
- setAuditLogs(mockLogs)
93
- }
94
-
95
- const toggleSetting = (setting) => {
96
- const updated = { ...securitySettings, [setting]: !securitySettings[setting] }
97
- setSecuritySettings(updated)
98
- saveSecuritySettings()
99
- }
100
-
101
- const togglePattern = (index) => {
102
- const updated = [...maskingPatterns]
103
- updated[index].enabled = !updated[index].enabled
104
- setMaskingPatterns(updated)
105
- saveSecuritySettings()
106
- }
107
-
108
- const addCustomPattern = () => {
109
- if (customPattern && !maskingPatterns.find(p => p.pattern === customPattern)) {
110
- const updated = [...maskingPatterns, { pattern: customPattern.toUpperCase(), enabled: true }]
111
- setMaskingPatterns(updated)
112
- setCustomPattern('')
113
- saveSecuritySettings()
114
- }
115
- }
116
-
117
- const removePattern = (index) => {
118
- const updated = maskingPatterns.filter((_, i) => i !== index)
119
- setMaskingPatterns(updated)
120
- saveSecuritySettings()
121
- }
122
-
123
- const addAccessRule = () => {
124
- if (newRule.user && newRule.pattern) {
125
- const updated = [...accessRules, { ...newRule, id: Date.now() }]
126
- setAccessRules(updated)
127
- setNewRule({ user: '', pattern: '', permission: 'read' })
128
- saveSecuritySettings()
129
- }
130
- }
131
-
132
- const removeAccessRule = (id) => {
133
- const updated = accessRules.filter(rule => rule.id !== id)
134
- setAccessRules(updated)
135
- saveSecuritySettings()
136
- }
137
-
138
- const exportAuditLogs = () => {
139
- const csv = [
140
- ['Timestamp', 'User', 'Action', 'Variable', 'Environment', 'Details'].join(','),
141
- ...auditLogs.map(log => [
142
- log.timestamp,
143
- log.user,
144
- log.action,
145
- log.variable,
146
- log.environment,
147
- log.details
148
- ].join(','))
149
- ].join('\n')
150
-
151
- const blob = new Blob([csv], { type: 'text/csv' })
152
- const url = URL.createObjectURL(blob)
153
- const a = document.createElement('a')
154
- a.href = url
155
- a.download = `audit-logs-${environment}-${Date.now()}.csv`
156
- a.click()
157
- URL.revokeObjectURL(url)
158
- }
159
-
160
- return (
161
- <div className="environment-security space-y-6">
162
- {/* Security Overview */}
163
- <div className="bg-white rounded-lg shadow p-6">
164
- <h3 className="text-lg font-medium text-gray-900 mb-4">Security Settings</h3>
165
-
166
- <div className="space-y-4">
167
- {/* Masking Toggle */}
168
- <div className="flex items-center justify-between">
169
- <div>
170
- <h4 className="text-sm font-medium text-gray-900">Variable Masking</h4>
171
- <p className="text-sm text-gray-500">Hide sensitive variable values in the UI</p>
172
- </div>
173
- <button
174
- onClick={() => toggleSetting('maskingEnabled')}
175
- className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
176
- securitySettings.maskingEnabled ? 'bg-blue-600' : 'bg-gray-200'
177
- }`}
178
- >
179
- <span
180
- className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
181
- securitySettings.maskingEnabled ? 'translate-x-6' : 'translate-x-1'
182
- }`}
183
- />
184
- </button>
185
- </div>
186
-
187
- {/* Encryption Toggle */}
188
- <div className="flex items-center justify-between">
189
- <div>
190
- <h4 className="text-sm font-medium text-gray-900">Value Encryption</h4>
191
- <p className="text-sm text-gray-500">Encrypt sensitive values at rest</p>
192
- </div>
193
- <button
194
- onClick={() => toggleSetting('encryptionEnabled')}
195
- className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
196
- securitySettings.encryptionEnabled ? 'bg-blue-600' : 'bg-gray-200'
197
- }`}
198
- >
199
- <span
200
- className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
201
- securitySettings.encryptionEnabled ? 'translate-x-6' : 'translate-x-1'
202
- }`}
203
- />
204
- </button>
205
- </div>
206
-
207
- {/* Audit Logging Toggle */}
208
- <div className="flex items-center justify-between">
209
- <div>
210
- <h4 className="text-sm font-medium text-gray-900">Audit Logging</h4>
211
- <p className="text-sm text-gray-500">Track all changes to environment variables</p>
212
- </div>
213
- <button
214
- onClick={() => toggleSetting('auditLoggingEnabled')}
215
- className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
216
- securitySettings.auditLoggingEnabled ? 'bg-blue-600' : 'bg-gray-200'
217
- }`}
218
- >
219
- <span
220
- className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
221
- securitySettings.auditLoggingEnabled ? 'translate-x-6' : 'translate-x-1'
222
- }`}
223
- />
224
- </button>
225
- </div>
226
-
227
- {/* Access Control Toggle */}
228
- <div className="flex items-center justify-between">
229
- <div>
230
- <h4 className="text-sm font-medium text-gray-900">Access Control</h4>
231
- <p className="text-sm text-gray-500">Enable role-based access control</p>
232
- </div>
233
- <button
234
- onClick={() => {
235
- const updated = { ...securitySettings }
236
- updated.accessControl.enabled = !updated.accessControl.enabled
237
- setSecuritySettings(updated)
238
- saveSecuritySettings()
239
- }}
240
- className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
241
- securitySettings.accessControl.enabled ? 'bg-blue-600' : 'bg-gray-200'
242
- }`}
243
- >
244
- <span
245
- className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
246
- securitySettings.accessControl.enabled ? 'translate-x-6' : 'translate-x-1'
247
- }`}
248
- />
249
- </button>
250
- </div>
251
- </div>
252
- </div>
253
-
254
- {/* Masking Patterns */}
255
- {securitySettings.maskingEnabled && (
256
- <div className="bg-white rounded-lg shadow p-6">
257
- <h3 className="text-lg font-medium text-gray-900 mb-4">Masking Patterns</h3>
258
- <p className="text-sm text-gray-500 mb-4">
259
- Variables containing these patterns will be automatically masked
260
- </p>
261
-
262
- <div className="space-y-2 mb-4">
263
- {maskingPatterns.map((pattern, index) => (
264
- <div key={index} className="flex items-center justify-between py-2">
265
- <div className="flex items-center">
266
- <input
267
- type="checkbox"
268
- checked={pattern.enabled}
269
- onChange={() => togglePattern(index)}
270
- className="mr-3"
271
- />
272
- <code className="text-sm font-mono text-gray-700">{pattern.pattern}</code>
273
- </div>
274
- {index >= 8 && ( // Allow removing custom patterns only
275
- <button
276
- onClick={() => removePattern(index)}
277
- className="text-red-600 hover:text-red-800"
278
- >
279
- Remove
280
- </button>
281
- )}
282
- </div>
283
- ))}
284
- </div>
285
-
286
- <div className="flex items-center space-x-2">
287
- <input
288
- type="text"
289
- value={customPattern}
290
- onChange={(e) => setCustomPattern(e.target.value.toUpperCase())}
291
- placeholder="Add custom pattern"
292
- className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-blue-500"
293
- />
294
- <button
295
- onClick={addCustomPattern}
296
- className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
297
- >
298
- Add Pattern
299
- </button>
300
- </div>
301
- </div>
302
- )}
303
-
304
- {/* Access Control Rules */}
305
- {securitySettings.accessControl.enabled && (
306
- <div className="bg-white rounded-lg shadow p-6">
307
- <h3 className="text-lg font-medium text-gray-900 mb-4">Access Control Rules</h3>
308
-
309
- <div className="mb-4">
310
- <label className="block text-sm font-medium text-gray-700 mb-2">
311
- Default Permission
312
- </label>
313
- <select
314
- value={securitySettings.accessControl.defaultPermission}
315
- onChange={(e) => {
316
- const updated = { ...securitySettings }
317
- updated.accessControl.defaultPermission = e.target.value
318
- setSecuritySettings(updated)
319
- saveSecuritySettings()
320
- }}
321
- className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-blue-500"
322
- >
323
- <option value="none">No Access</option>
324
- <option value="read">Read Only</option>
325
- <option value="write">Read & Write</option>
326
- </select>
327
- </div>
328
-
329
- {/* Access Rules Table */}
330
- {accessRules.length > 0 && (
331
- <div className="mb-4">
332
- <table className="min-w-full divide-y divide-gray-200">
333
- <thead className="bg-gray-50">
334
- <tr>
335
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">User/Role</th>
336
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Variable Pattern</th>
337
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Permission</th>
338
- <th className="px-4 py-2"></th>
339
- </tr>
340
- </thead>
341
- <tbody className="bg-white divide-y divide-gray-200">
342
- {accessRules.map(rule => (
343
- <tr key={rule.id}>
344
- <td className="px-4 py-2 text-sm">{rule.user}</td>
345
- <td className="px-4 py-2 text-sm font-mono">{rule.pattern}</td>
346
- <td className="px-4 py-2 text-sm">{rule.permission}</td>
347
- <td className="px-4 py-2 text-sm text-right">
348
- <button
349
- onClick={() => removeAccessRule(rule.id)}
350
- className="text-red-600 hover:text-red-800"
351
- >
352
- Remove
353
- </button>
354
- </td>
355
- </tr>
356
- ))}
357
- </tbody>
358
- </table>
359
- </div>
360
- )}
361
-
362
- {/* Add Rule Form */}
363
- <div className="grid grid-cols-3 gap-2">
364
- <input
365
- type="text"
366
- value={newRule.user}
367
- onChange={(e) => setNewRule({ ...newRule, user: e.target.value })}
368
- placeholder="User or role"
369
- className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-blue-500"
370
- />
371
- <input
372
- type="text"
373
- value={newRule.pattern}
374
- onChange={(e) => setNewRule({ ...newRule, pattern: e.target.value })}
375
- placeholder="Variable pattern (e.g., API_*)"
376
- className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-blue-500"
377
- />
378
- <div className="flex space-x-2">
379
- <select
380
- value={newRule.permission}
381
- onChange={(e) => setNewRule({ ...newRule, permission: e.target.value })}
382
- className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-blue-500"
383
- >
384
- <option value="none">No Access</option>
385
- <option value="read">Read Only</option>
386
- <option value="write">Read & Write</option>
387
- </select>
388
- <button
389
- onClick={addAccessRule}
390
- className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
391
- >
392
- Add
393
- </button>
394
- </div>
395
- </div>
396
- </div>
397
- )}
398
-
399
- {/* Audit Logs */}
400
- {securitySettings.auditLoggingEnabled && (
401
- <div className="bg-white rounded-lg shadow p-6">
402
- <div className="flex items-center justify-between mb-4">
403
- <h3 className="text-lg font-medium text-gray-900">Audit Logs</h3>
404
- <div className="space-x-2">
405
- <button
406
- onClick={() => setShowAuditLogs(!showAuditLogs)}
407
- className="px-3 py-1 text-sm bg-gray-200 text-gray-700 rounded hover:bg-gray-300"
408
- >
409
- {showAuditLogs ? 'Hide' : 'Show'} Logs
410
- </button>
411
- <button
412
- onClick={exportAuditLogs}
413
- className="px-3 py-1 text-sm bg-gray-200 text-gray-700 rounded hover:bg-gray-300"
414
- >
415
- Export CSV
416
- </button>
417
- </div>
418
- </div>
419
-
420
- {showAuditLogs && (
421
- <div className="overflow-x-auto">
422
- <table className="min-w-full divide-y divide-gray-200">
423
- <thead className="bg-gray-50">
424
- <tr>
425
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Timestamp</th>
426
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">User</th>
427
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Action</th>
428
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Variable</th>
429
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Details</th>
430
- </tr>
431
- </thead>
432
- <tbody className="bg-white divide-y divide-gray-200">
433
- {auditLogs.map(log => (
434
- <tr key={log.id}>
435
- <td className="px-4 py-2 text-sm text-gray-500">
436
- {new Date(log.timestamp).toLocaleString()}
437
- </td>
438
- <td className="px-4 py-2 text-sm">{log.user}</td>
439
- <td className="px-4 py-2 text-sm">
440
- <span className={`px-2 py-1 text-xs rounded ${
441
- log.action === 'create' ? 'bg-green-100 text-green-800' :
442
- log.action === 'update' ? 'bg-blue-100 text-blue-800' :
443
- log.action === 'delete' ? 'bg-red-100 text-red-800' :
444
- 'bg-gray-100 text-gray-800'
445
- }`}>
446
- {log.action}
447
- </span>
448
- </td>
449
- <td className="px-4 py-2 text-sm font-mono">{log.variable}</td>
450
- <td className="px-4 py-2 text-sm text-gray-500">{log.details}</td>
451
- </tr>
452
- ))}
453
- </tbody>
454
- </table>
455
- </div>
456
- )}
457
- </div>
458
- )}
459
- </div>
460
- )
461
- }
462
-
463
- export default EnvironmentSecurity
@@ -1,73 +0,0 @@
1
- import React from 'react'
2
-
3
- class ErrorBoundary extends React.Component {
4
- constructor(props) {
5
- super(props)
6
- this.state = { hasError: false, error: null, errorInfo: null }
7
- }
8
-
9
- static getDerivedStateFromError(error) {
10
- // Update state so the next render will show the fallback UI
11
- return { hasError: true }
12
- }
13
-
14
- componentDidCatch(error, errorInfo) {
15
- // Log the error to console or error reporting service
16
- console.error('ErrorBoundary caught an error:', error, errorInfo)
17
- this.setState({
18
- error: error,
19
- errorInfo: errorInfo
20
- })
21
- }
22
-
23
- render() {
24
- if (this.state.hasError) {
25
- if (this.props.fallback) {
26
- return this.props.fallback
27
- }
28
-
29
- return (
30
- <div className="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
31
- <div className="sm:mx-auto sm:w-full sm:max-w-md">
32
- <div className="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
33
- <div className="text-center">
34
- <div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100">
35
- <svg className="h-6 w-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
36
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z" />
37
- </svg>
38
- </div>
39
- <h3 className="mt-4 text-lg font-medium text-gray-900">Something went wrong</h3>
40
- <p className="mt-2 text-sm text-gray-500">
41
- An unexpected error occurred. Please refresh the page and try again.
42
- </p>
43
- {process.env.NODE_ENV === 'development' && this.state.error && (
44
- <details className="mt-4 text-left">
45
- <summary className="cursor-pointer text-sm font-medium text-gray-700 hover:text-gray-900">
46
- Error details (development only)
47
- </summary>
48
- <pre className="mt-2 text-xs text-red-600 whitespace-pre-wrap">
49
- {this.state.error.toString()}
50
- {this.state.errorInfo.componentStack}
51
- </pre>
52
- </details>
53
- )}
54
- <div className="mt-6">
55
- <button
56
- onClick={() => window.location.reload()}
57
- className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
58
- >
59
- Reload page
60
- </button>
61
- </div>
62
- </div>
63
- </div>
64
- </div>
65
- </div>
66
- )
67
- }
68
-
69
- return this.props.children
70
- }
71
- }
72
-
73
- export default ErrorBoundary