@friggframework/devtools 2.0.0--canary.400.bed3308.0 → 2.0.0--canary.404.e9d4980.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 (182) hide show
  1. package/frigg-cli/build-command/index.js +3 -18
  2. package/frigg-cli/deploy-command/index.js +3 -19
  3. package/frigg-cli/index.js +1 -73
  4. package/frigg-cli/install-command/index.js +2 -15
  5. package/frigg-cli/start-command/index.js +2 -17
  6. package/infrastructure/create-frigg-infrastructure.js +2 -2
  7. package/infrastructure/serverless-template.js +79 -529
  8. package/package.json +5 -9
  9. package/frigg-cli/.eslintrc.js +0 -141
  10. package/frigg-cli/__tests__/jest.config.js +0 -102
  11. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -483
  12. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -418
  13. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -592
  14. package/frigg-cli/__tests__/utils/command-tester.js +0 -170
  15. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  16. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  17. package/frigg-cli/__tests__/utils/test-setup.js +0 -286
  18. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -312
  19. package/frigg-cli/generate-command/azure-generator.js +0 -43
  20. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  21. package/frigg-cli/generate-command/index.js +0 -350
  22. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  23. package/frigg-cli/generate-iam-command.js +0 -115
  24. package/frigg-cli/package.json +0 -75
  25. package/frigg-cli/ui-command/index.js +0 -167
  26. package/frigg-cli/utils/app-resolver.js +0 -319
  27. package/frigg-cli/utils/backend-path.js +0 -38
  28. package/frigg-cli/utils/process-manager.js +0 -199
  29. package/frigg-cli/utils/repo-detection.js +0 -405
  30. package/infrastructure/AWS-DISCOVERY-TROUBLESHOOTING.md +0 -245
  31. package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +0 -620
  32. package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +0 -268
  33. package/infrastructure/GENERATE-IAM-DOCS.md +0 -253
  34. package/infrastructure/IAM-POLICY-TEMPLATES.md +0 -176
  35. package/infrastructure/README-TESTING.md +0 -332
  36. package/infrastructure/README.md +0 -421
  37. package/infrastructure/WEBSOCKET-CONFIGURATION.md +0 -105
  38. package/infrastructure/__tests__/fixtures/mock-aws-resources.js +0 -391
  39. package/infrastructure/__tests__/helpers/test-utils.js +0 -277
  40. package/infrastructure/aws-discovery.js +0 -568
  41. package/infrastructure/aws-discovery.test.js +0 -373
  42. package/infrastructure/build-time-discovery.js +0 -206
  43. package/infrastructure/build-time-discovery.test.js +0 -375
  44. package/infrastructure/frigg-deployment-iam-stack.yaml +0 -393
  45. package/infrastructure/iam-generator.js +0 -810
  46. package/infrastructure/iam-generator.test.js +0 -169
  47. package/infrastructure/iam-policy-basic.json +0 -236
  48. package/infrastructure/iam-policy-full.json +0 -305
  49. package/infrastructure/integration.test.js +0 -383
  50. package/infrastructure/run-discovery.js +0 -110
  51. package/infrastructure/serverless-template.test.js +0 -553
  52. package/management-ui/.eslintrc.js +0 -22
  53. package/management-ui/README.md +0 -203
  54. package/management-ui/components.json +0 -21
  55. package/management-ui/index.html +0 -13
  56. package/management-ui/merge-conflict-cleaner.py +0 -371
  57. package/management-ui/package-lock.json +0 -10997
  58. package/management-ui/package.json +0 -76
  59. package/management-ui/postcss.config.js +0 -6
  60. package/management-ui/server/api/backend.js +0 -256
  61. package/management-ui/server/api/cli.js +0 -315
  62. package/management-ui/server/api/codegen.js +0 -663
  63. package/management-ui/server/api/connections.js +0 -857
  64. package/management-ui/server/api/discovery.js +0 -185
  65. package/management-ui/server/api/environment/index.js +0 -1
  66. package/management-ui/server/api/environment/router.js +0 -378
  67. package/management-ui/server/api/environment.js +0 -328
  68. package/management-ui/server/api/integrations.js +0 -479
  69. package/management-ui/server/api/logs.js +0 -248
  70. package/management-ui/server/api/monitoring.js +0 -282
  71. package/management-ui/server/api/open-ide.js +0 -31
  72. package/management-ui/server/api/project.js +0 -553
  73. package/management-ui/server/api/users/sessions.js +0 -371
  74. package/management-ui/server/api/users/simulation.js +0 -254
  75. package/management-ui/server/api/users.js +0 -362
  76. package/management-ui/server/api-contract.md +0 -275
  77. package/management-ui/server/index.js +0 -428
  78. package/management-ui/server/middleware/errorHandler.js +0 -70
  79. package/management-ui/server/middleware/security.js +0 -32
  80. package/management-ui/server/processManager.js +0 -296
  81. package/management-ui/server/server.js +0 -188
  82. package/management-ui/server/services/aws-monitor.js +0 -413
  83. package/management-ui/server/services/npm-registry.js +0 -347
  84. package/management-ui/server/services/template-engine.js +0 -538
  85. package/management-ui/server/utils/cliIntegration.js +0 -220
  86. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  87. package/management-ui/server/utils/environment/awsParameterStore.js +0 -264
  88. package/management-ui/server/utils/environment/encryption.js +0 -278
  89. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  90. package/management-ui/server/utils/import-commonjs.js +0 -28
  91. package/management-ui/server/utils/response.js +0 -83
  92. package/management-ui/server/websocket/handler.js +0 -325
  93. package/management-ui/src/App.jsx +0 -51
  94. package/management-ui/src/assets/FriggLogo.svg +0 -1
  95. package/management-ui/src/components/AppRouter.jsx +0 -65
  96. package/management-ui/src/components/Button.jsx +0 -2
  97. package/management-ui/src/components/Card.jsx +0 -9
  98. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  99. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  100. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  101. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  102. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  103. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  104. package/management-ui/src/components/IntegrationCard.jsx +0 -199
  105. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -490
  106. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  107. package/management-ui/src/components/IntegrationStatus.jsx +0 -235
  108. package/management-ui/src/components/Layout.jsx +0 -250
  109. package/management-ui/src/components/LoadingSpinner.jsx +0 -45
  110. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  111. package/management-ui/src/components/SessionMonitor.jsx +0 -255
  112. package/management-ui/src/components/StatusBadge.jsx +0 -70
  113. package/management-ui/src/components/UserContextSwitcher.jsx +0 -154
  114. package/management-ui/src/components/UserSimulation.jsx +0 -299
  115. package/management-ui/src/components/Welcome.jsx +0 -434
  116. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  117. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  118. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  119. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  120. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  121. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  122. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  123. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  124. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  125. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  126. package/management-ui/src/components/codegen/index.js +0 -10
  127. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  128. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  129. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  130. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  131. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  132. package/management-ui/src/components/connections/index.js +0 -5
  133. package/management-ui/src/components/index.js +0 -21
  134. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  135. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  136. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  137. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  138. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  139. package/management-ui/src/components/monitoring/index.js +0 -6
  140. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  141. package/management-ui/src/components/theme-provider.jsx +0 -52
  142. package/management-ui/src/components/theme-toggle.jsx +0 -39
  143. package/management-ui/src/components/ui/badge.tsx +0 -36
  144. package/management-ui/src/components/ui/button.test.jsx +0 -56
  145. package/management-ui/src/components/ui/button.tsx +0 -57
  146. package/management-ui/src/components/ui/card.tsx +0 -76
  147. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  148. package/management-ui/src/components/ui/select.tsx +0 -157
  149. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  150. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  151. package/management-ui/src/hooks/useSocket.jsx +0 -58
  152. package/management-ui/src/index.css +0 -194
  153. package/management-ui/src/lib/utils.ts +0 -6
  154. package/management-ui/src/main.jsx +0 -10
  155. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  156. package/management-ui/src/pages/Connections.jsx +0 -252
  157. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -427
  158. package/management-ui/src/pages/Dashboard.jsx +0 -311
  159. package/management-ui/src/pages/Environment.jsx +0 -314
  160. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -544
  161. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -479
  162. package/management-ui/src/pages/IntegrationTest.jsx +0 -494
  163. package/management-ui/src/pages/Integrations.jsx +0 -254
  164. package/management-ui/src/pages/Monitoring.jsx +0 -17
  165. package/management-ui/src/pages/Simulation.jsx +0 -155
  166. package/management-ui/src/pages/Users.jsx +0 -492
  167. package/management-ui/src/services/api.js +0 -41
  168. package/management-ui/src/services/apiModuleService.js +0 -193
  169. package/management-ui/src/services/websocket-handlers.js +0 -120
  170. package/management-ui/src/test/api/project.test.js +0 -273
  171. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  172. package/management-ui/src/test/mocks/server.js +0 -178
  173. package/management-ui/src/test/setup.js +0 -61
  174. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  175. package/management-ui/src/utils/repository.js +0 -98
  176. package/management-ui/src/utils/repository.test.js +0 -118
  177. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  178. package/management-ui/tailwind.config.js +0 -63
  179. package/management-ui/tsconfig.json +0 -37
  180. package/management-ui/tsconfig.node.json +0 -10
  181. package/management-ui/vite.config.js +0 -26
  182. package/management-ui/vitest.config.js +0 -38
@@ -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