@friggframework/devtools 2.0.0--canary.517.35ee143.0 → 2.0.0--canary.524.06156322a.0

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 (147) hide show
  1. package/infrastructure/domains/shared/types/app-definition.js +0 -21
  2. package/infrastructure/domains/shared/utilities/base-definition-factory.js +15 -1
  3. package/infrastructure/infrastructure-composer.js +0 -2
  4. package/package.json +15 -7
  5. package/.eslintrc.json +0 -3
  6. package/CHANGELOG.md +0 -132
  7. package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
  8. package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
  9. package/infrastructure/domains/admin-scripts/index.js +0 -5
  10. package/layers/prisma/.build-complete +0 -3
  11. package/layers/prisma/nodejs/package.json +0 -8
  12. package/management-ui/.eslintrc.js +0 -22
  13. package/management-ui/components.json +0 -21
  14. package/management-ui/docs/phase2-integration-guide.md +0 -320
  15. package/management-ui/index.html +0 -13
  16. package/management-ui/package.json +0 -76
  17. package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +0 -302
  18. package/management-ui/postcss.config.js +0 -6
  19. package/management-ui/server/api/backend.js +0 -256
  20. package/management-ui/server/api/cli.js +0 -315
  21. package/management-ui/server/api/codegen.js +0 -663
  22. package/management-ui/server/api/connections.js +0 -857
  23. package/management-ui/server/api/discovery.js +0 -185
  24. package/management-ui/server/api/environment/index.js +0 -1
  25. package/management-ui/server/api/environment/router.js +0 -378
  26. package/management-ui/server/api/environment.js +0 -328
  27. package/management-ui/server/api/integrations.js +0 -876
  28. package/management-ui/server/api/logs.js +0 -248
  29. package/management-ui/server/api/monitoring.js +0 -282
  30. package/management-ui/server/api/open-ide.js +0 -31
  31. package/management-ui/server/api/project.js +0 -1029
  32. package/management-ui/server/api/users/sessions.js +0 -371
  33. package/management-ui/server/api/users/simulation.js +0 -254
  34. package/management-ui/server/api/users.js +0 -362
  35. package/management-ui/server/api-contract.md +0 -275
  36. package/management-ui/server/index.js +0 -873
  37. package/management-ui/server/middleware/errorHandler.js +0 -93
  38. package/management-ui/server/middleware/security.js +0 -32
  39. package/management-ui/server/processManager.js +0 -296
  40. package/management-ui/server/server.js +0 -346
  41. package/management-ui/server/services/aws-monitor.js +0 -413
  42. package/management-ui/server/services/npm-registry.js +0 -347
  43. package/management-ui/server/services/template-engine.js +0 -538
  44. package/management-ui/server/utils/cliIntegration.js +0 -220
  45. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  46. package/management-ui/server/utils/environment/awsParameterStore.js +0 -275
  47. package/management-ui/server/utils/environment/encryption.js +0 -278
  48. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  49. package/management-ui/server/utils/import-commonjs.js +0 -28
  50. package/management-ui/server/utils/response.js +0 -83
  51. package/management-ui/server/websocket/handler.js +0 -325
  52. package/management-ui/src/App.jsx +0 -25
  53. package/management-ui/src/assets/FriggLogo.svg +0 -1
  54. package/management-ui/src/components/AppRouter.jsx +0 -65
  55. package/management-ui/src/components/Button.jsx +0 -70
  56. package/management-ui/src/components/Card.jsx +0 -97
  57. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  58. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  59. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  60. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  61. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  62. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  63. package/management-ui/src/components/IntegrationCard.jsx +0 -481
  64. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -770
  65. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  66. package/management-ui/src/components/IntegrationStatus.jsx +0 -336
  67. package/management-ui/src/components/Layout.jsx +0 -716
  68. package/management-ui/src/components/LoadingSpinner.jsx +0 -113
  69. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  70. package/management-ui/src/components/SessionMonitor.jsx +0 -350
  71. package/management-ui/src/components/StatusBadge.jsx +0 -208
  72. package/management-ui/src/components/UserContextSwitcher.jsx +0 -212
  73. package/management-ui/src/components/UserSimulation.jsx +0 -327
  74. package/management-ui/src/components/Welcome.jsx +0 -434
  75. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  76. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  77. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  78. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  79. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  80. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  81. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  82. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  83. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  84. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  85. package/management-ui/src/components/codegen/index.js +0 -10
  86. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  87. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  88. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  89. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  90. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  91. package/management-ui/src/components/connections/index.js +0 -5
  92. package/management-ui/src/components/index.js +0 -21
  93. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  94. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  95. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  96. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  97. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  98. package/management-ui/src/components/monitoring/index.js +0 -6
  99. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  100. package/management-ui/src/components/theme-provider.jsx +0 -52
  101. package/management-ui/src/components/theme-toggle.jsx +0 -39
  102. package/management-ui/src/components/ui/badge.tsx +0 -36
  103. package/management-ui/src/components/ui/button.test.jsx +0 -56
  104. package/management-ui/src/components/ui/button.tsx +0 -57
  105. package/management-ui/src/components/ui/card.tsx +0 -76
  106. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  107. package/management-ui/src/components/ui/select.tsx +0 -157
  108. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  109. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  110. package/management-ui/src/hooks/useSocket.jsx +0 -58
  111. package/management-ui/src/index.css +0 -193
  112. package/management-ui/src/lib/utils.ts +0 -6
  113. package/management-ui/src/main.jsx +0 -10
  114. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  115. package/management-ui/src/pages/Connections.jsx +0 -252
  116. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -633
  117. package/management-ui/src/pages/Dashboard.jsx +0 -311
  118. package/management-ui/src/pages/Environment.jsx +0 -314
  119. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -669
  120. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -567
  121. package/management-ui/src/pages/IntegrationTest.jsx +0 -742
  122. package/management-ui/src/pages/Integrations.jsx +0 -253
  123. package/management-ui/src/pages/Monitoring.jsx +0 -17
  124. package/management-ui/src/pages/Simulation.jsx +0 -155
  125. package/management-ui/src/pages/Users.jsx +0 -492
  126. package/management-ui/src/services/api.js +0 -41
  127. package/management-ui/src/services/apiModuleService.js +0 -193
  128. package/management-ui/src/services/websocket-handlers.js +0 -120
  129. package/management-ui/src/test/api/project.test.js +0 -273
  130. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  131. package/management-ui/src/test/mocks/server.js +0 -178
  132. package/management-ui/src/test/setup.js +0 -61
  133. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  134. package/management-ui/src/utils/repository.js +0 -98
  135. package/management-ui/src/utils/repository.test.js +0 -118
  136. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  137. package/management-ui/tailwind.config.js +0 -63
  138. package/management-ui/tsconfig.json +0 -37
  139. package/management-ui/tsconfig.node.json +0 -10
  140. package/management-ui/vite.config.js +0 -26
  141. package/management-ui/vitest.config.js +0 -38
  142. package/test/auther-definition-method-tester.js +0 -45
  143. package/test/index.js +0 -9
  144. package/test/integration-validator.js +0 -2
  145. package/test/mock-api-readme.md +0 -102
  146. package/test/mock-api.js +0 -284
  147. 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