Docker images / prepare-release (push) Successful in 12s
Docker images / backend-test (push) Successful in 4m9s
Docker images / frontend-image (push) Successful in 4m28s
Docker images / updater-image (push) Successful in 58s
Docker images / backend-image (push) Successful in 2m49s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 11s
При старте backend накатывает схему PostgreSQL 18 и, если база пустая, один раз импортирует mikrotik.db с тома. Повторный старт не копирует данные. Бэкап в UI идёт через pg_dump. Co-authored-by: Cursor <[email protected]>
75 lines
2.8 KiB
TypeScript
75 lines
2.8 KiB
TypeScript
import assert from "node:assert/strict"
|
|
import { normalizeBindingPeer, PeerBindError } from "./peer-bind.js"
|
|
import { withPgOrSkip } from "../../test/pg.js"
|
|
import { dbQuery } from "../../db/index.js"
|
|
|
|
assert.throws(
|
|
() => normalizeBindingPeer("wg", ""),
|
|
(err: unknown) => err instanceof PeerBindError && err.status === 400,
|
|
"WG без ключа — 400",
|
|
)
|
|
assert.equal(normalizeBindingPeer("ether", "ignored"), "")
|
|
assert.equal(normalizeBindingPeer("wg", " abc "), "abc")
|
|
|
|
if (!(await withPgOrSkip())) {
|
|
console.log("users bindings unique+cascade tests skip")
|
|
process.exit(0)
|
|
}
|
|
|
|
await dbQuery(`
|
|
INSERT INTO servers (id, name, host) VALUES (91001, 'jh-bind-test', '10.0.0.1')
|
|
ON CONFLICT (id) DO NOTHING
|
|
`)
|
|
await dbQuery(`
|
|
INSERT INTO app_users (id, name, login)
|
|
VALUES ('u-bind-1', 'A', 'a.bind.test'), ('u-bind-2', 'B', 'b.bind.test')
|
|
ON CONFLICT (id) DO NOTHING
|
|
`)
|
|
await dbQuery(`DELETE FROM user_interface_bindings WHERE server_id = 91001`)
|
|
await dbQuery(`
|
|
INSERT INTO user_interface_bindings (id, user_id, server_id, interface_name, interface_type)
|
|
VALUES ('b-bind-1', 'u-bind-1', 91001, 'gre-office', 'gre')
|
|
`)
|
|
|
|
let uniqueIface = false
|
|
try {
|
|
await dbQuery(`
|
|
INSERT INTO user_interface_bindings (id, user_id, server_id, interface_name, interface_type)
|
|
VALUES ('b-bind-2', 'u-bind-2', 91001, 'gre-office', 'gre')
|
|
`)
|
|
} catch {
|
|
uniqueIface = true
|
|
}
|
|
assert.equal(uniqueIface, true, "один интерфейс на сервере — один пользователь")
|
|
|
|
await dbQuery(`
|
|
INSERT INTO user_interface_bindings (id, user_id, server_id, interface_name, interface_type, peer_public_key, peer_name)
|
|
VALUES ('wg-bind-1', 'u-bind-1', 91001, 'wg-server', 'wg', 'peer-key-aaa', 'phone')
|
|
`)
|
|
await dbQuery(`
|
|
INSERT INTO user_interface_bindings (id, user_id, server_id, interface_name, interface_type, peer_public_key, peer_name)
|
|
VALUES ('wg-bind-2', 'u-bind-2', 91001, 'wg-server', 'wg', 'peer-key-bbb', 'laptop')
|
|
`)
|
|
|
|
let uniquePeer = false
|
|
try {
|
|
await dbQuery(`
|
|
INSERT INTO user_interface_bindings (id, user_id, server_id, interface_name, interface_type, peer_public_key)
|
|
VALUES ('wg-bind-3', 'u-bind-2', 91001, 'wg-server', 'wg', 'peer-key-aaa')
|
|
`)
|
|
} catch {
|
|
uniquePeer = true
|
|
}
|
|
assert.equal(uniquePeer, true, "один пир — один пользователь")
|
|
|
|
await dbQuery(`DELETE FROM app_users WHERE id = 'u-bind-1'`)
|
|
const leftover = await dbQuery<{ n: number }>(
|
|
`SELECT COUNT(*)::int AS n FROM user_interface_bindings WHERE server_id = 91001`,
|
|
)
|
|
assert.equal(leftover.rows[0]?.n, 1, "каскад: привязки u1 удаляются, пир u2 остаётся")
|
|
|
|
await dbQuery(`DELETE FROM app_users WHERE id IN ('u-bind-1', 'u-bind-2')`)
|
|
await dbQuery(`DELETE FROM servers WHERE id = 91001`)
|
|
|
|
console.log("users bindings unique+cascade tests ok")
|