sequelize-game-bank 3.0.2 → 5.0.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.
- package/README.md +64 -36
- package/config/setup-env.js +34 -0
- package/database/services/account/transfer.js +1 -1
- package/index.js +19 -11
- package/package.json +1 -1
- package/public/accounts.html +11 -11
- package/public/admin.html +5 -5
- package/public/credit.html +10 -10
- package/public/css/style.css +3 -1
- package/public/general.html +11 -11
- package/public/history.html +11 -11
- package/public/home.html +2 -2
- package/public/js/js.js +19 -95
- package/public/login.html +3 -3
- package/public/profile.html +10 -10
- package/public/register.html +7 -7
- package/public/transfer.html +10 -10
- package/public/uploads/avatars/PAVEL_1792314486483.png +0 -0
- package/public/uploads/avatars/root_1792312973479.png +0 -0
- package/public/uploads/avatars/root_1792313212019.png +0 -0
- package/server/server.js +31 -28
- package/database/services/bot/generators/ban-bot.html +0 -1
- package/database/services/bot/generators/ban-bot.txt +0 -1
- package/database/services/bot/generators/disable-2FA-bot.html +0 -1
- package/database/services/bot/generators/disable-2FA-bot.txt +0 -1
- package/database/services/bot/generators/enable-2FA-bot.html +0 -1
- package/database/services/bot/generators/enable-2FA-bot.txt +0 -1
- package/database/services/bot/generators/login-bot.html +0 -1
- package/database/services/bot/generators/login-bot.txt +0 -1
- package/database/services/bot/generators/register-bot.html +0 -1
- package/database/services/bot/generators/register-bot.txt +0 -7
- package/database/services/bot/generators/transfer-from-bot.html +0 -1
- package/database/services/bot/generators/transfer-from-bot.txt +0 -1
- package/database/services/bot/generators/transfer-to-bot.html +0 -1
- package/database/services/bot/generators/transfer-to-bot.txt +0 -1
- package/database/services/bot/generators/unban-bot.html +0 -1
- package/database/services/bot/generators/unban-bot.txt +0 -1
package/public/js/js.js
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
//import Toastifyt from 'https://cdn.jsdelivr.net/npm/toastify-js';
|
|
2
1
|
const toastifyScript = document.createElement('script');
|
|
3
2
|
toastifyScript.src = 'https://cdn.jsdelivr.net/npm/toastify-js';
|
|
4
3
|
document.head.append(toastifyScript);
|
|
5
4
|
let currentUsername = "";
|
|
6
|
-
|
|
7
5
|
function showTab(tabId) {
|
|
8
6
|
document.querySelectorAll('.section').forEach(s => s.classList.remove('active'));
|
|
9
7
|
document.querySelectorAll('.menu-btn').forEach(b => b.classList.remove('active'));
|
|
10
8
|
document.getElementById(tabId).classList.add('active');
|
|
11
9
|
event.target.classList.add('active');
|
|
12
10
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
11
|
window.tippy('#general', {
|
|
19
12
|
content: "Главная",
|
|
20
13
|
placement:'top-end',
|
|
@@ -57,22 +50,9 @@ let currentUsername = "";
|
|
|
57
50
|
animation:'scale-extreme',
|
|
58
51
|
theme:"light"
|
|
59
52
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
53
|
async function loadData() {
|
|
74
54
|
try {
|
|
75
|
-
let response = await fetch('/api/accounts/my');
|
|
55
|
+
let response = await fetch('/api/bank/accounts/my');
|
|
76
56
|
if (response.status === 401 || response.status === 403) {
|
|
77
57
|
window.Swal.fire({
|
|
78
58
|
title: 'Внимание!',
|
|
@@ -83,11 +63,11 @@ let currentUsername = "";
|
|
|
83
63
|
confirmButtonColor: '#3085d6',
|
|
84
64
|
background:'#d6cb3089'
|
|
85
65
|
});
|
|
86
|
-
window.location.href = '/login.html';
|
|
66
|
+
window.location.href = '/bank/login.html';
|
|
87
67
|
return;
|
|
88
68
|
}
|
|
89
69
|
let result = await response.json();
|
|
90
|
-
let mannyRes = await fetch('/api/users/my-total-manny');
|
|
70
|
+
let mannyRes = await fetch('/api/bank/users/my-total-manny');
|
|
91
71
|
let mannyData = await mannyRes.json();
|
|
92
72
|
currentUsername = mannyData.username;
|
|
93
73
|
const userDisplay = document.getElementById('user-display');
|
|
@@ -152,7 +132,7 @@ let currentUsername = "";
|
|
|
152
132
|
}
|
|
153
133
|
});
|
|
154
134
|
}
|
|
155
|
-
let profileRes = await fetch('/api/users/profile');
|
|
135
|
+
let profileRes = await fetch('/api/bank/users/profile');
|
|
156
136
|
let profileData = await profileRes.json();
|
|
157
137
|
const userAvatar = document.getElementById('user-avatar');
|
|
158
138
|
window.tippy("#user-avatar", {
|
|
@@ -185,38 +165,11 @@ let currentUsername = "";
|
|
|
185
165
|
});
|
|
186
166
|
}
|
|
187
167
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
168
|
async function openCreateAccountModal() {
|
|
216
169
|
const pin = await window.Swal.fire({title: 'Создание щёта', text: 'Введите надёжный пин-код!', icon: 'question', iconColor:"blue", input:"number", inputAttributes: { autocapitalize: "off" }, preConfirm:async(pincode)=>{return pincode}, confirmButtonText: 'ОК', confirmButtonColor: '#3085d6', background:'#ffffffaf'})
|
|
217
170
|
if (!pin.value) return;
|
|
218
171
|
const fa = await Swal.fire({title: 'Создание щёта', text: 'Включить индивидуальную 2FA-защиту транзакций для этого счета?', icon: 'question', iconColor:"blue", showCancelButton: true, confirmButtonColor: '#3085d6', cancelButtonColor: '#3085d6', confirmButtonText: 'Да, включить', cancelButtonText: 'Нет, не включать'}).then((result) => {return result;});
|
|
219
|
-
const res = await fetch('/api/accounts', {
|
|
172
|
+
const res = await fetch('/api/bank/accounts', {
|
|
220
173
|
method: 'POST',
|
|
221
174
|
headers: {'Content-Type': 'application/json'},
|
|
222
175
|
body: JSON.stringify({ pinCode: pin.value, enableAccount2FA: fa.isConfirmed })
|
|
@@ -253,7 +206,7 @@ let currentUsername = "";
|
|
|
253
206
|
const fa = await Swal.fire({title: 'Перевод', text: 'Вы подтверждаете перевод?', icon: 'question', iconColor:"blue", showCancelButton: true, confirmButtonColor: '#3085d6', cancelButtonColor: '#3085d6', confirmButtonText: 'Да, перевести', cancelButtonText: 'Нет, не переводить'}).then((result) => {return result;});
|
|
254
207
|
if(!fa.isConfirmed) return
|
|
255
208
|
|
|
256
|
-
const res = await fetch('/api/accounts/transfer', {
|
|
209
|
+
const res = await fetch('/api/bank/accounts/transfer', {
|
|
257
210
|
method: 'POST',
|
|
258
211
|
headers: {'Content-Type': 'application/json'},
|
|
259
212
|
body: JSON.stringify({ fromId, toId, amount, pinCode })
|
|
@@ -275,20 +228,13 @@ let currentUsername = "";
|
|
|
275
228
|
console.error("Ошибка ["+data.statusCode+"]: " + data.message);
|
|
276
229
|
}
|
|
277
230
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
231
|
async function applyForCredit() {
|
|
286
232
|
const targetAccountId = document.getElementById('credit-target').value;
|
|
287
233
|
const amount = document.getElementById('credit-amount').value;
|
|
288
234
|
const paymentsCount = document.getElementById('credit-payments').value;
|
|
289
235
|
const autoWithdrawal = document.getElementById('credit-auto').checked;
|
|
290
236
|
const pinCode = document.getElementById('credit-pin').value;
|
|
291
|
-
const res = await fetch('/api/accounts/credit', {
|
|
237
|
+
const res = await fetch('/api/bank/accounts/credit', {
|
|
292
238
|
method: 'POST',
|
|
293
239
|
headers: {'Content-Type': 'application/json'},
|
|
294
240
|
body: JSON.stringify({
|
|
@@ -347,48 +293,26 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
347
293
|
await Toastify({ text: `Выход из аккаунта`, duration: 3000, style: { background: "rgb(245, 128, 11)" }}).showToast();
|
|
348
294
|
|
|
349
295
|
try {
|
|
350
|
-
await fetch('/api/users/logout', { method: 'POST' });
|
|
296
|
+
await fetch('/api/bank/users/logout', { method: 'POST' });
|
|
351
297
|
} catch (e) {
|
|
352
298
|
console.error('Ошибка сети при логауте:', e.message);
|
|
353
299
|
}
|
|
354
|
-
window.location.href = '/home.html';
|
|
300
|
+
window.location.href = '/bank/home.html';
|
|
355
301
|
});
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
302
|
window.onload = loadData;
|
|
374
303
|
let user2FaActive = false;
|
|
375
|
-
|
|
376
304
|
async function syncProfileSectionData() {
|
|
377
305
|
try {
|
|
378
|
-
const response = await fetch('/api/users/profile');
|
|
379
|
-
|
|
380
|
-
// 🔑 ЗАЩИТА: Если бэкенд вернул ошибку (не 200 OK), не пытаемся парсить JSON
|
|
306
|
+
const response = await fetch('/api/bank/users/profile/settings');
|
|
381
307
|
if (!response.ok) {
|
|
382
308
|
console.warn("⚠️ [City-bank] Не удалось загрузить данные профиля, сервер вернул статус:", response.status);
|
|
383
309
|
return;
|
|
384
310
|
}
|
|
385
|
-
|
|
386
311
|
const result = await response.json();
|
|
387
312
|
if (result.status && result.user) {
|
|
388
313
|
if (result.user.avatar) {
|
|
389
314
|
document.getElementById('user-avatar').src = result.user.avatar;
|
|
390
|
-
}
|
|
391
|
-
|
|
315
|
+
}
|
|
392
316
|
user2FaActive = result.user.two_fa_status;
|
|
393
317
|
const statusText = document.getElementById('2fa-current-status');
|
|
394
318
|
const toggleBtn = document.getElementById('btn-toggle-2fa');
|
|
@@ -418,7 +342,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
418
342
|
formData.append('avatar', fileInput.files[0]);
|
|
419
343
|
|
|
420
344
|
try {
|
|
421
|
-
const res = await fetch('/api/users/avatar', {
|
|
345
|
+
const res = await fetch('/api/bank/users/avatar', {
|
|
422
346
|
method: 'POST',
|
|
423
347
|
body: formData
|
|
424
348
|
});
|
|
@@ -454,7 +378,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
454
378
|
if (!totpCode) return;
|
|
455
379
|
}
|
|
456
380
|
try {
|
|
457
|
-
const res = await fetch('/api/users/change-password', {
|
|
381
|
+
const res = await fetch('/api/bank/users/change-password', {
|
|
458
382
|
method: 'POST',
|
|
459
383
|
headers: {'Content-Type': 'application/json'},
|
|
460
384
|
body: JSON.stringify({ oldPassword, newPassword, totpCode })
|
|
@@ -485,7 +409,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
485
409
|
}
|
|
486
410
|
|
|
487
411
|
try {
|
|
488
|
-
const res = await fetch('/api/users/change-gmail', {
|
|
412
|
+
const res = await fetch('/api/bank/users/change-gmail', {
|
|
489
413
|
method: 'POST',
|
|
490
414
|
headers: {'Content-Type': 'application/json'},
|
|
491
415
|
body: JSON.stringify({ newGmail })
|
|
@@ -510,7 +434,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
510
434
|
}
|
|
511
435
|
}
|
|
512
436
|
async function toggleSystem2FA() {
|
|
513
|
-
const url = user2FaActive ? '/api/users/disable-2fa' : '/api/users/enable-2fa';
|
|
437
|
+
const url = user2FaActive ? '/api/bank/users/disable-2fa' : '/api/bank/users/enable-2fa';
|
|
514
438
|
try {
|
|
515
439
|
const res = await fetch(url, { method: 'POST' });
|
|
516
440
|
const data = await res.json();
|
|
@@ -547,7 +471,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
547
471
|
const deleteAccountStatus = await Swal.fire({title: 'Удаление щёта', text: 'Вы действительно хотите удалить щёт?', icon: 'warning', iconColor:"orange", showCancelButton: true, confirmButtonColor: '#d63030', cancelButtonColor: '#46d630', confirmButtonText: 'Да, удалить', cancelButtonText: 'Отмена'}).then((result) => {return result;});
|
|
548
472
|
if (!deleteAccountStatus.isConfirmed) return;
|
|
549
473
|
try {
|
|
550
|
-
const response = await fetch(`/api/accounts/${accountId}`, {
|
|
474
|
+
const response = await fetch(`/api/bank/accounts/${accountId}`, {
|
|
551
475
|
method: 'DELETE'
|
|
552
476
|
});
|
|
553
477
|
if (!response.ok) {
|
|
@@ -583,7 +507,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
583
507
|
}
|
|
584
508
|
async function loadTransactionLogs() {
|
|
585
509
|
try {
|
|
586
|
-
const response = await fetch('/api/accounts/my-logs');
|
|
510
|
+
const response = await fetch('/api/bank/accounts/my-logs');
|
|
587
511
|
if (!response.ok) return;
|
|
588
512
|
const result = await response.json();
|
|
589
513
|
const tbody = document.querySelector('#table-logs tbody');
|
|
@@ -658,7 +582,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
658
582
|
}
|
|
659
583
|
|
|
660
584
|
// 3. Отправляем fetch-запрос на бэкенд-роут игрового банка
|
|
661
|
-
const response = await fetch('/api/
|
|
585
|
+
const response = await fetch('/api/bank/accounts/credit', {
|
|
662
586
|
method: 'POST',
|
|
663
587
|
headers: {
|
|
664
588
|
'Content-Type': 'application/json'
|
|
@@ -683,7 +607,7 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
|
|
|
683
607
|
if (result.success) {
|
|
684
608
|
Swal.fire('Успех!', result.message || 'Кредит успешно оформлен', 'success').then(() => {
|
|
685
609
|
// Перенаправляем пользователя на страницу счетов, чтобы увидеть обновленный баланс
|
|
686
|
-
location.href = '/accounts';
|
|
610
|
+
location.href = '/bank/accounts.html';
|
|
687
611
|
});
|
|
688
612
|
} else {
|
|
689
613
|
Swal.fire('Ошибка оформления', result.error || 'Не удалось выдать кредит', 'error');
|
package/public/login.html
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
<div id="login-error" class="error"></div>
|
|
36
36
|
<button class="btn" onclick="submitLogin()">Войти в кабинет</button>
|
|
37
|
-
<p style="text-align: center; font-size: 14px; margin-top: 15px;"><a href="/register.html">Создать аккаунт</a></p>
|
|
37
|
+
<p style="text-align: center; font-size: 14px; margin-top: 15px;"><a href="/bank/register.html">Создать аккаунт</a></p>
|
|
38
38
|
</div>
|
|
39
39
|
|
|
40
40
|
<script>
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
errBlock.style.display = 'none';
|
|
47
47
|
|
|
48
48
|
try {
|
|
49
|
-
const response = await fetch('/api/users/login', {
|
|
49
|
+
const response = await fetch('/api/bank/users/login', {
|
|
50
50
|
method: 'POST',
|
|
51
51
|
headers: {'Content-Type': 'application/json'},
|
|
52
52
|
body: JSON.stringify({ name, password: pass, totpCode: totp || null })
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
const result = await response.json();
|
|
55
55
|
|
|
56
56
|
if (response.ok && result.status === true) {
|
|
57
|
-
window.location.href = 'general.html';
|
|
57
|
+
window.location.href = '/bank/general.html';
|
|
58
58
|
} else if (result.require2FA) {
|
|
59
59
|
document.getElementById('totp-block').style.display = 'block';
|
|
60
60
|
errBlock.innerText = result.message;
|
package/public/profile.html
CHANGED
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<title>City-Bank | Профиль</title>
|
|
6
|
-
<link rel="stylesheet" href="/css/style.css">
|
|
6
|
+
<link rel="stylesheet" href="/api/bank/css/style.css">
|
|
7
7
|
<link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div class="main-container">
|
|
11
11
|
<div class="sidebar">
|
|
12
12
|
<div style="text-align: center; margin-bottom: 15px;">
|
|
13
|
-
<img id="user-avatar" src="/uploads/avatars/default.png" style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid #1abc9c;">
|
|
13
|
+
<img id="user-avatar" src="/api/bank/uploads/avatars/default.png" style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid #1abc9c;">
|
|
14
14
|
</div>
|
|
15
15
|
<h2 id="user-display">Загрузка...</h2>
|
|
16
16
|
<p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
|
|
17
17
|
<hr style="border-color: #34495e;">
|
|
18
|
-
<a href="/general.html" class="nav-item"><button class="menu-btn" id="general">Главная</button></a>
|
|
19
|
-
<a href="/accounts.html" class="nav-item"><button class="menu-btn" id="acccount">Мои Счета</button></a>
|
|
20
|
-
<a href="/transfer.html" class="nav-item"><button class="menu-btn" id="transfer">Перевод средств</button></a>
|
|
21
|
-
<a href="/history.html" class="nav-item"><button class="menu-btn" id="history">История транзакций</button></a>
|
|
22
|
-
<a href="/credit.html" class="nav-item"><button class="menu-btn" id="credit">Оформить Кредит</button></a>
|
|
18
|
+
<a href="/bank/general.html" class="nav-item"><button class="menu-btn" id="general">Главная</button></a>
|
|
19
|
+
<a href="/bank/accounts.html" class="nav-item"><button class="menu-btn" id="acccount">Мои Счета</button></a>
|
|
20
|
+
<a href="/bank/transfer.html" class="nav-item"><button class="menu-btn" id="transfer">Перевод средств</button></a>
|
|
21
|
+
<a href="/bank/history.html" class="nav-item"><button class="menu-btn" id="history">История транзакций</button></a>
|
|
22
|
+
<a href="/bank/credit.html" class="nav-item"><button class="menu-btn" id="credit">Оформить Кредит</button></a>
|
|
23
23
|
<a class="nav-item"><button class="menu-btn active" id="profile">Управление профилем</button></a>
|
|
24
|
-
<button class="menu-btn" onclick="location.href='/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
|
|
24
|
+
<button class="menu-btn" onclick="location.href='/bank/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
|
|
25
25
|
<br><br>
|
|
26
26
|
<button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
|
|
27
27
|
</div>
|
|
@@ -73,9 +73,9 @@
|
|
|
73
73
|
</div>
|
|
74
74
|
</div>
|
|
75
75
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
|
|
76
|
-
<script src="/js/sweetalert2.js"></script>
|
|
76
|
+
<script src="/api/bank/js/sweetalert2.js"></script>
|
|
77
77
|
<script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
|
|
78
78
|
<script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
|
|
79
|
-
<script src="/js/js.js"></script>
|
|
79
|
+
<script src="/api/bank/js/js.js"></script>
|
|
80
80
|
</body>
|
|
81
81
|
</html>
|
package/public/register.html
CHANGED
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
try {
|
|
242
|
-
const response = await fetch(`/api/users/check-nik?name=${encodeURIComponent(nikInput)}`);
|
|
242
|
+
const response = await fetch(`/api/bank/users/check-nik?name=${encodeURIComponent(nikInput)}`);
|
|
243
243
|
const result = await response.json();
|
|
244
244
|
|
|
245
245
|
if (result.status === true && result.statusCode === 1) {
|
|
@@ -267,7 +267,7 @@
|
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
try {
|
|
270
|
-
const response = await fetch(`/api/users/check-gmail?gmail=${encodeURIComponent(gmailInput)}`);
|
|
270
|
+
const response = await fetch(`/api/bank/users/check-gmail?gmail=${encodeURIComponent(gmailInput)}`);
|
|
271
271
|
const result = await response.json();
|
|
272
272
|
|
|
273
273
|
if (result.status === true && result.statusCode === 1) {
|
|
@@ -317,7 +317,7 @@
|
|
|
317
317
|
nextBtn.innerText = "Проверить токен 2FA";
|
|
318
318
|
|
|
319
319
|
try {
|
|
320
|
-
const response = await fetch('/api/users/generate-temporary-2fa', {
|
|
320
|
+
const response = await fetch('/api/bank/users/generate-temporary-2fa', {
|
|
321
321
|
method: 'POST',
|
|
322
322
|
headers: {'Content-Type': 'application/json'},
|
|
323
323
|
body: JSON.stringify({ name: registrationPayload.name || document.getElementById('reg-nik').value.trim() })
|
|
@@ -376,7 +376,7 @@
|
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
try {
|
|
379
|
-
const response = await fetch('/api/users/verify-temporary-2fa', {
|
|
379
|
+
const response = await fetch('/api/bank/users/verify-temporary-2fa', {
|
|
380
380
|
method: 'POST',
|
|
381
381
|
headers: {'Content-Type': 'application/json'},
|
|
382
382
|
body: JSON.stringify({
|
|
@@ -418,7 +418,7 @@
|
|
|
418
418
|
registrationPayload.userSurname = surname;
|
|
419
419
|
|
|
420
420
|
try {
|
|
421
|
-
const response = await fetch('/api/users/register', {
|
|
421
|
+
const response = await fetch('/api/bank/users/register', {
|
|
422
422
|
method: 'POST',
|
|
423
423
|
headers: {'Content-Type': 'application/json'},
|
|
424
424
|
body: JSON.stringify(registrationPayload)
|
|
@@ -426,8 +426,8 @@
|
|
|
426
426
|
const result = await response.json();
|
|
427
427
|
|
|
428
428
|
if (result.status === true && result.statusCode === 1) {
|
|
429
|
-
alert("
|
|
430
|
-
window.location.href = '/login.html';
|
|
429
|
+
alert("Регистрация успешно завершена! Проверьте вашу почту для получения паролей и токенов.");
|
|
430
|
+
window.location.href = '/bank/login.html';
|
|
431
431
|
} else {
|
|
432
432
|
errBlock.innerText = result.message || "Внутренняя ошибка сервера";
|
|
433
433
|
errBlock.style.display = 'block';
|
package/public/transfer.html
CHANGED
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<title>City-Bank | Переводы</title>
|
|
6
|
-
<link rel="stylesheet" href="/css/style.css">
|
|
6
|
+
<link rel="stylesheet" href="/api/bank/css/style.css">
|
|
7
7
|
<link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div class="main-container">
|
|
11
11
|
<div class="sidebar">
|
|
12
12
|
<div style="text-align: center; margin-bottom: 15px;">
|
|
13
|
-
<img id="user-avatar" src="/uploads/avatars/default.png" style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid #1abc9c;">
|
|
13
|
+
<img id="user-avatar" src="/api/bank/uploads/avatars/default.png" style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid #1abc9c;">
|
|
14
14
|
</div>
|
|
15
15
|
<h2 id="user-display">Загрузка...</h2>
|
|
16
16
|
<p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
|
|
17
17
|
<hr style="border-color: #34495e;">
|
|
18
|
-
<a href="/general.html" class="nav-item"><button class="menu-btn" id="general">Главная</button></a>
|
|
19
|
-
<a href="/accounts.html" class="nav-item"><button class="menu-btn" id="acccount">Мои Счета</button></a>
|
|
18
|
+
<a href="/bank/general.html" class="nav-item"><button class="menu-btn" id="general">Главная</button></a>
|
|
19
|
+
<a href="/bank/accounts.html" class="nav-item"><button class="menu-btn" id="acccount">Мои Счета</button></a>
|
|
20
20
|
<a class="nav-item"><button class="menu-btn active" id="transfer">Перевод средств</button></a>
|
|
21
|
-
<a href="/history.html" class="nav-item"><button class="menu-btn" id="history">История транзакций</button></a>
|
|
22
|
-
<a href="/credit.html" class="nav-item"><button class="menu-btn" id="credit">Оформить Кредит</button></a>
|
|
23
|
-
<a href="/profile.html" class="nav-item"><button class="menu-btn" id="profile">Управление профилем</button></a>
|
|
24
|
-
<button class="menu-btn" onclick="location.href='/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
|
|
21
|
+
<a href="/bank/history.html" class="nav-item"><button class="menu-btn" id="history">История транзакций</button></a>
|
|
22
|
+
<a href="/bank/credit.html" class="nav-item"><button class="menu-btn" id="credit">Оформить Кредит</button></a>
|
|
23
|
+
<a href="/bank/profile.html" class="nav-item"><button class="menu-btn" id="profile">Управление профилем</button></a>
|
|
24
|
+
<button class="menu-btn" onclick="location.href='/bank/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
|
|
25
25
|
<br><br>
|
|
26
26
|
<button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
|
|
27
27
|
</div>
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
|
-
<script src="/js/sweetalert2.js"></script>
|
|
57
|
+
<script src="/api/bank/js/sweetalert2.js"></script>
|
|
58
58
|
<script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
|
|
59
59
|
<script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
|
|
60
|
-
<script src="/js/js.js"></script>
|
|
60
|
+
<script src="/api/bank/js/js.js"></script>
|
|
61
61
|
</body>
|
|
62
62
|
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/server/server.js
CHANGED
|
@@ -5,6 +5,7 @@ const User = require(path.join(__dirname, '..', 'database', 'models', 'User.js')
|
|
|
5
5
|
const Account = require(path.join(__dirname, '..', 'database', 'models', 'Account.js'));
|
|
6
6
|
const multer = require('multer');
|
|
7
7
|
const fs = require('fs');
|
|
8
|
+
const express = require("express");
|
|
8
9
|
const logger = require("custom-color-logs").print;
|
|
9
10
|
const storage = multer.diskStorage({
|
|
10
11
|
destination: function (req, file, cb) {
|
|
@@ -43,8 +44,10 @@ function verifySession(req, res, next) {
|
|
|
43
44
|
return res.status(403).json({ status: false, statusCode: -2, message: 'Сессия устарела. Войдите снова.' });
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
|
-
module.exports = function registerRoutes(
|
|
47
|
-
|
|
47
|
+
module.exports = function registerRoutes() {
|
|
48
|
+
const get = express.Router();
|
|
49
|
+
const post = express.Router();
|
|
50
|
+
post.post('/users/generate-temporary-2fa', async (req, res) => {
|
|
48
51
|
try {
|
|
49
52
|
const otplib = require('otplib');
|
|
50
53
|
const { name } = req.body;
|
|
@@ -55,7 +58,7 @@ module.exports = function registerRoutes(app) {
|
|
|
55
58
|
return res.status(500).json({ status: false, message: err.message });
|
|
56
59
|
}
|
|
57
60
|
})
|
|
58
|
-
|
|
61
|
+
post.post('/users/verify-temporary-2fa', async (req, res) => {
|
|
59
62
|
try {
|
|
60
63
|
const otplib = require('otplib');
|
|
61
64
|
const { secret, code } = req.body;
|
|
@@ -72,39 +75,39 @@ module.exports = function registerRoutes(app) {
|
|
|
72
75
|
return res.status(500).json({ status: false, message: err.message });
|
|
73
76
|
}
|
|
74
77
|
});
|
|
75
|
-
|
|
78
|
+
post.post('/users/avatar', verifySession, upload.single('avatar'), async (req, res) => {
|
|
76
79
|
if (!req.file) {
|
|
77
80
|
return res.status(400).json({ status: false, statusCode: -2, message: 'Файл не загружен' });
|
|
78
81
|
}
|
|
79
|
-
const avatarUrl = `/uploads/avatars/${req.file.filename}`;
|
|
82
|
+
const avatarUrl = `/api/bank/uploads/avatars/${req.file.filename}`;
|
|
80
83
|
const result = await usersHub.changeAvatar(req.user.name, avatarUrl);
|
|
81
84
|
return res.json(result);
|
|
82
85
|
});
|
|
83
|
-
|
|
86
|
+
post.get('/users/profile', verifySession, async (req, res) => {
|
|
84
87
|
const user = await User.findByPk(req.user.name, { attributes: ['name', 'user_gmail', 'avatar'] });
|
|
85
88
|
if (!user) return res.status(404).json({ status: false });
|
|
86
89
|
return res.json({ status: true, user });
|
|
87
90
|
});
|
|
88
|
-
|
|
91
|
+
post.get('/users/check-nik', async (req, res) => {
|
|
89
92
|
const user = await User.findByPk(req.query.name);
|
|
90
93
|
if (user) {
|
|
91
94
|
return res.json({ status: false, statusCode: -20, message: 'Никнейм уже занят!' });
|
|
92
95
|
}
|
|
93
96
|
return res.json({ status: true, statusCode: 1 });
|
|
94
97
|
});
|
|
95
|
-
|
|
98
|
+
post.get('/users/check-gmail', async (req, res) => {
|
|
96
99
|
const user = await User.findOne({ where: { user_gmail: req.query.gmail } });
|
|
97
100
|
if (user) {
|
|
98
101
|
return res.json({ status: false, statusCode: -21, message: 'Данный email уже используется!' });
|
|
99
102
|
}
|
|
100
103
|
return res.json({ status: true, statusCode: 1 });
|
|
101
104
|
});
|
|
102
|
-
|
|
105
|
+
post.post('/users/register', async (req, res) => {
|
|
103
106
|
const result = await usersHub.registerUser(req.body);
|
|
104
107
|
if (!result.status) return res.status(400).json(result);
|
|
105
108
|
return res.status(201).json(result);
|
|
106
109
|
});
|
|
107
|
-
|
|
110
|
+
post.post('/users/login', async (req, res) => {
|
|
108
111
|
const { name, password, totpCode } = req.body;
|
|
109
112
|
const result = await usersHub.login(name, password, totpCode);
|
|
110
113
|
if (!result.status) {
|
|
@@ -117,20 +120,20 @@ module.exports = function registerRoutes(app) {
|
|
|
117
120
|
res.cookie('token', sessionToken, { httpOnly: true, maxAge: 2 * 60 * 60 * 1000 });
|
|
118
121
|
return res.json(result);
|
|
119
122
|
});
|
|
120
|
-
|
|
123
|
+
post.post('/users/logout', (req, res) => {
|
|
121
124
|
res.clearCookie('token');
|
|
122
125
|
return res.json({ status: true, statusCode: 1 });
|
|
123
126
|
});
|
|
124
|
-
|
|
127
|
+
post.get('/users/my-total-manny', verifySession, async (req, res) => {
|
|
125
128
|
const result = await usersHub.mathManny(req.user.name);
|
|
126
129
|
return res.json({ status: result.status, statusCode: result.statusCode, totalManny: result.totalManny, username: req.user.name });
|
|
127
130
|
});
|
|
128
|
-
|
|
131
|
+
post.post('/accounts', verifySession, async (req, res) => {
|
|
129
132
|
const { pinCode, enableAccount2FA } = req.body;
|
|
130
133
|
const result = await accountsHub.create(req.user.name, pinCode, enableAccount2FA);
|
|
131
134
|
return res.json(result);
|
|
132
135
|
});
|
|
133
|
-
|
|
136
|
+
post.get('/accounts/my', verifySession, async (req, res) => {
|
|
134
137
|
try {
|
|
135
138
|
const myAccounts = await Account.findAll({ where: { user: req.user.name } });
|
|
136
139
|
return res.json({ status: true, statusCode: 1, accounts: myAccounts });
|
|
@@ -138,7 +141,7 @@ module.exports = function registerRoutes(app) {
|
|
|
138
141
|
return res.status(500).json({ status: false, statusCode: -10 });
|
|
139
142
|
}
|
|
140
143
|
});
|
|
141
|
-
|
|
144
|
+
post.delete('/accounts/:id', verifySession, async (req, res) => {
|
|
142
145
|
try {
|
|
143
146
|
const result = await accountsHub.delete(req.params.id, req.user.name);
|
|
144
147
|
if (!result.status) {
|
|
@@ -154,22 +157,22 @@ module.exports = function registerRoutes(app) {
|
|
|
154
157
|
return res.status(500).json({ status: false, statusCode: -10, message: "Внутренняя ошибка сервера" });
|
|
155
158
|
}
|
|
156
159
|
});
|
|
157
|
-
|
|
160
|
+
post.post('/accounts/transfer', verifySession, async (req, res) => {
|
|
158
161
|
const { fromId, toId, amount, pinCode, totpCode } = req.body;
|
|
159
162
|
const result = await accountsHub.transfer(fromId, toId, amount, pinCode, totpCode);
|
|
160
163
|
return res.json(result);
|
|
161
164
|
});
|
|
162
|
-
|
|
165
|
+
post.post('/accounts/credit', verifySession, async (req, res) => {
|
|
163
166
|
const { targetAccountId, amount, paymentsCount, autoWithdrawal, pinCode } = req.body;
|
|
164
167
|
const result = await accountsHub.creatCredit(req.user.name, targetAccountId, amount, pinCode, paymentsCount, autoWithdrawal);
|
|
165
168
|
return res.json(result);
|
|
166
169
|
});
|
|
167
|
-
|
|
170
|
+
post.post('/admin/accounts/:id/status', verifySession, async (req, res) => {
|
|
168
171
|
if (req.user.name !== 'root') return res.status(403).json({ status: false, statusCode: -2, message: 'Отказано в доступе' });
|
|
169
172
|
const result = await accountsHub.changeAccountStatus(req.params.id, req.body.active);
|
|
170
173
|
return res.json(result);
|
|
171
174
|
});
|
|
172
|
-
|
|
175
|
+
post.post('/admin/accounts/:id/modify', verifySession, async (req, res) => {
|
|
173
176
|
if (req.user.name !== 'root') return res.status(403).json({ status: false, statusCode: -2, message: 'Отказано в доступе' });
|
|
174
177
|
const { amount, type } = req.body;
|
|
175
178
|
let result;
|
|
@@ -180,7 +183,7 @@ module.exports = function registerRoutes(app) {
|
|
|
180
183
|
}
|
|
181
184
|
return res.json(result);
|
|
182
185
|
});
|
|
183
|
-
|
|
186
|
+
post.get('/admin/accounts/all', verifySession, async (req, res) => {
|
|
184
187
|
if (req.user.name !== 'root') return res.status(403).json({ status: false, statusCode: -2, message: 'Отказано в доступе' });
|
|
185
188
|
try {
|
|
186
189
|
const allAccounts = await Account.findAll({ order: [['id', 'ASC']] });
|
|
@@ -189,7 +192,7 @@ module.exports = function registerRoutes(app) {
|
|
|
189
192
|
return res.status(500).json({ status: false, statusCode: -10 });
|
|
190
193
|
}
|
|
191
194
|
});
|
|
192
|
-
|
|
195
|
+
post.get('/users/profile/settings', verifySession, async (req, res) => {
|
|
193
196
|
try {
|
|
194
197
|
const user = await User.findByPk(req.user.name, { attributes: ['name', 'user_gmail', 'two_fa_status', 'avatar'] });
|
|
195
198
|
if (!user) return res.status(404).json({ status: false, message: 'Юзер не найден' });
|
|
@@ -198,19 +201,19 @@ module.exports = function registerRoutes(app) {
|
|
|
198
201
|
return res.status(500).json({ status: false, message: 'Внутренняя ошибка бэка' });
|
|
199
202
|
}
|
|
200
203
|
});
|
|
201
|
-
|
|
204
|
+
post.post('/users/enable-2fa', verifySession, async (req, res) => {
|
|
202
205
|
const result = await usersHub.enable2FA(req.user.name);
|
|
203
206
|
return res.json(result);
|
|
204
207
|
});
|
|
205
|
-
|
|
208
|
+
post.post('/users/disable-2fa', verifySession, async (req, res) => {
|
|
206
209
|
const result = await usersHub.disable2FA(req.user.name);
|
|
207
210
|
return res.json(result);
|
|
208
211
|
});
|
|
209
|
-
|
|
212
|
+
post.get('/accounts/my-logs', verifySession, async (req, res) => {
|
|
210
213
|
const result = await accountsHub.getLogs(req.user.name);
|
|
211
214
|
return res.json(result);
|
|
212
215
|
});
|
|
213
|
-
|
|
216
|
+
post.post('/terminal/register', async(req, res)=>{
|
|
214
217
|
if(!req.body) return res.sendStatus(400)
|
|
215
218
|
const id = req.body.id;
|
|
216
219
|
const pincode = req.body.pincode;
|
|
@@ -219,13 +222,13 @@ module.exports = function registerRoutes(app) {
|
|
|
219
222
|
if(!result.status) return res.sendStatus(422)
|
|
220
223
|
return res.sendStatus(200);
|
|
221
224
|
});
|
|
222
|
-
|
|
225
|
+
post.post('/terminal/transfer', async(req, res)=>{
|
|
223
226
|
const card = req.body.card;
|
|
224
227
|
const to = req.body.to;
|
|
225
228
|
const pincode = req.body.pincode;
|
|
226
|
-
const manny = req.body.
|
|
229
|
+
const manny = req.body.manny;
|
|
227
230
|
const result = await accountsHub.cardTransfer(card, to, manny, pincode)
|
|
228
231
|
});
|
|
229
|
-
return
|
|
232
|
+
return {GET:get, POST:post};
|
|
230
233
|
};
|
|
231
234
|
module.exports.verifySession = verifySession;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<h3 style='color:red;'>🚫 Заморозка счета</h3><p>Ваш банковский счет #{accountId} заблокирован администрацией.</p>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
🚫 Счет #{accountId} ЗАБЛОКИРОВАН администратором.
|