security: round 3 hardening (CSRF double-submit, TRX MITM, container hardening)

This commit is contained in:
ZOMBIIIIIII
2026-05-12 01:47:58 +03:00
parent c8bc40af97
commit 8dc0855827
37 changed files with 1852 additions and 318 deletions

View File

@@ -20,6 +20,12 @@ export const WalletModel = {
return db('wallets').where({ user_id: userId, chain }).first();
},
/**
* Insert wallets. UNIQUE(user_id, chain) на уровне DB предотвращает дубликаты —
* на конфликт kicks transaction rollback.
* Используется только из createWallet (custodial bootstrap, one-shot per user).
* НЕ используем upsertMany — нет легитимного пути менять адрес после генерации.
*/
async createMany(
wallets: { user_id: string; chain: string; address: string; derivation_path: string }[],
trx?: Knex.Transaction,
@@ -27,19 +33,4 @@ export const WalletModel = {
const withIds = wallets.map((w) => ({ id: generateUlid(), ...w }));
return (trx || db)('wallets').insert(withIds).returning('*');
},
/**
* Insert wallets, on conflict (user_id, chain) update address + derivation_path.
* Used by POST /api/wallets — клиент шлёт массив адресов после регистрации в BITOK.
*/
async upsertMany(
wallets: { user_id: string; chain: string; address: string; derivation_path: string }[]
): Promise<WalletRow[]> {
const withIds = wallets.map((w) => ({ id: generateUlid(), ...w }));
return db('wallets')
.insert(withIds)
.onConflict(['user_id', 'chain'])
.merge(['address', 'derivation_path'])
.returning('*');
},
};