sequelize-game-bank 1.0.3 → 1.2.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.
@@ -35,6 +35,11 @@ const Account = sequelize.define('account', {
35
35
  allowNull: false,
36
36
  defaultValue: false,
37
37
  field: '2FA-status'
38
+ },
39
+ cardNumber:{
40
+ type:DataTypes.STRING,
41
+ allowNull:true,
42
+ unique:true
38
43
  }
39
44
  });
40
45
  User.hasMany(Account, { foreignKey: 'user', sourceKey: 'name' });
@@ -0,0 +1,91 @@
1
+ const path = require("path");
2
+ const bcrypt = require('bcrypt');
3
+ const Account = require(path.join(__dirname, '..', '..', 'models', 'Account'));
4
+ const User = require(path.join(__dirname, '..', '..', 'models', 'User'));
5
+ const Transaction = require(path.join(__dirname, '..', '..', 'models', 'Transaction'));
6
+ const sequelize = require(path.join(__dirname, '..', '..', 'config', 'init-db'));
7
+ const { sendBotNotification } = require(path.join(__dirname, '..', 'bot', 'bot'));
8
+ const logger = require("custom-color-logs").print;
9
+ async function getIdByCard(card) {
10
+ const result = await Account.findOne({
11
+ where:{cardNumber:card.toString()},
12
+ attributes: ['id']
13
+ });
14
+ if (!result) return false
15
+ return result
16
+ }
17
+ module.exports = async function cardTransfer(card, toId, amount, pinCode) {
18
+ const t = await sequelize.transaction();
19
+ try {
20
+ const fromId = await getIdByCard(card);
21
+ const numericAmount = parseFloat(amount);
22
+ if (isNaN(numericAmount) || numericAmount <= 0) {
23
+ await t.rollback();
24
+ return { status: false, statusCode: -2, message: 'Некорректная сумма перевода' };
25
+ }
26
+ const fromAcc = await Account.findByPk(fromId, {
27
+ transaction: t,
28
+ lock: t.LOCK.UPDATE
29
+ });
30
+ const toAcc = await Account.findByPk(toId, {
31
+ transaction: t,
32
+ lock: t.LOCK.UPDATE
33
+ });
34
+ if (!fromAcc || !toAcc) {
35
+ await t.rollback();
36
+ return { status: false, statusCode: -2, message: 'Один из счетов не найден' };
37
+ }
38
+ if (!fromAcc.active || !toAcc.active) {
39
+ await t.rollback();
40
+ return { status: false, statusCode: -11, message: 'Один из счетов заблокирован' };
41
+ }
42
+ const isPinValid = await bcrypt.compare(pinCode, fromAcc.pin_code);
43
+ if (!isPinValid) {
44
+ await t.rollback();
45
+ return { status: false, statusCode: -23, message: 'Неверный пароль счета отправителя' };
46
+ }
47
+ if (fromAcc.user !== 'root' && parseFloat(fromAcc.manny) < numericAmount) {
48
+ await t.rollback();
49
+ return { status: false, statusCode: -11, message: 'Недостаточно средств на счете' };
50
+ }
51
+ if (fromAcc.two_fa_status) {
52
+ const owner = await User.findByPk(fromAcc.user, { transaction: t });
53
+ if (owner && owner.two_fa_status) {
54
+ const isTotpValid = await bcrypt.compare(totpCode, owner.two_fa_token);
55
+ if (!isTotpValid) {
56
+ await t.rollback();
57
+ return { status: false, statusCode: -2, message: 'Неверный токен подтверждения 2FA' };
58
+ }
59
+ }
60
+ }
61
+ await fromAcc.decrement('manny', { by: numericAmount, transaction: t });
62
+ await toAcc.increment('manny', { by: numericAmount, transaction: t });
63
+ await Transaction.create({
64
+ account_id: fromId,
65
+ type: 'TRANSFER_OUT',
66
+ sender_or_receiver: `На счет #${toId} (${toAcc.user})`,
67
+ amount: numericAmount
68
+ }, { transaction: t });
69
+ await Transaction.create({
70
+ account_id: toId,
71
+ type: 'TRANSFER_IN',
72
+ sender_or_receiver: `Со счета #${fromId} (${fromAcc.user})`,
73
+ amount: numericAmount
74
+ }, { transaction: t });
75
+ await t.commit();
76
+ await fromAcc.reload();
77
+ await toAcc.reload();
78
+ try {
79
+ await sendBotNotification('transfer-from-bot', { fromId, toId, amount: numericAmount, balance: fromAcc.manny });
80
+ await sendBotNotification('transfer-to-bot', { toId, fromId, amount: numericAmount, balance: toAcc.manny });
81
+ } catch (botErr) {
82
+ console.log(logger.DatabaseError('Ошибка отправки уведомления боту:', botErr.message))
83
+ }
84
+ return { status: true, statusCode: 1 };
85
+ } catch (err) {
86
+ if (!t.finished) {
87
+ await t.rollback();
88
+ }
89
+ return { status: false, statusCode: -10, message: err.message };
90
+ }
91
+ };
@@ -12,10 +12,19 @@ module.exports = async function createAccount(username, pinCode, enable2FA) {
12
12
  pin_code: hashedPin,
13
13
  manny: 0.00,
14
14
  active: true,
15
- two_fa_status: enable2FA
15
+ two_fa_status: enable2FA,
16
+ cardNumber:null
16
17
  });
17
18
  return { status: true, statusCode: 1, accountId: newAccount.id };
18
19
  } catch (err) {
20
+ console.log(err)
21
+
22
+
23
+
24
+
25
+
26
+
27
+
19
28
  return { status: false, statusCode: -10, message: err.message };
20
29
  }
21
30
  };
@@ -0,0 +1,18 @@
1
+ const path = require("path");
2
+ const Account = require(path.join(__dirname, '..', '..', 'models', 'Account'));
3
+ const logger = require("custom-color-logs").print;
4
+ module.exports = async function linkACard(card, id, pin_code) {
5
+ try {
6
+ const account = await Account.findByPk(id);
7
+ if (!account) return { status: false, statusCode: -2, message: "?¿?" };
8
+ if(!account.active) return { status: false, statusCode: -11, message: 'Один из счетов заблокирован' };
9
+ if (account.pin_code !== pin_code) return { status: false, statusCode: -23, message: "Неправильны пароль!" };
10
+ if (account.cardNumber !== null) return { status: false, statusCode: -19, message: "Карты уже привязана" };
11
+ account.cardNumber = card;
12
+ await account.save();
13
+ return {status: true, statusCode: 1, message: 'Привязка карты удалась'};
14
+ } catch (err) {
15
+ console.log(logger.BankError(err));
16
+ return { status: false, statusCode: -10, message: err.message };
17
+ }
18
+ }
@@ -9,5 +9,7 @@ module.exports = {
9
9
  findManny: require(path.join(__dirname, 'account', 'find-manny')),
10
10
  creatCredit: require(path.join(__dirname, 'account', 'create-credit')),
11
11
  getLogs: require(path.join(__dirname, 'account', 'logs')),
12
- changeAccountStatus: require(path.join(__dirname, 'account', 'change-status'))
12
+ changeAccountStatus: require(path.join(__dirname, 'account', 'change-status')),
13
+ linkACard: require(path.join(__dirname, 'account', 'linkACard')),
14
+ cardTransfer: require(path.join(__dirname, 'account', 'cardTransfer'))
13
15
  };
package/index.js CHANGED
@@ -11,11 +11,9 @@ const { writeTemplatesIfNotExist } = require(path.join(__dirname, 'database', 's
11
11
  const registerRoutes = require(path.join(__dirname, 'server', 'server'));
12
12
  const Transaction = require(path.join(__dirname, 'database', 'models', 'Transaction'));
13
13
  const app = express();
14
-
15
14
  const { verifySession } = require(path.join(__dirname, 'server', 'server'));
16
15
  app.use(express.json());
17
16
  app.use(cookieParser());
18
- require(path.join(__dirname, 'database', 'services', 'bot', 'cron-schedule'));
19
17
  async function Bank() {
20
18
  try {
21
19
  await sequelize.sync();
@@ -53,6 +51,8 @@ async function Bank() {
53
51
  app.get('/home.html', (req, res) => res.sendFile(path.join(__dirname, 'public', 'home.html')));
54
52
  app.get('/favicon.ico', (req, res) => res.sendFile(path.join(__dirname, 'public', 'icon', 'icon.png')));
55
53
  app.get('/', (req, res) => res.redirect('/home.html'));
54
+
55
+ require(path.join(__dirname, 'database', 'services', 'bot', 'cron-schedule'));
56
56
  return configuredApp;
57
57
  } catch (err) {
58
58
  console.log(logger.ServerBankError("Критическая ошибка инициализации модулей", err));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sequelize-game-bank",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "description": "A Sequelize-based gaming economy and banking system featuring user profiles, credits, admin management, and detailed transaction history.",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
@@ -4,6 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <title>City-Bank | Мои Счета</title>
6
6
  <link rel="stylesheet" href="/css/style.css">
7
+ <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
7
8
  </head>
8
9
  <body>
9
10
  <div class="main-container">
@@ -14,12 +15,12 @@
14
15
  <h2 id="user-display">Загрузка...</h2>
15
16
  <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
16
17
  <hr style="border-color: #34495e;">
17
- <a href="/general.html" class="nav-item"><button class="menu-btn">Главная</button></a>
18
- <a href="/accounts.html" class="nav-item"><button class="menu-btn active">Мои Счета</button></a>
19
- <a href="/transfer.html" class="nav-item"><button class="menu-btn">Перевод средств</button></a>
20
- <a href="/history.html" class="nav-item"><button class="menu-btn">История транзакций</button></a>
21
- <a href="/credit.html" class="nav-item"><button class="menu-btn">Оформить Кредит</button></a>
22
- <a href="/profile.html" class="nav-item"><button class="menu-btn">Управление профилем</button></a>
18
+ <a href="/general.html" class="nav-item"><button class="menu-btn" id="general">Главная</button></a>
19
+ <a class="nav-item"><button class="menu-btn active" 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>
23
+ <a href="/profile.html" class="nav-item"><button class="menu-btn" id="profile">Управление профилем</button></a>
23
24
  <button class="menu-btn" onclick="location.href='/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
24
25
  <br><br>
25
26
  <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
@@ -39,6 +40,8 @@
39
40
  </div>
40
41
  <script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
41
42
  <script src="/js/sweetalert2.js"></script>
43
+ <script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
44
+ <script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
42
45
  <script src="/js/js.js"></script>
43
46
  </body>
44
47
  </html>
@@ -4,26 +4,27 @@
4
4
  <meta charset="UTF-8">
5
5
  <title>City-Bank | Кредитование</title>
6
6
  <link rel="stylesheet" href="/css/style.css">
7
+ <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
7
8
  </head>
8
9
  <body>
9
10
  <div class="main-container">
10
11
  <div class="sidebar">
11
- <div style="text-align: center; margin-bottom: 15px;">
12
- <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
- </div>
14
- <h2 id="user-display">Загрузка...</h2>
15
- <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
16
- <hr style="border-color: #34495e;">
17
- <a href="/general.html" class="nav-item"><button class="menu-btn active">Главная</button></a>
18
- <a href="/accounts.html" class="nav-item"><button class="menu-btn">Мои Счета</button></a>
19
- <a href="/transfer.html" class="nav-item"><button class="menu-btn">Перевод средств</button></a>
20
- <a href="/history.html" class="nav-item"><button class="menu-btn">История транзакций</button></a>
21
- <a href="/credit.html" class="nav-item"><button class="menu-btn">Оформить Кредит</button></a>
22
- <a href="/profile.html" class="nav-item"><button class="menu-btn">Управление профилем</button></a>
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;">
14
+ </div>
15
+ <h2 id="user-display">Загрузка...</h2>
16
+ <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
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 class="nav-item"><button class="menu-btn active" id="credit">Оформить Кредит</button></a>
23
+ <a href="/profile.html" class="nav-item"><button class="menu-btn" id="profile">Управление профилем</button></a>
23
24
  <button class="menu-btn" onclick="location.href='/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
24
- <br><br>
25
- <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
26
- </div>
25
+ <br><br>
26
+ <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
27
+ </div>
27
28
 
28
29
  <div class="container">
29
30
  <div class="container-center">
@@ -82,6 +83,8 @@
82
83
  </div>
83
84
  <script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
84
85
  <script src="/js/sweetalert2.js"></script>
86
+ <script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
87
+ <script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
85
88
  <script src="/js/js.js"></script>
86
89
  </body>
87
90
  </html>
@@ -55,4 +55,7 @@
55
55
  border: 1px solid green;
56
56
  border-radius: 10px;
57
57
  }
58
-
58
+ .tippy-box[data-theme~='user-info']{
59
+ background-color: rgba(240, 248, 255, 0.747);
60
+ border: 1px solid rgb(0, 0, 255);
61
+ }
@@ -5,28 +5,29 @@
5
5
  <title>City-Bank | Главная</title>
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1">
7
7
  <link rel="stylesheet" href="/css/style.css">
8
+ <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
8
9
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">
9
10
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
10
11
  </head>
11
12
  <body>
12
13
  <div class="main-container">
13
14
  <div class="sidebar">
14
- <div style="text-align: center; margin-bottom: 15px;">
15
- <img id="user-avatar" src="/uploads/avatars/default.png" style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid #1abc9c;">
16
- </div>
17
- <h2 id="user-display">Загрузка...</h2>
18
- <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
19
- <hr style="border-color: #34495e;">
20
- <a href="/general.html" class="nav-item"><button class="menu-btn active">Главная</button></a>
21
- <a href="/accounts.html" class="nav-item"><button class="menu-btn">Мои Счета</button></a>
22
- <a href="/transfer.html" class="nav-item"><button class="menu-btn">Перевод средств</button></a>
23
- <a href="/history.html" class="nav-item"><button class="menu-btn">История транзакций</button></a>
24
- <a href="/credit.html" class="nav-item"><button class="menu-btn">Оформить Кредит</button></a>
25
- <a href="/profile.html" class="nav-item"><button class="menu-btn">Управление профилем</button></a>
15
+ <div style="text-align: center; margin-bottom: 15px;">
16
+ <img id="user-avatar" src="/uploads/avatars/default.png" style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid #1abc9c;">
17
+ </div>
18
+ <h2 id="user-display">Загрузка...</h2>
19
+ <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
20
+ <hr style="border-color: #34495e;">
21
+ <a class="nav-item"><button class="menu-btn active" id="general">Главная</button></a>
22
+ <a href="/accounts.html" class="nav-item"><button class="menu-btn" id="acccount">Мои Счета</button></a>
23
+ <a href="/transfer.html" class="nav-item"><button class="menu-btn" id="transfer">Перевод средств</button></a>
24
+ <a href="/history.html" class="nav-item"><button class="menu-btn" id="history">История транзакций</button></a>
25
+ <a href="/credit.html" class="nav-item"><button class="menu-btn" id="credit">Оформить Кредит</button></a>
26
+ <a href="/profile.html" class="nav-item"><button class="menu-btn" id="profile">Управление профилем</button></a>
26
27
  <button class="menu-btn" onclick="location.href='/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
27
- <br><br>
28
- <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
29
- </div>
28
+ <br><br>
29
+ <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
30
+ </div>
30
31
 
31
32
  <div class="container">
32
33
  <div class="container-center">
@@ -48,6 +49,8 @@
48
49
  </div>
49
50
  <script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
50
51
  <script src="/js/sweetalert2.js"></script>
52
+ <script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
53
+ <script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
51
54
  <script src="/js/js.js"></script>
52
55
  </body>
53
56
  </html>
@@ -4,6 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <title>City-Bank | История</title>
6
6
  <link rel="stylesheet" href="/css/style.css">
7
+ <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
7
8
  </head>
8
9
  <body>
9
10
  <div class="main-container">
@@ -14,12 +15,12 @@
14
15
  <h2 id="user-display">Загрузка...</h2>
15
16
  <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
16
17
  <hr style="border-color: #34495e;">
17
- <a href="/general.html" class="nav-item"><button class="menu-btn active">Главная</button></a>
18
- <a href="/accounts.html" class="nav-item"><button class="menu-btn">Мои Счета</button></a>
19
- <a href="/transfer.html" class="nav-item"><button class="menu-btn">Перевод средств</button></a>
20
- <a href="/history.html" class="nav-item"><button class="menu-btn">История транзакций</button></a>
21
- <a href="/credit.html" class="nav-item"><button class="menu-btn">Оформить Кредит</button></a>
22
- <a href="/profile.html" class="nav-item"><button class="menu-btn">Управление профилем</button></a>
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 class="nav-item"><button class="menu-btn active" 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>
23
24
  <button class="menu-btn" onclick="location.href='/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
24
25
  <br><br>
25
26
  <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
@@ -57,6 +58,8 @@
57
58
  </dialog>
58
59
  <script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
59
60
  <script src="/js/sweetalert2.js"></script>
61
+ <script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
62
+ <script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
60
63
  <script src="/js/js.js"></script>
61
64
  </body>
62
65
  </html>
package/public/js/js.js CHANGED
@@ -2,8 +2,6 @@
2
2
  const toastifyScript = document.createElement('script');
3
3
  toastifyScript.src = 'https://cdn.jsdelivr.net/npm/toastify-js';
4
4
  document.head.append(toastifyScript);
5
-
6
-
7
5
  let currentUsername = "";
8
6
 
9
7
  function showTab(tabId) {
@@ -12,6 +10,66 @@ let currentUsername = "";
12
10
  document.getElementById(tabId).classList.add('active');
13
11
  event.target.classList.add('active');
14
12
  }
13
+
14
+
15
+
16
+
17
+
18
+ window.tippy('#general', {
19
+ content: "Главная",
20
+ placement:'top-end',
21
+ arrow: false,
22
+ animation:'scale-extreme',
23
+ theme:"light"
24
+ });
25
+ window.tippy('#acccount', {
26
+ content: "Щета",
27
+ placement:'top-end',
28
+ arrow: false,
29
+ animation:'scale-extreme',
30
+ theme:"light"
31
+ });
32
+ window.tippy('#transfer', {
33
+ content: "Перевод",
34
+ placement:'top-end',
35
+ arrow: false,
36
+ animation:'scale-extreme',
37
+ theme:"light"
38
+ });
39
+ window.tippy('#history', {
40
+ content: "История",
41
+ placement:'top-end',
42
+ arrow: false,
43
+ animation:'scale-extreme',
44
+ theme:"light"
45
+ });
46
+ window.tippy('#credit', {
47
+ content: "Кредит",
48
+ placement:'top-end',
49
+ arrow: false,
50
+ animation:'scale-extreme',
51
+ theme:"light"
52
+ });
53
+ window.tippy('#profile', {
54
+ content: "Редактировать профиль",
55
+ placement:'top-end',
56
+ arrow: false,
57
+ animation:'scale-extreme',
58
+ theme:"light"
59
+ });
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
15
73
  async function loadData() {
16
74
  try {
17
75
  let response = await fetch('/api/accounts/my');
@@ -97,6 +155,13 @@ let currentUsername = "";
97
155
  let profileRes = await fetch('/api/users/profile');
98
156
  let profileData = await profileRes.json();
99
157
  const userAvatar = document.getElementById('user-avatar');
158
+ window.tippy("#user-avatar", {
159
+ content:`<span style='color:blue'>${currentUsername.toLocaleUpperCase()}</span> — <span style='color:lightgreen;'>${mannyData.totalManny.toFixed(2)}</span>`,
160
+ placement:"right",
161
+ allowHTML:true,
162
+ theme:'user-info',
163
+ arrow:false
164
+ })
100
165
  const userAvatar2 = document.getElementById('user-avatar2');
101
166
  if (profileData.status && profileData.user && profileData.user.avatar && userAvatar) {
102
167
  userAvatar.src = profileData.user.avatar;
@@ -120,6 +185,33 @@ let currentUsername = "";
120
185
  });
121
186
  }
122
187
  }
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
+
123
215
  async function openCreateAccountModal() {
124
216
  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'})
125
217
  if (!pin.value) return;
@@ -191,33 +283,25 @@ let currentUsername = "";
191
283
 
192
284
 
193
285
  async function applyForCredit() {
194
- // 1. Извлекаем значения из ваших оригинальных ID элементов HTML
195
286
  const targetAccountId = document.getElementById('credit-target').value;
196
287
  const amount = document.getElementById('credit-amount').value;
197
288
  const paymentsCount = document.getElementById('credit-payments').value;
198
289
  const autoWithdrawal = document.getElementById('credit-auto').checked;
199
290
  const pinCode = document.getElementById('credit-pin').value;
200
-
201
- // 2. Отправляем fetch-запрос на ваш бэкенд-роут
202
291
  const res = await fetch('/api/accounts/credit', {
203
292
  method: 'POST',
204
293
  headers: {'Content-Type': 'application/json'},
205
- // Маппим ваши оригинальные фронтенд-переменные в ключи, которые ожидает бэкенд-сервис
206
294
  body: JSON.stringify({
207
- accountId: targetAccountId, // targetAccountId конвертируется в accountId для бэкенда
208
- amount: parseFloat(amount), // явно приводим к числу
209
- termMonths: parseInt(paymentsCount, 10), // paymentsCount конвертируется в termMonths
210
- autoRepay: autoWithdrawal, // autoWithdrawal конвертируется в autoRepay
211
- pinCode: pinCode, // передаем пин-код для верификации, если он нужен в сервисе
212
- rate: 0.1 // дефолтная ставка (10%), если на фронтенде нет такого поля
295
+ accountId: targetAccountId,
296
+ amount: parseFloat(amount),
297
+ termMonths: parseInt(paymentsCount, 10),
298
+ autoRepay: autoWithdrawal,
299
+ pinCode: pinCode,
300
+ rate: 0.1
213
301
  })
214
302
  });
215
-
216
303
  const data = await res.json();
217
-
218
- // 3. Обработка ответа от сервера
219
- if(data.success || data.status) { // Проверяем оба флага для надежности
220
- // ИСПРАВЛЕНО: 'sucess' изменено на валидное 'success' (теперь окно сработает и не упадет в ошибку)
304
+ if(data.success || data.status) {
221
305
  await Swal.fire({
222
306
  title: 'Кредит',
223
307
  text: "Кредит одобрен! Деньги зачислены на счет #" + (data.creditId || data.creditAccountId),
@@ -232,7 +316,7 @@ async function applyForCredit() {
232
316
  style: { background: "rgb(58, 245, 11)" }
233
317
  }).showToast();
234
318
 
235
- if (typeof loadData === 'function') loadData(); // Безопасный вызов обновления данных
319
+ if (typeof loadData === 'function') loadData();
236
320
  } else {
237
321
  await Swal.fire({
238
322
  title: 'Кредит',
@@ -245,8 +329,6 @@ async function applyForCredit() {
245
329
  console.error("Ошибка: " + (data.error || data.message));
246
330
  }
247
331
  }
248
-
249
- // Обработчик кнопки выхода из системы
250
332
  document.getElementById("logoutBtn").addEventListener("click", async () => {
251
333
  const logOut = await Swal.fire({
252
334
  title: 'Выход',
@@ -269,8 +351,6 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
269
351
  } catch (e) {
270
352
  console.error('Ошибка сети при логауте:', e.message);
271
353
  }
272
-
273
- // ИСПРАВЛЕНО: перенаправление на чистый роут без расширения .html
274
354
  window.location.href = '/home.html';
275
355
  });
276
356
 
@@ -4,26 +4,27 @@
4
4
  <meta charset="UTF-8">
5
5
  <title>City-Bank | Профиль</title>
6
6
  <link rel="stylesheet" href="/css/style.css">
7
+ <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
7
8
  </head>
8
9
  <body>
9
10
  <div class="main-container">
10
11
  <div class="sidebar">
11
- <div style="text-align: center; margin-bottom: 15px;">
12
- <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
- </div>
14
- <h2 id="user-display">Загрузка...</h2>
15
- <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
16
- <hr style="border-color: #34495e;">
17
- <a href="/general.html" class="nav-item"><button class="menu-btn active">Главная</button></a>
18
- <a href="/accounts.html" class="nav-item"><button class="menu-btn">Мои Счета</button></a>
19
- <a href="/transfer.html" class="nav-item"><button class="menu-btn">Перевод средств</button></a>
20
- <a href="/history.html" class="nav-item"><button class="menu-btn">История транзакций</button></a>
21
- <a href="/credit.html" class="nav-item"><button class="menu-btn">Оформить Кредит</button></a>
22
- <a href="/profile.html" class="nav-item"><button class="menu-btn">Управление профилем</button></a>
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;">
14
+ </div>
15
+ <h2 id="user-display">Загрузка...</h2>
16
+ <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
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>
23
+ <a class="nav-item"><button class="menu-btn active" id="profile">Управление профилем</button></a>
23
24
  <button class="menu-btn" onclick="location.href='/admin.html'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
24
- <br><br>
25
- <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
26
- </div>
25
+ <br><br>
26
+ <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
27
+ </div>
27
28
 
28
29
  <div class="container">
29
30
  <div class="container-center">
@@ -73,6 +74,8 @@
73
74
  </div>
74
75
  <script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
75
76
  <script src="/js/sweetalert2.js"></script>
77
+ <script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
78
+ <script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
76
79
  <script src="/js/js.js"></script>
77
80
  </body>
78
81
  </html>
@@ -4,6 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <title>City-Bank | Переводы</title>
6
6
  <link rel="stylesheet" href="/css/style.css">
7
+ <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/>
7
8
  </head>
8
9
  <body>
9
10
  <div class="main-container">
@@ -14,13 +15,13 @@
14
15
  <h2 id="user-display">Загрузка...</h2>
15
16
  <p style="text-align: center; color: #bbb;">Всего средств: <span id="total-manny" style="font-weight: bold; color: #1abc9c;">0.00</span> руб.</p>
16
17
  <hr style="border-color: #34495e;">
17
- <a href="/general.html" class="nav-item"><button class="menu-btn">Главная</button></a>
18
- <a href="/accounts.html" class="nav-item"><button class="menu-btn">Мои Счета</button></a>
19
- <a href="/transfer.html" class="nav-item"><button class="menu-btn active">Перевод средств</button></a>
20
- <a href="/history.html" class="nav-item"><button class="menu-btn">История транзакций</button></a>
21
- <a href="/credit.html" class="nav-item"><button class="menu-btn">Оформить Кредит</button></a>
22
- <a href="/profile.html" class="nav-item"><button class="menu-btn">Управление профилем</button></a>
23
- <button class="menu-btn" onclick="location.href='/admin'" id="admin-nav" style="display: none; color: #ffc107;">Админ-панель</button>
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 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>
24
25
  <br><br>
25
26
  <button class="menu-btn btn-danger" id="logoutBtn" style="text-align: center;">Выйти из системы</button>
26
27
  </div>
@@ -54,6 +55,8 @@
54
55
  </div>
55
56
  </div>
56
57
  <script src="/js/sweetalert2.js"></script>
58
+ <script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
59
+ <script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
57
60
  <script src="/js/js.js"></script>
58
61
  </body>
59
62
  </html>
package/server/server.js CHANGED
@@ -210,9 +210,22 @@ module.exports = function registerRoutes(app) {
210
210
  const result = await accountsHub.getLogs(req.user.name);
211
211
  return res.json(result);
212
212
  });
213
-
214
-
215
-
213
+ app.post('/api/terminal/login', async(req, res)=>{
214
+ if(!req.body) return res.sendStatus(400)
215
+ const id = req.body.id;
216
+ const pincode = req.body.pincode;
217
+ const card = req.body.card;
218
+ const result = await accountsHub.linkACard(card, id, pincode)
219
+ if(!result.status) return res.sendStatus(422)
220
+ return res.sendStatus(200);
221
+ });
222
+ app.post('/api/terminal/transfer', async(req, res)=>{
223
+ const card = req.body.card;
224
+ const to = req.body.to;
225
+ const pincode = req.body.pincode;
226
+ const manny = req.body.pinCode;
227
+ const result = await accountsHub.cardTransfer(card, to, manny, pincode)
228
+ });
216
229
  return app;
217
230
  };
218
231
  module.exports.verifySession = verifySession;