@spektre/veil 0.1.7 → 0.1.8
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.
- package/dist/index.esm.js +162 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +162 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -44,6 +44,21 @@ function injectDevUIStyles() {
|
|
|
44
44
|
box-shadow: 0 6px 16px rgba(100, 116, 139, 0.6);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
.spektre-dev-dot.warning {
|
|
48
|
+
background-color: #ef4444;
|
|
49
|
+
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.6);
|
|
50
|
+
animation: spektre-pulse 2s infinite;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@keyframes spektre-pulse {
|
|
54
|
+
0%, 100% {
|
|
55
|
+
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.6);
|
|
56
|
+
}
|
|
57
|
+
50% {
|
|
58
|
+
box-shadow: 0 4px 20px rgba(239, 68, 68, 0.8);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
47
62
|
/* Modal Overlay */
|
|
48
63
|
.spektre-dev-modal-overlay {
|
|
49
64
|
position: fixed;
|
|
@@ -134,6 +149,8 @@ function injectDevUIStyles() {
|
|
|
134
149
|
.spektre-dev-modal-body {
|
|
135
150
|
padding: 24px;
|
|
136
151
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
152
|
+
max-height: 60vh;
|
|
153
|
+
overflow-y: auto;
|
|
137
154
|
}
|
|
138
155
|
|
|
139
156
|
.spektre-dev-modal-info {
|
|
@@ -240,6 +257,52 @@ function injectDevUIStyles() {
|
|
|
240
257
|
font-weight: 500;
|
|
241
258
|
}
|
|
242
259
|
|
|
260
|
+
/* Security Scan Results */
|
|
261
|
+
.spektre-security-scan-container {
|
|
262
|
+
margin-top: 16px;
|
|
263
|
+
padding: 16px;
|
|
264
|
+
background-color: rgba(239, 68, 68, 0.1);
|
|
265
|
+
border: 1px solid rgba(239, 68, 68, 0.3);
|
|
266
|
+
border-radius: 8px;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.spektre-security-scan-title {
|
|
270
|
+
font-size: 14px;
|
|
271
|
+
font-weight: 600;
|
|
272
|
+
color: #fca5a5;
|
|
273
|
+
margin: 0 0 12px 0;
|
|
274
|
+
display: flex;
|
|
275
|
+
align-items: center;
|
|
276
|
+
gap: 8px;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.spektre-security-scan-issues {
|
|
280
|
+
display: flex;
|
|
281
|
+
flex-direction: column;
|
|
282
|
+
gap: 8px;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.spektre-security-issue {
|
|
286
|
+
font-size: 13px;
|
|
287
|
+
color: #fed7aa;
|
|
288
|
+
padding: 8px;
|
|
289
|
+
background-color: rgba(239, 68, 68, 0.15);
|
|
290
|
+
border-left: 3px solid #ef4444;
|
|
291
|
+
border-radius: 4px;
|
|
292
|
+
line-height: 1.4;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.spektre-security-scan-clean {
|
|
296
|
+
font-size: 13px;
|
|
297
|
+
color: #86efac;
|
|
298
|
+
padding: 12px;
|
|
299
|
+
background-color: rgba(34, 197, 94, 0.15);
|
|
300
|
+
border: 1px solid rgba(34, 197, 94, 0.3);
|
|
301
|
+
border-radius: 6px;
|
|
302
|
+
text-align: center;
|
|
303
|
+
font-weight: 500;
|
|
304
|
+
}
|
|
305
|
+
|
|
243
306
|
/* Accessibility */
|
|
244
307
|
@media (prefers-reduced-motion: reduce) {
|
|
245
308
|
.spektre-dev-dot,
|
|
@@ -284,6 +347,65 @@ function injectDevUIStyles() {
|
|
|
284
347
|
`;
|
|
285
348
|
document.head.appendChild(styleSheet);
|
|
286
349
|
}
|
|
350
|
+
function runSecurityScan() {
|
|
351
|
+
const issues = [];
|
|
352
|
+
// 1. Check for hardcoded API keys/tokens
|
|
353
|
+
const sensitivePatterns = [
|
|
354
|
+
{ pattern: /api[_-]?key\s*[:=]\s*['"]\S+['"]/gi, label: 'API Key' },
|
|
355
|
+
{ pattern: /token\s*[:=]\s*['"]\S+['"]/gi, label: 'Token' },
|
|
356
|
+
{ pattern: /password\s*[:=]\s*['"]\S+['"]/gi, label: 'Password' },
|
|
357
|
+
{ pattern: /secret\s*[:=]\s*['"]\S+['"]/gi, label: 'Secret' },
|
|
358
|
+
{ pattern: /bearer\s+[A-Za-z0-9\-._~+/]+=*/gi, label: 'Bearer Token' },
|
|
359
|
+
];
|
|
360
|
+
const pageHTML = document.documentElement.outerHTML;
|
|
361
|
+
const scriptTags = Array.from(document.querySelectorAll('script'));
|
|
362
|
+
const allText = pageHTML + scriptTags.map(s => s.textContent).join('\n');
|
|
363
|
+
sensitivePatterns.forEach(({ pattern, label }) => {
|
|
364
|
+
if (pattern.test(allText)) {
|
|
365
|
+
issues.push(`⚠️ Found hardcoded ${label} in page code`);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
// 2. Check for dangerous functions
|
|
369
|
+
const dangerousPatterns = [
|
|
370
|
+
{ pattern: /eval\s*\(/gi, label: 'eval() usage' },
|
|
371
|
+
{ pattern: /innerHTML\s*=/gi, label: 'innerHTML manipulation' },
|
|
372
|
+
{ pattern: /dangerouslySetInnerHTML/gi, label: 'dangerouslySetInnerHTML' },
|
|
373
|
+
{ pattern: /document\.write/gi, label: 'document.write()' },
|
|
374
|
+
{ pattern: /setTimeout\s*\(\s*['"`].*['"`]/gi, label: 'setTimeout with string' },
|
|
375
|
+
];
|
|
376
|
+
dangerousPatterns.forEach(({ pattern, label }) => {
|
|
377
|
+
if (pattern.test(allText)) {
|
|
378
|
+
issues.push(`⚠️ Potential security risk: ${label}`);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
// 3. Check localStorage for sensitive data
|
|
382
|
+
try {
|
|
383
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
384
|
+
const key = localStorage.key(i);
|
|
385
|
+
if (key) {
|
|
386
|
+
const value = localStorage.getItem(key);
|
|
387
|
+
if (value) {
|
|
388
|
+
if (/token|password|secret|key|auth/i.test(key) &&
|
|
389
|
+
value.length > 20) {
|
|
390
|
+
issues.push(`⚠️ Sensitive data in localStorage: "${key}"`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
catch (e) {
|
|
397
|
+
// localStorage access denied, skip
|
|
398
|
+
}
|
|
399
|
+
// 4. Check for missing CSP headers (via console warning detection)
|
|
400
|
+
const scripts = scriptTags.filter(s => s.src && !s.src.includes('spektre'));
|
|
401
|
+
if (scripts.length > 10) {
|
|
402
|
+
issues.push(`⚠️ Many external scripts loaded (${scripts.length})`);
|
|
403
|
+
}
|
|
404
|
+
return {
|
|
405
|
+
hasIssues: issues.length > 0,
|
|
406
|
+
issues,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
287
409
|
function initializeDevUI() {
|
|
288
410
|
// Inject styles first
|
|
289
411
|
injectDevUIStyles();
|
|
@@ -296,6 +418,18 @@ function initializeDevUI() {
|
|
|
296
418
|
}
|
|
297
419
|
// Create and inject the orange dot
|
|
298
420
|
createDevDot();
|
|
421
|
+
// Run security scan after a short delay to ensure DOM is ready
|
|
422
|
+
setTimeout(() => {
|
|
423
|
+
const scanResult = runSecurityScan();
|
|
424
|
+
if (scanResult.hasIssues) {
|
|
425
|
+
// Update dot to warning state and auto-open modal
|
|
426
|
+
const dot = document.getElementById('spektre-dev-dot');
|
|
427
|
+
if (dot) {
|
|
428
|
+
dot.classList.add('warning');
|
|
429
|
+
}
|
|
430
|
+
openDevModal(scanResult);
|
|
431
|
+
}
|
|
432
|
+
}, 500);
|
|
299
433
|
}
|
|
300
434
|
function createDevDot() {
|
|
301
435
|
const dot = document.createElement('div');
|
|
@@ -307,7 +441,7 @@ function createDevDot() {
|
|
|
307
441
|
});
|
|
308
442
|
document.body.appendChild(dot);
|
|
309
443
|
}
|
|
310
|
-
function openDevModal() {
|
|
444
|
+
function openDevModal(scanResult) {
|
|
311
445
|
// Check if modal already exists
|
|
312
446
|
if (document.getElementById('spektre-dev-modal')) {
|
|
313
447
|
return;
|
|
@@ -374,6 +508,33 @@ function openDevModal() {
|
|
|
374
508
|
body.appendChild(statusBadge);
|
|
375
509
|
body.appendChild(toggleContainer);
|
|
376
510
|
body.appendChild(reloadMessage);
|
|
511
|
+
// Add security scan results if available
|
|
512
|
+
if (scanResult) {
|
|
513
|
+
const scanContainer = document.createElement('div');
|
|
514
|
+
scanContainer.className = 'spektre-security-scan-container';
|
|
515
|
+
const scanTitle = document.createElement('div');
|
|
516
|
+
scanTitle.className = 'spektre-security-scan-title';
|
|
517
|
+
scanTitle.innerHTML = '🔒 Security Check';
|
|
518
|
+
scanContainer.appendChild(scanTitle);
|
|
519
|
+
if (scanResult.hasIssues) {
|
|
520
|
+
const issuesContainer = document.createElement('div');
|
|
521
|
+
issuesContainer.className = 'spektre-security-scan-issues';
|
|
522
|
+
scanResult.issues.forEach(issue => {
|
|
523
|
+
const issueElement = document.createElement('div');
|
|
524
|
+
issueElement.className = 'spektre-security-issue';
|
|
525
|
+
issueElement.textContent = issue;
|
|
526
|
+
issuesContainer.appendChild(issueElement);
|
|
527
|
+
});
|
|
528
|
+
scanContainer.appendChild(issuesContainer);
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
const cleanMessage = document.createElement('div');
|
|
532
|
+
cleanMessage.className = 'spektre-security-scan-clean';
|
|
533
|
+
cleanMessage.textContent = '✓ No security issues detected';
|
|
534
|
+
scanContainer.appendChild(cleanMessage);
|
|
535
|
+
}
|
|
536
|
+
body.appendChild(scanContainer);
|
|
537
|
+
}
|
|
377
538
|
modalContent.appendChild(header);
|
|
378
539
|
modalContent.appendChild(body);
|
|
379
540
|
modal.appendChild(modalContent);
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,21 @@ function injectDevUIStyles() {
|
|
|
46
46
|
box-shadow: 0 6px 16px rgba(100, 116, 139, 0.6);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
.spektre-dev-dot.warning {
|
|
50
|
+
background-color: #ef4444;
|
|
51
|
+
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.6);
|
|
52
|
+
animation: spektre-pulse 2s infinite;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@keyframes spektre-pulse {
|
|
56
|
+
0%, 100% {
|
|
57
|
+
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.6);
|
|
58
|
+
}
|
|
59
|
+
50% {
|
|
60
|
+
box-shadow: 0 4px 20px rgba(239, 68, 68, 0.8);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
49
64
|
/* Modal Overlay */
|
|
50
65
|
.spektre-dev-modal-overlay {
|
|
51
66
|
position: fixed;
|
|
@@ -136,6 +151,8 @@ function injectDevUIStyles() {
|
|
|
136
151
|
.spektre-dev-modal-body {
|
|
137
152
|
padding: 24px;
|
|
138
153
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
154
|
+
max-height: 60vh;
|
|
155
|
+
overflow-y: auto;
|
|
139
156
|
}
|
|
140
157
|
|
|
141
158
|
.spektre-dev-modal-info {
|
|
@@ -242,6 +259,52 @@ function injectDevUIStyles() {
|
|
|
242
259
|
font-weight: 500;
|
|
243
260
|
}
|
|
244
261
|
|
|
262
|
+
/* Security Scan Results */
|
|
263
|
+
.spektre-security-scan-container {
|
|
264
|
+
margin-top: 16px;
|
|
265
|
+
padding: 16px;
|
|
266
|
+
background-color: rgba(239, 68, 68, 0.1);
|
|
267
|
+
border: 1px solid rgba(239, 68, 68, 0.3);
|
|
268
|
+
border-radius: 8px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.spektre-security-scan-title {
|
|
272
|
+
font-size: 14px;
|
|
273
|
+
font-weight: 600;
|
|
274
|
+
color: #fca5a5;
|
|
275
|
+
margin: 0 0 12px 0;
|
|
276
|
+
display: flex;
|
|
277
|
+
align-items: center;
|
|
278
|
+
gap: 8px;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.spektre-security-scan-issues {
|
|
282
|
+
display: flex;
|
|
283
|
+
flex-direction: column;
|
|
284
|
+
gap: 8px;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.spektre-security-issue {
|
|
288
|
+
font-size: 13px;
|
|
289
|
+
color: #fed7aa;
|
|
290
|
+
padding: 8px;
|
|
291
|
+
background-color: rgba(239, 68, 68, 0.15);
|
|
292
|
+
border-left: 3px solid #ef4444;
|
|
293
|
+
border-radius: 4px;
|
|
294
|
+
line-height: 1.4;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.spektre-security-scan-clean {
|
|
298
|
+
font-size: 13px;
|
|
299
|
+
color: #86efac;
|
|
300
|
+
padding: 12px;
|
|
301
|
+
background-color: rgba(34, 197, 94, 0.15);
|
|
302
|
+
border: 1px solid rgba(34, 197, 94, 0.3);
|
|
303
|
+
border-radius: 6px;
|
|
304
|
+
text-align: center;
|
|
305
|
+
font-weight: 500;
|
|
306
|
+
}
|
|
307
|
+
|
|
245
308
|
/* Accessibility */
|
|
246
309
|
@media (prefers-reduced-motion: reduce) {
|
|
247
310
|
.spektre-dev-dot,
|
|
@@ -286,6 +349,65 @@ function injectDevUIStyles() {
|
|
|
286
349
|
`;
|
|
287
350
|
document.head.appendChild(styleSheet);
|
|
288
351
|
}
|
|
352
|
+
function runSecurityScan() {
|
|
353
|
+
const issues = [];
|
|
354
|
+
// 1. Check for hardcoded API keys/tokens
|
|
355
|
+
const sensitivePatterns = [
|
|
356
|
+
{ pattern: /api[_-]?key\s*[:=]\s*['"]\S+['"]/gi, label: 'API Key' },
|
|
357
|
+
{ pattern: /token\s*[:=]\s*['"]\S+['"]/gi, label: 'Token' },
|
|
358
|
+
{ pattern: /password\s*[:=]\s*['"]\S+['"]/gi, label: 'Password' },
|
|
359
|
+
{ pattern: /secret\s*[:=]\s*['"]\S+['"]/gi, label: 'Secret' },
|
|
360
|
+
{ pattern: /bearer\s+[A-Za-z0-9\-._~+/]+=*/gi, label: 'Bearer Token' },
|
|
361
|
+
];
|
|
362
|
+
const pageHTML = document.documentElement.outerHTML;
|
|
363
|
+
const scriptTags = Array.from(document.querySelectorAll('script'));
|
|
364
|
+
const allText = pageHTML + scriptTags.map(s => s.textContent).join('\n');
|
|
365
|
+
sensitivePatterns.forEach(({ pattern, label }) => {
|
|
366
|
+
if (pattern.test(allText)) {
|
|
367
|
+
issues.push(`⚠️ Found hardcoded ${label} in page code`);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
// 2. Check for dangerous functions
|
|
371
|
+
const dangerousPatterns = [
|
|
372
|
+
{ pattern: /eval\s*\(/gi, label: 'eval() usage' },
|
|
373
|
+
{ pattern: /innerHTML\s*=/gi, label: 'innerHTML manipulation' },
|
|
374
|
+
{ pattern: /dangerouslySetInnerHTML/gi, label: 'dangerouslySetInnerHTML' },
|
|
375
|
+
{ pattern: /document\.write/gi, label: 'document.write()' },
|
|
376
|
+
{ pattern: /setTimeout\s*\(\s*['"`].*['"`]/gi, label: 'setTimeout with string' },
|
|
377
|
+
];
|
|
378
|
+
dangerousPatterns.forEach(({ pattern, label }) => {
|
|
379
|
+
if (pattern.test(allText)) {
|
|
380
|
+
issues.push(`⚠️ Potential security risk: ${label}`);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
// 3. Check localStorage for sensitive data
|
|
384
|
+
try {
|
|
385
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
386
|
+
const key = localStorage.key(i);
|
|
387
|
+
if (key) {
|
|
388
|
+
const value = localStorage.getItem(key);
|
|
389
|
+
if (value) {
|
|
390
|
+
if (/token|password|secret|key|auth/i.test(key) &&
|
|
391
|
+
value.length > 20) {
|
|
392
|
+
issues.push(`⚠️ Sensitive data in localStorage: "${key}"`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
catch (e) {
|
|
399
|
+
// localStorage access denied, skip
|
|
400
|
+
}
|
|
401
|
+
// 4. Check for missing CSP headers (via console warning detection)
|
|
402
|
+
const scripts = scriptTags.filter(s => s.src && !s.src.includes('spektre'));
|
|
403
|
+
if (scripts.length > 10) {
|
|
404
|
+
issues.push(`⚠️ Many external scripts loaded (${scripts.length})`);
|
|
405
|
+
}
|
|
406
|
+
return {
|
|
407
|
+
hasIssues: issues.length > 0,
|
|
408
|
+
issues,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
289
411
|
function initializeDevUI() {
|
|
290
412
|
// Inject styles first
|
|
291
413
|
injectDevUIStyles();
|
|
@@ -298,6 +420,18 @@ function initializeDevUI() {
|
|
|
298
420
|
}
|
|
299
421
|
// Create and inject the orange dot
|
|
300
422
|
createDevDot();
|
|
423
|
+
// Run security scan after a short delay to ensure DOM is ready
|
|
424
|
+
setTimeout(() => {
|
|
425
|
+
const scanResult = runSecurityScan();
|
|
426
|
+
if (scanResult.hasIssues) {
|
|
427
|
+
// Update dot to warning state and auto-open modal
|
|
428
|
+
const dot = document.getElementById('spektre-dev-dot');
|
|
429
|
+
if (dot) {
|
|
430
|
+
dot.classList.add('warning');
|
|
431
|
+
}
|
|
432
|
+
openDevModal(scanResult);
|
|
433
|
+
}
|
|
434
|
+
}, 500);
|
|
301
435
|
}
|
|
302
436
|
function createDevDot() {
|
|
303
437
|
const dot = document.createElement('div');
|
|
@@ -309,7 +443,7 @@ function createDevDot() {
|
|
|
309
443
|
});
|
|
310
444
|
document.body.appendChild(dot);
|
|
311
445
|
}
|
|
312
|
-
function openDevModal() {
|
|
446
|
+
function openDevModal(scanResult) {
|
|
313
447
|
// Check if modal already exists
|
|
314
448
|
if (document.getElementById('spektre-dev-modal')) {
|
|
315
449
|
return;
|
|
@@ -376,6 +510,33 @@ function openDevModal() {
|
|
|
376
510
|
body.appendChild(statusBadge);
|
|
377
511
|
body.appendChild(toggleContainer);
|
|
378
512
|
body.appendChild(reloadMessage);
|
|
513
|
+
// Add security scan results if available
|
|
514
|
+
if (scanResult) {
|
|
515
|
+
const scanContainer = document.createElement('div');
|
|
516
|
+
scanContainer.className = 'spektre-security-scan-container';
|
|
517
|
+
const scanTitle = document.createElement('div');
|
|
518
|
+
scanTitle.className = 'spektre-security-scan-title';
|
|
519
|
+
scanTitle.innerHTML = '🔒 Security Check';
|
|
520
|
+
scanContainer.appendChild(scanTitle);
|
|
521
|
+
if (scanResult.hasIssues) {
|
|
522
|
+
const issuesContainer = document.createElement('div');
|
|
523
|
+
issuesContainer.className = 'spektre-security-scan-issues';
|
|
524
|
+
scanResult.issues.forEach(issue => {
|
|
525
|
+
const issueElement = document.createElement('div');
|
|
526
|
+
issueElement.className = 'spektre-security-issue';
|
|
527
|
+
issueElement.textContent = issue;
|
|
528
|
+
issuesContainer.appendChild(issueElement);
|
|
529
|
+
});
|
|
530
|
+
scanContainer.appendChild(issuesContainer);
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
const cleanMessage = document.createElement('div');
|
|
534
|
+
cleanMessage.className = 'spektre-security-scan-clean';
|
|
535
|
+
cleanMessage.textContent = '✓ No security issues detected';
|
|
536
|
+
scanContainer.appendChild(cleanMessage);
|
|
537
|
+
}
|
|
538
|
+
body.appendChild(scanContainer);
|
|
539
|
+
}
|
|
379
540
|
modalContent.appendChild(header);
|
|
380
541
|
modalContent.appendChild(body);
|
|
381
542
|
modal.appendChild(modalContent);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|