payment-skill 1.1.1 → 1.1.3
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/dashboard.html +14 -18
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +1 -0
- package/dist/server/server.js.map +1 -1
- package/package.json +1 -1
- package/public/dashboard.js +360 -0
- package/src/server/server.ts +1 -0
package/dashboard.html
CHANGED
|
@@ -290,7 +290,7 @@
|
|
|
290
290
|
</head>
|
|
291
291
|
<body>
|
|
292
292
|
<div class="header">
|
|
293
|
-
<button class="emergency-btn">🔴 Emergency Stop</button>
|
|
293
|
+
<button class="emergency-btn" id="emergency-btn">🔴 Emergency Stop</button>
|
|
294
294
|
<img src="logo.png" alt="Logo" class="header-logo">
|
|
295
295
|
</div>
|
|
296
296
|
|
|
@@ -354,18 +354,16 @@
|
|
|
354
354
|
</div>
|
|
355
355
|
<div class="section-body">
|
|
356
356
|
<div class="form-row">
|
|
357
|
-
<div class="form-group"><label>Per Transaction</label><input type="
|
|
358
|
-
<div class="form-group"><label>Per Hour</label><input type="
|
|
359
|
-
<div class="form-group"><label>Per Day</label><input type="
|
|
360
|
-
<div class="form-group"><label>Per Week</label><input type="
|
|
357
|
+
<div class="form-group"><label>Per Transaction</label><input type="number" id="per-transaction-limit" value="10000"></div>
|
|
358
|
+
<div class="form-group"><label>Per Hour</label><input type="number" id="hourly-limit" value="10"></div>
|
|
359
|
+
<div class="form-group"><label>Per Day</label><input type="number" id="daily-limit" value="50000"></div>
|
|
360
|
+
<div class="form-group"><label>Per Week</label><input type="number" id="weekly-limit" value="200000"></div>
|
|
361
361
|
</div>
|
|
362
362
|
<div class="form-row">
|
|
363
|
-
<div class="form-group"><label>Per Month</label><input type="
|
|
364
|
-
<div class="form-group"><label>
|
|
365
|
-
<div class="form-group"><label>Currency</label><select><option>USD</option><option>EUR</option></select></div>
|
|
366
|
-
<div class="form-group"><label>Max Tx/Hour</label><input type="text" value="20"></div>
|
|
363
|
+
<div class="form-group"><label>Per Month</label><input type="number" id="monthly-limit" value="500000"></div>
|
|
364
|
+
<div class="form-group"><label>Currency</label><select id="limit-currency"><option>USD</option><option>EUR</option></select></div>
|
|
367
365
|
</div>
|
|
368
|
-
<button class="save-section-btn">Save Account Limits</button>
|
|
366
|
+
<button class="save-section-btn" onclick="saveAccountLimits()">Save Account Limits</button>
|
|
369
367
|
<div class="clearfix"></div>
|
|
370
368
|
</div>
|
|
371
369
|
</div>
|
|
@@ -450,18 +448,15 @@
|
|
|
450
448
|
</div>
|
|
451
449
|
<div class="section-body">
|
|
452
450
|
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 12px;">
|
|
453
|
-
<
|
|
454
|
-
<div style="position: absolute; width: 14px; height: 14px; background: white; border-radius: 50%; top: 2px; right: 2px;"></div>
|
|
455
|
-
</div>
|
|
451
|
+
<input type="checkbox" id="time-window-enabled" style="width: 18px; height: 18px; cursor: pointer;">
|
|
456
452
|
<span style="font-size: 11px;">Enable time window enforcement</span>
|
|
457
453
|
</div>
|
|
458
454
|
<div class="form-row">
|
|
459
|
-
<div class="form-group"><label>Start Time</label><input type="time" value="08:00"></div>
|
|
460
|
-
<div class="form-group"><label>End Time</label><input type="time" value="22:00"></div>
|
|
461
|
-
<div class="form-group"><label>Timezone</label><select><option>Europe/Bucharest</option><option>UTC</option></select></div>
|
|
462
|
-
<div class="form-group"><label>Blocked Days</label><select><option>None</option><option>Weekends</option></select></div>
|
|
455
|
+
<div class="form-group"><label>Start Time</label><input type="time" id="start-time" value="08:00"></div>
|
|
456
|
+
<div class="form-group"><label>End Time</label><input type="time" id="end-time" value="22:00"></div>
|
|
457
|
+
<div class="form-group"><label>Timezone</label><select id="timezone"><option>Europe/Bucharest</option><option>UTC</option></select></div>
|
|
463
458
|
</div>
|
|
464
|
-
<button class="save-section-btn">Save Time Policy</button>
|
|
459
|
+
<button class="save-section-btn" onclick="saveTimeWindow()">Save Time Policy</button>
|
|
465
460
|
<div class="clearfix"></div>
|
|
466
461
|
</div>
|
|
467
462
|
</div>
|
|
@@ -665,5 +660,6 @@
|
|
|
665
660
|
arrow.textContent = body.classList.contains('collapsed') ? '▶' : '▼';
|
|
666
661
|
}
|
|
667
662
|
</script>
|
|
663
|
+
<script src="/public/dashboard.js"></script>
|
|
668
664
|
</body>
|
|
669
665
|
</html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,GAAE,MAAa;IAO/B,OAAO,CAAC,eAAe;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,GAAE,MAAa;IAO/B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,WAAW;IAkMnB,KAAK,IAAI,IAAI;CAMd"}
|
package/dist/server/server.js
CHANGED
|
@@ -29,6 +29,7 @@ class PaymentSkillServer {
|
|
|
29
29
|
this.app.use((0, cors_1.default)());
|
|
30
30
|
this.app.use(express_1.default.json());
|
|
31
31
|
this.app.use(express_1.default.static(path_1.default.join(__dirname, '../../')));
|
|
32
|
+
this.app.use('/public', express_1.default.static(path_1.default.join(__dirname, '../../public')));
|
|
32
33
|
}
|
|
33
34
|
setupRoutes() {
|
|
34
35
|
// Health check
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;AAEH,sDAA8B;AAC9B,gDAAwB;AACxB,oDAA4B;AAC5B,gDAAwB;AACxB,2CAA+C;AAC/C,qDAAyD;AAEzD,MAAa,kBAAkB;IAI7B,YAAY,OAAe,IAAI;QAC7B,IAAI,CAAC,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,EAAC;YAClB,qBAAqB,EAAE,KAAK,CAAC,qCAAqC;SACnE,CAAC,CAAC,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,GAAE,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,MAAM,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Skill Dashboard - JavaScript API Client
|
|
3
|
+
*
|
|
4
|
+
* Connects dashboard UI to backend API
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const API_BASE = '';
|
|
8
|
+
|
|
9
|
+
// Utility functions
|
|
10
|
+
function showNotification(message, type = 'success') {
|
|
11
|
+
const notification = document.createElement('div');
|
|
12
|
+
notification.style.cssText = `
|
|
13
|
+
position: fixed;
|
|
14
|
+
top: 20px;
|
|
15
|
+
right: 20px;
|
|
16
|
+
padding: 12px 20px;
|
|
17
|
+
border-radius: 6px;
|
|
18
|
+
color: white;
|
|
19
|
+
font-size: 12px;
|
|
20
|
+
z-index: 10000;
|
|
21
|
+
background: ${type === 'success' ? '#22c55e' : type === 'error' ? '#dc2626' : '#3b82f6'};
|
|
22
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
23
|
+
`;
|
|
24
|
+
notification.textContent = message;
|
|
25
|
+
document.body.appendChild(notification);
|
|
26
|
+
setTimeout(() => notification.remove(), 3000);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function apiGet(endpoint) {
|
|
30
|
+
try {
|
|
31
|
+
const response = await fetch(`${API_BASE}${endpoint}`);
|
|
32
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
33
|
+
return await response.json();
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error('API Error:', error);
|
|
36
|
+
showNotification(`Error: ${error.message}`, 'error');
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function apiPost(endpoint, data) {
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch(`${API_BASE}${endpoint}`, {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: { 'Content-Type': 'application/json' },
|
|
46
|
+
body: JSON.stringify(data)
|
|
47
|
+
});
|
|
48
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
49
|
+
const result = await response.json();
|
|
50
|
+
showNotification(result.message || 'Success');
|
|
51
|
+
return result;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('API Error:', error);
|
|
54
|
+
showNotification(`Error: ${error.message}`, 'error');
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Load all limits and controls
|
|
60
|
+
async function loadLimits() {
|
|
61
|
+
try {
|
|
62
|
+
const data = await apiGet('/api/limits');
|
|
63
|
+
|
|
64
|
+
// Update Account Limits
|
|
65
|
+
if (data.limits) {
|
|
66
|
+
document.getElementById('per-transaction-limit').value = data.limits.perTransaction || '';
|
|
67
|
+
document.getElementById('daily-limit').value = data.limits.daily || '';
|
|
68
|
+
document.getElementById('weekly-limit').value = data.limits.weekly || '';
|
|
69
|
+
document.getElementById('monthly-limit').value = data.limits.monthly || '';
|
|
70
|
+
document.getElementById('hourly-limit').value = data.limits.maxTransactionsPerHour || '';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Update Time Window
|
|
74
|
+
if (data.timeWindow) {
|
|
75
|
+
document.getElementById('time-window-enabled').checked = data.timeWindow.enabled;
|
|
76
|
+
document.getElementById('start-time').value = data.timeWindow.start || '08:00';
|
|
77
|
+
document.getElementById('end-time').value = data.timeWindow.end || '22:00';
|
|
78
|
+
document.getElementById('timezone').value = data.timeWindow.timezone || 'Europe/Bucharest';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Update Cumulative Budgets
|
|
82
|
+
if (data.cumulativeBudgets) {
|
|
83
|
+
updateBudgetsList(data.cumulativeBudgets);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Update Domain Controls
|
|
87
|
+
if (data.domainControls) {
|
|
88
|
+
document.getElementById('domain-mode').value = data.domainControls.mode || 'blacklist';
|
|
89
|
+
updateDomainsList(data.domainControls.domains || []);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Update Geography Controls
|
|
93
|
+
if (data.geographyControls) {
|
|
94
|
+
document.getElementById('geo-enabled').checked = data.geographyControls.enabled;
|
|
95
|
+
document.getElementById('geo-mode').value = data.geographyControls.mode || 'allow';
|
|
96
|
+
updateCountriesList(data.geographyControls.countries || []);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Update Category Controls
|
|
100
|
+
if (data.categoryControls) {
|
|
101
|
+
updateBlockedCategories(data.categoryControls.blockedCategories || []);
|
|
102
|
+
updateAllowedCategories(data.categoryControls.allowedCategories || []);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.error('Failed to load limits:', error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Save Account Limits
|
|
111
|
+
async function saveAccountLimits() {
|
|
112
|
+
const limits = {
|
|
113
|
+
perTransaction: parseInt(document.getElementById('per-transaction-limit').value) || 0,
|
|
114
|
+
daily: parseInt(document.getElementById('daily-limit').value) || 0,
|
|
115
|
+
weekly: parseInt(document.getElementById('weekly-limit').value) || 0,
|
|
116
|
+
monthly: parseInt(document.getElementById('monthly-limit').value) || 0,
|
|
117
|
+
maxTransactionsPerHour: parseInt(document.getElementById('hourly-limit').value) || 0
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
await apiPost('/api/limits', limits);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Save Time Window
|
|
124
|
+
async function saveTimeWindow() {
|
|
125
|
+
const timeWindow = {
|
|
126
|
+
enabled: document.getElementById('time-window-enabled').checked,
|
|
127
|
+
start: document.getElementById('start-time').value,
|
|
128
|
+
end: document.getElementById('end-time').value,
|
|
129
|
+
timezone: document.getElementById('timezone').value
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
await apiPost('/api/limits/time-window', timeWindow);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Budget Management
|
|
136
|
+
let budgets = [];
|
|
137
|
+
|
|
138
|
+
function updateBudgetsList(budgetsList) {
|
|
139
|
+
budgets = budgetsList;
|
|
140
|
+
const container = document.getElementById('budgets-list');
|
|
141
|
+
if (!container) return;
|
|
142
|
+
|
|
143
|
+
container.innerHTML = budgets.map((b, i) => `
|
|
144
|
+
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8px; background: var(--bg-primary); border-radius: 4px; margin-bottom: 5px;">
|
|
145
|
+
<span>${b.amount} ${b.currency || ''} per ${b.period}</span>
|
|
146
|
+
<button onclick="removeBudget(${i})" style="background: #dc2626; color: white; border: none; padding: 4px 8px; border-radius: 3px; cursor: pointer; font-size: 10px;">Remove</button>
|
|
147
|
+
</div>
|
|
148
|
+
`).join('');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function addBudget() {
|
|
152
|
+
const amount = parseFloat(document.getElementById('budget-amount').value);
|
|
153
|
+
const currency = document.getElementById('budget-currency').value || 'EUR';
|
|
154
|
+
const period = document.getElementById('budget-period').value;
|
|
155
|
+
|
|
156
|
+
if (!amount || !period) {
|
|
157
|
+
showNotification('Please fill in all fields', 'error');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
await apiPost('/api/limits/budgets', { amount, currency, period, enabled: true });
|
|
162
|
+
document.getElementById('budget-amount').value = '';
|
|
163
|
+
await loadLimits();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function removeBudget(index) {
|
|
167
|
+
try {
|
|
168
|
+
const response = await fetch(`${API_BASE}/api/limits/budgets/${index}`, { method: 'DELETE' });
|
|
169
|
+
if (!response.ok) throw new Error('Failed to remove budget');
|
|
170
|
+
showNotification('Budget removed');
|
|
171
|
+
await loadLimits();
|
|
172
|
+
} catch (error) {
|
|
173
|
+
showNotification('Error removing budget', 'error');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Domain Management
|
|
178
|
+
let domains = [];
|
|
179
|
+
|
|
180
|
+
function updateDomainsList(domainList) {
|
|
181
|
+
domains = domainList;
|
|
182
|
+
const container = document.getElementById('domains-list');
|
|
183
|
+
if (!container) return;
|
|
184
|
+
|
|
185
|
+
container.innerHTML = domains.map(d => `
|
|
186
|
+
<span style="background: rgba(59, 130, 246, 0.2); color: #3b82f6; padding: 3px 8px; border-radius: 3px; font-size: 10px; display: inline-flex; align-items: center; gap: 5px; margin: 2px;">
|
|
187
|
+
${d}
|
|
188
|
+
<button onclick="removeDomain('${d}')" style="background: none; border: none; color: #ef4444; cursor: pointer; font-size: 12px; padding: 0;">×</button>
|
|
189
|
+
</span>
|
|
190
|
+
`).join('');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async function addDomain() {
|
|
194
|
+
const domain = document.getElementById('new-domain').value.trim();
|
|
195
|
+
if (!domain) return;
|
|
196
|
+
|
|
197
|
+
await apiPost('/api/limits/domains', { domain });
|
|
198
|
+
document.getElementById('new-domain').value = '';
|
|
199
|
+
await loadLimits();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function removeDomain(domain) {
|
|
203
|
+
try {
|
|
204
|
+
const response = await fetch(`${API_BASE}/api/limits/domains/${encodeURIComponent(domain)}`, { method: 'DELETE' });
|
|
205
|
+
if (!response.ok) throw new Error('Failed to remove domain');
|
|
206
|
+
showNotification('Domain removed');
|
|
207
|
+
await loadLimits();
|
|
208
|
+
} catch (error) {
|
|
209
|
+
showNotification('Error removing domain', 'error');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function saveDomainMode() {
|
|
214
|
+
const mode = document.getElementById('domain-mode').value;
|
|
215
|
+
await apiPost('/api/limits/domains', { mode });
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Geography Management
|
|
219
|
+
let countries = [];
|
|
220
|
+
|
|
221
|
+
function updateCountriesList(countryList) {
|
|
222
|
+
countries = countryList;
|
|
223
|
+
const container = document.getElementById('countries-list');
|
|
224
|
+
if (!container) return;
|
|
225
|
+
|
|
226
|
+
container.innerHTML = countries.map(c => `
|
|
227
|
+
<span style="background: rgba(34, 197, 94, 0.2); color: #22c55e; padding: 3px 8px; border-radius: 3px; font-size: 10px; display: inline-flex; align-items: center; gap: 5px; margin: 2px;">
|
|
228
|
+
${c}
|
|
229
|
+
<button onclick="removeCountry('${c}')" style="background: none; border: none; color: #ef4444; cursor: pointer; font-size: 12px; padding: 0;">×</button>
|
|
230
|
+
</span>
|
|
231
|
+
`).join('');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function addCountry() {
|
|
235
|
+
const country = document.getElementById('new-country').value.trim().toUpperCase();
|
|
236
|
+
if (!country) return;
|
|
237
|
+
|
|
238
|
+
await apiPost('/api/limits/geo', { country });
|
|
239
|
+
document.getElementById('new-country').value = '';
|
|
240
|
+
await loadLimits();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function removeCountry(country) {
|
|
244
|
+
try {
|
|
245
|
+
const response = await fetch(`${API_BASE}/api/limits/geo/${country}`, { method: 'DELETE' });
|
|
246
|
+
if (!response.ok) throw new Error('Failed to remove country');
|
|
247
|
+
showNotification('Country removed');
|
|
248
|
+
await loadLimits();
|
|
249
|
+
} catch (error) {
|
|
250
|
+
showNotification('Error removing country', 'error');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async function saveGeoSettings() {
|
|
255
|
+
const enabled = document.getElementById('geo-enabled').checked;
|
|
256
|
+
const mode = document.getElementById('geo-mode').value;
|
|
257
|
+
await apiPost('/api/limits/geo', { enabled, mode });
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Category Management
|
|
261
|
+
function updateBlockedCategories(categories) {
|
|
262
|
+
const container = document.getElementById('blocked-categories-list');
|
|
263
|
+
if (!container) return;
|
|
264
|
+
|
|
265
|
+
container.innerHTML = categories.map(c => `
|
|
266
|
+
<span style="background: rgba(220, 38, 38, 0.2); color: #ef4444; padding: 3px 8px; border-radius: 3px; font-size: 10px; display: inline-flex; align-items: center; gap: 5px; margin: 2px;">
|
|
267
|
+
${c}
|
|
268
|
+
<button onclick="unblockCategory('${c}')" style="background: none; border: none; color: #ef4444; cursor: pointer; font-size: 12px; padding: 0;">×</button>
|
|
269
|
+
</span>
|
|
270
|
+
`).join('');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function updateAllowedCategories(categories) {
|
|
274
|
+
const container = document.getElementById('allowed-categories-list');
|
|
275
|
+
if (!container) return;
|
|
276
|
+
|
|
277
|
+
container.innerHTML = categories.map(c => `
|
|
278
|
+
<span style="background: rgba(34, 197, 94, 0.2); color: #22c55e; padding: 3px 8px; border-radius: 3px; font-size: 10px; display: inline-flex; align-items: center; gap: 5px; margin: 2px;">
|
|
279
|
+
${c}
|
|
280
|
+
<button onclick="disallowCategory('${c}')" style="background: none; border: none; color: #ef4444; cursor: pointer; font-size: 12px; padding: 0;">×</button>
|
|
281
|
+
</span>
|
|
282
|
+
`).join('');
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async function blockCategory() {
|
|
286
|
+
const category = document.getElementById('new-blocked-category').value.trim();
|
|
287
|
+
if (!category) return;
|
|
288
|
+
|
|
289
|
+
await apiPost('/api/limits/categories/block', { category });
|
|
290
|
+
document.getElementById('new-blocked-category').value = '';
|
|
291
|
+
await loadLimits();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async function unblockCategory(category) {
|
|
295
|
+
await apiPost('/api/limits/categories/unblock', { category });
|
|
296
|
+
await loadLimits();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async function allowCategory() {
|
|
300
|
+
const category = document.getElementById('new-allowed-category').value.trim();
|
|
301
|
+
if (!category) return;
|
|
302
|
+
|
|
303
|
+
await apiPost('/api/limits/categories/allow', { category });
|
|
304
|
+
document.getElementById('new-allowed-category').value = '';
|
|
305
|
+
await loadLimits();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async function disallowCategory(category) {
|
|
309
|
+
await apiPost('/api/limits/categories/disallow', { category });
|
|
310
|
+
await loadLimits();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Emergency Stop
|
|
314
|
+
async function toggleEmergencyStop() {
|
|
315
|
+
const btn = document.getElementById('emergency-btn');
|
|
316
|
+
const isActive = btn.classList.contains('active');
|
|
317
|
+
|
|
318
|
+
if (!isActive) {
|
|
319
|
+
// Activate
|
|
320
|
+
if (!confirm('Are you sure you want to activate EMERGENCY STOP? This will halt all transactions.')) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
await apiPost('/api/emergency/stop', { reason: 'Dashboard activation' });
|
|
324
|
+
btn.classList.add('active');
|
|
325
|
+
btn.textContent = '🔴 Emergency Stop ACTIVE - Click to Resume';
|
|
326
|
+
showNotification('Emergency stop activated', 'error');
|
|
327
|
+
} else {
|
|
328
|
+
// Deactivate
|
|
329
|
+
await apiPost('/api/emergency/resume', {});
|
|
330
|
+
btn.classList.remove('active');
|
|
331
|
+
btn.textContent = '🔴 Emergency Stop';
|
|
332
|
+
showNotification('Emergency stop deactivated');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Load emergency stop status
|
|
337
|
+
async function loadEmergencyStatus() {
|
|
338
|
+
try {
|
|
339
|
+
const data = await apiGet('/api/emergency');
|
|
340
|
+
const btn = document.getElementById('emergency-btn');
|
|
341
|
+
if (data.active) {
|
|
342
|
+
btn.classList.add('active');
|
|
343
|
+
btn.textContent = '🔴 Emergency Stop ACTIVE - Click to Resume';
|
|
344
|
+
}
|
|
345
|
+
} catch (error) {
|
|
346
|
+
console.error('Failed to load emergency status:', error);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Initialize dashboard
|
|
351
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
352
|
+
loadLimits();
|
|
353
|
+
loadEmergencyStatus();
|
|
354
|
+
|
|
355
|
+
// Set up emergency button
|
|
356
|
+
const emergencyBtn = document.getElementById('emergency-btn');
|
|
357
|
+
if (emergencyBtn) {
|
|
358
|
+
emergencyBtn.addEventListener('click', toggleEmergencyStop);
|
|
359
|
+
}
|
|
360
|
+
});
|
package/src/server/server.ts
CHANGED
|
@@ -29,6 +29,7 @@ export class PaymentSkillServer {
|
|
|
29
29
|
this.app.use(cors());
|
|
30
30
|
this.app.use(express.json());
|
|
31
31
|
this.app.use(express.static(path.join(__dirname, '../../')));
|
|
32
|
+
this.app.use('/public', express.static(path.join(__dirname, '../../public')));
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
private setupRoutes(): void {
|