fix: harden auth and investment synchronization
Backend security / security (push) Successful in 8s
Backend verify / verify (push) Successful in 11m9s
Conventional commits / commits (pull_request) Successful in 28s
Backend security / security (pull_request) Successful in 7s
Backend verify / verify (pull_request) Successful in 10m38s

Resolve A01-A10 and C01-C07 from the backend audit.
Preserve auth failures, forced candle reconciliation and forecast freshness.
Validate MOEX responses and nested HTTP errors; remove unused legacy paths.

Verified: 209 unit tests, 262 SQLite e2e tests on Linux, OpenAPI and durability.
Record the remaining macOS native SQLite abort in the audit.
This commit is contained in:
2026-09-27 14:09:05 +03:00
parent 5d3835e796
commit 4796d9d3f0
55 changed files with 1954 additions and 569 deletions
+34
View File
@@ -275,6 +275,40 @@ describe('Manual bank cards configured HTTP and real SQLite', () => {
})
.expect(400);
});
it('returns nested money field errors without exposing input or writing a card', async () => {
const before = await db.bankCard.count();
const response = await auth('post', '')
.send({
id: randomUUID(),
name: 'Card',
openingDate: '2026-01-01',
openingBalance: {
currency: 'USD',
value: 'SYNTHETIC_VALIDATION_SECRET',
},
})
.expect(400)
.expect('Content-Type', /application\/problem\+json/);
expect(response.body).toEqual({
status: 400,
code: 'VALIDATION_ERROR',
errors: [
{
pointer: '#/openingBalance/currency',
detail: expect.stringContaining('RUB') as unknown,
},
{
pointer: '#/openingBalance/value',
detail: expect.any(String) as unknown,
},
],
});
expect(JSON.stringify(response.body)).not.toContain(
'SYNTHETIC_VALIDATION_SECRET',
);
expect(await db.bankCard.count()).toBe(before);
});
it('scopes every card/category/expense link and edit to owner', async () => {
const own = await createCard(),
foreign = await createCard('0', stranger);