diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3ab87f0..491038a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,10 +1,8 @@
name: CI
on:
- push:
- paths-ignore:
- - '*.md'
pull_request:
+ types: [opened, synchronize, reopened]
env:
CI: true
@@ -23,7 +21,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VER }}
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- run: npm install
- name: Initialize MySQL
run: sh sql/init-mysql.sh
@@ -56,12 +54,12 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
- node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
+ node-version: ${{ fromJson(needs.get-lts.outputs.lts) }}
fail-fast: false
steps:
- run: sudo /etc/init.d/mysql start
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
- run: sh sql/init-mysql.sh
@@ -73,15 +71,15 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
- node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
+ node-version: ${{ fromJson(needs.get-lts.outputs.lts) }}
fail-fast: false
steps:
- name: Install & Start MySQL
run: |
brew install mysql@8.4
brew services start mysql@8.4
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
with:
node-version: ${{ matrix.node-version }}
@@ -95,15 +93,15 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
- node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
+ node-version: ${{ fromJson(needs.get-lts.outputs.lts) }}
experimental: [true]
fail-fast: false
steps:
- name: Install MySQL
run: |
choco install mysql
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
name: Node ${{ matrix.node-version }}
with:
node-version: ${{ matrix.node-version }}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 311399f..337ce04 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,25 +1,20 @@
name: publish
on:
- push:
- branches:
- - main
- paths:
- - package.json
- release:
- types: [published]
+ release:
+ types: [published]
env:
CI: true
- node-version: 20
+ node-version: 22
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: sudo /etc/init.d/mysql start
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
with:
node-version: ${{ env.node-version }}
- run: sh sql/init-mysql.sh
@@ -30,25 +25,19 @@ jobs:
needs: build
runs-on: ubuntu-latest
steps:
- - uses: actions/setup-node@v4
+ - uses: actions/setup-node@v6
name: Node ${{ env.node-version }}
with:
node-version: ${{ env.node-version }}
registry-url: https://registry.npmjs.org/
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
# fetch-depth 0 needed by GitHub Release
- name: publish to NPM
run: npm publish --access=public
- env:
- NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
-
- - name: GitHub Release
- uses: justincy/github-action-npm-release@2.0.1
- id: release
publish-gpr:
needs: build
@@ -57,8 +46,8 @@ jobs:
contents: read
packages: write
steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
with:
node-version: ${{ env.node-version }}
registry-url: https://npm.pkg.github.com/
diff --git a/.prettierrc.yml b/.prettierrc.yml
deleted file mode 100644
index 9b110b8..0000000
--- a/.prettierrc.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-trailingComma: 'all'
-semi: false
-singleQuote: true
diff --git a/.release b/.release
index 7307651..d106d83 160000
--- a/.release
+++ b/.release
@@ -1 +1 @@
-Subproject commit 73076513e83c2057a32515831b638771c15b1d83
+Subproject commit d106d83e69d5d8c99e4d6be4ba98ddde550d082b
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1b7847..c519682 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,15 @@
+# Changelog
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/).
+
# CHANGES
### Unreleased
+### [3.0.0-alpha.7] - 2026-03-13
+
+- fixes
+
### [3.0.0-alpha.6] - 2025-04-08
- dep(eslint): upgraded to v9
@@ -39,7 +47,11 @@
- lib/user.get: convert booleans
+[3.0.0-alpha.0]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.0
+[3.0.0-alpha.1]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.1
+[3.0.0-alpha.2]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.2
[3.0.0-alpha.3]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.3
-[3.0.0-alpha.4]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.4
-[3.0.0-alpha.5]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.5
-[3.0.0-alpha.6]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.6
+[3.0.0-alpha.4]: https://github.com/NicTool/api/releases/tag/v3.0.0-alpha.4
+[3.0.0-alpha.5]: https://github.com/NicTool/api/releases/tag/v3.0.0-alpha.5
+[3.0.0-alpha.6]: https://github.com/NicTool/api/releases/tag/v3.0.0-alpha.6
+[3.0.0-alpha.7]: https://github.com/NicTool/api/releases/tag/v3.0.0-alpha.7
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
new file mode 100644
index 0000000..a489471
--- /dev/null
+++ b/CONTRIBUTORS.md
@@ -0,0 +1,9 @@
+# Contributors
+
+This handcrafted artisanal software is brought to you by:
+
+| 
msimerson (14)|
+| :---: |
+
+this file is generated by [.release](https://github.com/msimerson/.release).
+Contribute to this project to get your GitHub profile included here.
diff --git a/lib/config.js b/lib/config.js
index 08e6962..d636954 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -12,7 +12,7 @@ class Config {
this.getEnv(opts)
}
- async getEnv(opts = {}) {
+ getEnv(opts = {}) {
this.env = process.env.NODE_ENV ?? opts.env ?? ''
this.debug = Boolean(process.env.NODE_DEBUG)
if (this.debug) console.log(`debug: true, env: ${this.env}`)
diff --git a/lib/config.test.js b/lib/config.test.js
index d223605..ea7740c 100644
--- a/lib/config.test.js
+++ b/lib/config.test.js
@@ -39,15 +39,12 @@ describe('config', () => {
it(`detects NODE_DEBUG env`, async () => {
process.env.NODE_DEBUG = 1
- let cfg = await Config.get('mysql', 'test')
+ await Config.get('mysql', 'test')
assert.equal(Config.debug, true)
process.env.NODE_DEBUG = ''
- cfg = await Config.get('mysql', 'test')
+ await Config.get('mysql', 'test')
assert.equal(Config.debug, false)
-
- cfg = await Config.get('mysql', 'test')
- assert.equal(cfg.user, 'root')
})
})
})
diff --git a/lib/group.js b/lib/group.js
index 332a5de..64ecc0e 100644
--- a/lib/group.js
+++ b/lib/group.js
@@ -15,9 +15,7 @@ class Group {
if (g.length === 1) return g[0].id
}
- return await Mysql.execute(
- ...Mysql.insert(`nt_group`, mapToDbColumn(args, groupDbMap)),
- )
+ return await Mysql.execute(...Mysql.insert(`nt_group`, mapToDbColumn(args, groupDbMap)))
}
async get(args) {
@@ -48,11 +46,7 @@ class Group {
const id = args.id
delete args.id
const r = await Mysql.execute(
- ...Mysql.update(
- `nt_group`,
- `nt_group_id=${id}`,
- mapToDbColumn(args, groupDbMap),
- ),
+ ...Mysql.update(`nt_group`, `nt_group_id=${id}`, mapToDbColumn(args, groupDbMap)),
)
return r.changedRows === 1
}
@@ -67,9 +61,7 @@ class Group {
}
async destroy(args) {
- const r = await Mysql.execute(
- ...Mysql.delete(`nt_group`, { nt_group_id: args.id }),
- )
+ const r = await Mysql.execute(...Mysql.delete(`nt_group`, { nt_group_id: args.id }))
return r.affectedRows === 1
}
}
diff --git a/lib/mysql.js b/lib/mysql.js
index b55f35c..b72ddfc 100644
--- a/lib/mysql.js
+++ b/lib/mysql.js
@@ -18,8 +18,7 @@ class Mysql {
if (_debug) console.log(cfg)
this.dbh = await mysql.createConnection(cfg)
- if (_debug)
- console.log(`MySQL connection id ${this.dbh.connection.connectionId}`)
+ if (_debug) console.log(`MySQL connection id ${this.dbh.connection.connectionId}`)
return this.dbh
}
@@ -54,10 +53,7 @@ class Mysql {
}
update(table, where, params = {}) {
- return [
- `UPDATE ${table} SET ${Object.keys(params).join('=?,')}=? WHERE ${where}`,
- Object.values(params),
- ]
+ return [`UPDATE ${table} SET ${Object.keys(params).join('=?,')}=? WHERE ${where}`, Object.values(params)]
}
delete(table, params) {
diff --git a/lib/mysql.test.js b/lib/mysql.test.js
index 5bb305c..95e1047 100644
--- a/lib/mysql.test.js
+++ b/lib/mysql.test.js
@@ -34,10 +34,7 @@ describe('mysql', () => {
first_name: 'uNite',
last_name: 'Test',
})
- assert.deepEqual(r, [
- `INSERT INTO nt_user (first_name,last_name) VALUES(?,?)`,
- ['uNite', 'Test'],
- ])
+ assert.deepEqual(r, [`INSERT INTO nt_user (first_name,last_name) VALUES(?,?)`, ['uNite', 'Test']])
})
describe('update', () => {
@@ -45,10 +42,7 @@ describe('mysql', () => {
const r = Mysql.update(`nt_user`, `nt_user_id=4096`, {
first_name: 'uNite',
})
- assert.deepEqual(r, [
- `UPDATE nt_user SET first_name=? WHERE nt_user_id=4096`,
- ['uNite'],
- ])
+ assert.deepEqual(r, [`UPDATE nt_user SET first_name=? WHERE nt_user_id=4096`, ['uNite']])
})
it('formats with two values', () => {
@@ -56,10 +50,7 @@ describe('mysql', () => {
last_name: 'Teste',
is_admin: 1,
})
- assert.deepEqual(r, [
- `UPDATE nt_user SET last_name=?,is_admin=? WHERE nt_user_id=4096`,
- ['Teste', 1],
- ])
+ assert.deepEqual(r, [`UPDATE nt_user SET last_name=?,is_admin=? WHERE nt_user_id=4096`, ['Teste', 1]])
})
it('formats with three values', () => {
diff --git a/lib/nameserver.js b/lib/nameserver.js
index f349b98..84a99f3 100644
--- a/lib/nameserver.js
+++ b/lib/nameserver.js
@@ -26,12 +26,7 @@ class Nameserver {
delete args.export.type
}
- return await Mysql.execute(
- ...Mysql.insert(
- `nt_nameserver`,
- mapToDbColumn(objectToDb(args), nsDbMap),
- ),
- )
+ return await Mysql.execute(...Mysql.insert(`nt_nameserver`, mapToDbColumn(objectToDb(args), nsDbMap)))
}
async get(args) {
@@ -79,11 +74,7 @@ class Nameserver {
delete args.id
// Mysql.debug(1)
const r = await Mysql.execute(
- ...Mysql.update(
- `nt_nameserver`,
- `nt_nameserver_id=${id}`,
- mapToDbColumn(args, nsDbMap),
- ),
+ ...Mysql.update(`nt_nameserver`, `nt_nameserver_id=${id}`, mapToDbColumn(args, nsDbMap)),
)
return r.changedRows === 1
}
@@ -98,9 +89,7 @@ class Nameserver {
}
async destroy(args) {
- const r = await Mysql.execute(
- ...Mysql.delete(`nt_nameserver`, { nt_nameserver_id: args.id }),
- )
+ const r = await Mysql.execute(...Mysql.delete(`nt_nameserver`, { nt_nameserver_id: args.id }))
return r.affectedRows === 1
}
}
@@ -109,14 +98,7 @@ export default new Nameserver()
function dbToObject(rows) {
for (const row of rows) {
- for (const f of [
- 'description',
- 'address6',
- 'remote_login',
- 'datadir',
- 'logdir',
- 'export_status',
- ]) {
+ for (const f of ['description', 'address6', 'remote_login', 'datadir', 'logdir', 'export_status']) {
if ([undefined, null].includes(row[f])) row[f] = ''
}
for (const f of ['export']) {
diff --git a/lib/nameserver.test.js b/lib/nameserver.test.js
index 619b5eb..173a19c 100644
--- a/lib/nameserver.test.js
+++ b/lib/nameserver.test.js
@@ -27,9 +27,7 @@ describe('nameserver', function () {
})
it('changes a nameserver', async () => {
- assert.ok(
- await Nameserver.put({ id: testCase.id, name: 'b.ns.example.com.' }),
- )
+ assert.ok(await Nameserver.put({ id: testCase.id, name: 'b.ns.example.com.' }))
const ns = await Nameserver.get({ id: testCase.id })
assert.deepEqual(ns[0].name, 'b.ns.example.com.')
assert.ok(await Nameserver.put({ id: testCase.id, name: testCase.name }))
diff --git a/lib/permission.js b/lib/permission.js
index 84cc41d..c9e09c9 100644
--- a/lib/permission.js
+++ b/lib/permission.js
@@ -20,9 +20,7 @@ class Permission {
if (p) return p.id
}
- return await Mysql.execute(
- ...Mysql.insert(`nt_perm`, mapToDbColumn(objectToDb(args), permDbMap)),
- )
+ return await Mysql.execute(...Mysql.insert(`nt_perm`, mapToDbColumn(objectToDb(args), permDbMap)))
}
async get(args) {
@@ -38,14 +36,10 @@ class Permission {
, p.deleted
FROM nt_perm p`
- const rows = await Mysql.execute(
- ...Mysql.select(query, mapToDbColumn(args, permDbMap)),
- )
+ const rows = await Mysql.execute(...Mysql.select(query, mapToDbColumn(args, permDbMap)))
if (rows.length === 0) return
if (rows.length > 1) {
- throw new Error(
- `permissions.get found ${rows.length} rows for uid ${args.uid}`,
- )
+ throw new Error(`permissions.get found ${rows.length} rows for uid ${args.uid}`)
}
const row = dbToObject(rows[0])
if (args.deleted === false) delete row.deleted
@@ -76,11 +70,7 @@ class Permission {
const id = args.id
delete args.id
const r = await Mysql.execute(
- ...Mysql.update(
- `nt_perm`,
- `nt_perm_id=${id}`,
- mapToDbColumn(args, permDbMap),
- ),
+ ...Mysql.update(`nt_perm`, `nt_perm_id=${id}`, mapToDbColumn(args, permDbMap)),
)
return r.changedRows === 1
}
@@ -96,9 +86,7 @@ class Permission {
}
async destroy(args) {
- const r = await Mysql.execute(
- ...Mysql.delete(`nt_perm`, mapToDbColumn(args, permDbMap)),
- )
+ const r = await Mysql.execute(...Mysql.delete(`nt_perm`, mapToDbColumn(args, permDbMap)))
return r.affectedRows === 1
}
}
diff --git a/lib/permission.test.js b/lib/permission.test.js
index 20eb8a4..be5821f 100644
--- a/lib/permission.test.js
+++ b/lib/permission.test.js
@@ -24,40 +24,26 @@ describe('permission', function () {
})
it('get: by id', async () => {
- assert.deepEqual(
- await Permission.get({ id: permTestCase.id }),
- permTestCase,
- )
+ assert.deepEqual(await Permission.get({ id: permTestCase.id }), permTestCase)
})
it('get: by user id', async () => {
- assert.deepEqual(
- await Permission.get({ uid: permTestCase.user.id }),
- permTestCase,
- )
+ assert.deepEqual(await Permission.get({ uid: permTestCase.user.id }), permTestCase)
})
it('get: by group id', async () => {
- assert.deepEqual(
- await Permission.get({ gid: permTestCase.group.id }),
- permTestCase,
- )
+ assert.deepEqual(await Permission.get({ gid: permTestCase.group.id }), permTestCase)
})
it('getGroup: gets group permissions', async () => {
- assert.deepEqual(
- await Permission.getGroup({ uid: permTestCase.user.id }),
- permTestCase,
- )
+ assert.deepEqual(await Permission.getGroup({ uid: permTestCase.user.id }), permTestCase)
})
it('changes a permission', async () => {
assert.ok(await Permission.put({ id: permTestCase.id, name: 'Changed' }))
const perm = await Permission.get({ id: permTestCase.id })
assert.deepEqual(perm.name, 'Changed')
- assert.ok(
- await Permission.put({ id: permTestCase.id, name: 'Test Permission' }),
- )
+ assert.ok(await Permission.put({ id: permTestCase.id, name: 'Test Permission' }))
})
it('deletes a permission', async () => {
diff --git a/lib/session.js b/lib/session.js
index 31fd11e..95efcd6 100644
--- a/lib/session.js
+++ b/lib/session.js
@@ -16,9 +16,7 @@ class Session {
const r = await this.get(args)
if (r) return r.id
- const id = await Mysql.execute(
- ...Mysql.insert(`nt_user_session`, mapToDbColumn(args, sessionDbMap)),
- )
+ const id = await Mysql.execute(...Mysql.insert(`nt_user_session`, mapToDbColumn(args, sessionDbMap)))
return id
}
@@ -67,20 +65,14 @@ class Session {
const id = args.id
delete args.id
const r = await Mysql.execute(
- ...Mysql.update(
- `nt_user_session`,
- `nt_user_session_id=${id}`,
- mapToDbColumn(args, sessionDbMap),
- ),
+ ...Mysql.update(`nt_user_session`, `nt_user_session_id=${id}`, mapToDbColumn(args, sessionDbMap)),
)
// console.log(r)
return r.changedRows === 1
}
async delete(args) {
- const r = await Mysql.execute(
- ...Mysql.delete(`nt_user_session`, mapToDbColumn(args, sessionDbMap)),
- )
+ const r = await Mysql.execute(...Mysql.delete(`nt_user_session`, mapToDbColumn(args, sessionDbMap)))
return r.affectedRows === 1
}
}
diff --git a/lib/session.test.js b/lib/session.test.js
index 904fb31..288b4c4 100644
--- a/lib/session.test.js
+++ b/lib/session.test.js
@@ -5,11 +5,20 @@ import User from './user.js'
import Session from './session.js'
import userCase from './test/user.json' with { type: 'json' }
+const sessionUser = {
+ ...userCase,
+ id: userCase.id + 100,
+ username: `${userCase.username}-session`,
+ email: `session-${userCase.email}`,
+}
+
before(async () => {
- await User.create(userCase)
+ await User.create(sessionUser)
})
after(async () => {
+ await Session.delete({ uid: sessionUser.id })
+ await User.destroy({ id: sessionUser.id })
await User.mysql.disconnect()
})
@@ -20,7 +29,7 @@ describe('session', function () {
describe('create', () => {
it('creates a login session', async () => {
sessionId = await Session.create({
- nt_user_id: userCase.id,
+ nt_user_id: sessionUser.id,
session: '3.0.0',
last_access: parseInt(Date.now() / 1000, 10),
})
@@ -31,7 +40,6 @@ describe('session', function () {
describe('get', () => {
it('finds a session by id', async () => {
const s = await Session.get({ id: sessionId })
- // console.log(s)
assert.ok(s?.id)
})
diff --git a/lib/test/nameserver.json b/lib/test/nameserver.json
index 39e76ab..934ecbd 100644
--- a/lib/test/nameserver.json
+++ b/lib/test/nameserver.json
@@ -12,7 +12,7 @@
"interval": 0,
"serials": true,
"status": "last run:03-05 15:25
last cp :09-20 12:59",
- "type": "NSD"
+ "type": "nsd"
},
"ttl": 3600
}
diff --git a/lib/user.js b/lib/user.js
index 208dd7b..a5ac0ad 100644
--- a/lib/user.js
+++ b/lib/user.js
@@ -37,14 +37,7 @@ class User {
AND g.name = ?`
for (const u of await Mysql.execute(query, [username, groupName])) {
- if (
- await this.validPassword(
- authTry.password,
- u.password,
- authTry.username,
- u.pass_salt,
- )
- ) {
+ if (await this.validPassword(authTry.password, u.password, authTry.username, u.pass_salt)) {
for (const f of ['password', 'pass_salt']) {
delete u[f] // SECURITY: no longer needed
}
@@ -73,9 +66,7 @@ class User {
args.password = await this.hashAuthPbkdf2(args.password, args.pass_salt)
}
- const userId = await Mysql.execute(
- ...Mysql.insert(`nt_user`, mapToDbColumn(args, userDbMap)),
- )
+ const userId = await Mysql.execute(...Mysql.insert(`nt_user`, mapToDbColumn(args, userDbMap)))
return userId
}
@@ -111,11 +102,7 @@ class User {
const id = args.id
delete args.id
const r = await Mysql.execute(
- ...Mysql.update(
- `nt_user`,
- `nt_user_id=${id}`,
- mapToDbColumn(args, userDbMap),
- ),
+ ...Mysql.update(`nt_user`, `nt_user_id=${id}`, mapToDbColumn(args, userDbMap)),
)
return r.changedRows === 1
}
@@ -130,16 +117,12 @@ class User {
}
async destroy(args) {
- const r = await Mysql.execute(
- ...Mysql.delete(`nt_user`, mapToDbColumn({ id: args.id }, userDbMap)),
- )
+ const r = await Mysql.execute(...Mysql.delete(`nt_user`, mapToDbColumn({ id: args.id }, userDbMap)))
return r.affectedRows === 1
}
generateSalt(length = 16) {
- const chars = Array.from({ length: 87 }, (_, i) =>
- String.fromCharCode(i + 40),
- ) // ASCII 40-126
+ const chars = Array.from({ length: 87 }, (_, i) => String.fromCharCode(i + 40)) // ASCII 40-126
let salt = ''
for (let i = 0; i < length; i++) {
salt += chars[Math.floor(Math.random() * 87)]
@@ -168,10 +151,7 @@ class User {
// Check for HMAC SHA-1 password
if (/^[0-9a-f]{40}$/.test(passDb)) {
- const digest = crypto
- .createHmac('sha1', username.toLowerCase())
- .update(passTry)
- .digest('hex')
+ const digest = crypto.createHmac('sha1', username.toLowerCase()).update(passTry).digest('hex')
if (this.debug) console.log(`digest: (${digest === passDb}) ${digest}`)
return digest === passDb
}
diff --git a/lib/zone.js b/lib/zone.js
index c712da3..44e065e 100644
--- a/lib/zone.js
+++ b/lib/zone.js
@@ -15,9 +15,7 @@ class Zone {
if (g.length === 1) return g[0].id
}
- return await Mysql.execute(
- ...Mysql.insert(`nt_zone`, mapToDbColumn(args, zoneDbMap)),
- )
+ return await Mysql.execute(...Mysql.insert(`nt_zone`, mapToDbColumn(args, zoneDbMap)))
}
async get(args) {
@@ -51,6 +49,8 @@ class Zone {
for (const f of ['description', 'location']) {
if ([null].includes(row[f])) row[f] = ''
}
+ if (row['last_publish'] === undefined) delete row['last_publish']
+ if (/00:00:00/.test(row['last_publish'])) row['last_publish'] = null
if (args.deleted === false) delete row.deleted
}
@@ -62,11 +62,7 @@ class Zone {
const id = args.id
delete args.id
const r = await Mysql.execute(
- ...Mysql.update(
- `nt_zone`,
- `nt_zone_id=${id}`,
- mapToDbColumn(args, zoneDbMap),
- ),
+ ...Mysql.update(`nt_zone`, `nt_zone_id=${id}`, mapToDbColumn(args, zoneDbMap)),
)
return r.changedRows === 1
}
@@ -81,9 +77,7 @@ class Zone {
}
async destroy(args) {
- const r = await Mysql.execute(
- ...Mysql.delete(`nt_zone`, { nt_zone_id: args.id }),
- )
+ const r = await Mysql.execute(...Mysql.delete(`nt_zone`, { nt_zone_id: args.id }))
return r.affectedRows === 1
}
}
diff --git a/lib/zone.test.js b/lib/zone.test.js
index 01185de..c4be676 100644
--- a/lib/zone.test.js
+++ b/lib/zone.test.js
@@ -29,9 +29,7 @@ describe('zone', function () {
})
it('changes a zone', async () => {
- assert.ok(
- await Zone.put({ id: testCase.id, mailaddr: 'toastmaster.example.com.' }),
- )
+ assert.ok(await Zone.put({ id: testCase.id, mailaddr: 'toastmaster.example.com.' }))
const ns = await Zone.get({ id: testCase.id })
assert.deepEqual(ns[0].mailaddr, 'toastmaster.example.com.')
assert.ok(await Zone.put({ id: testCase.id, mailaddr: testCase.mailaddr }))
diff --git a/lib/zone_record.js b/lib/zone_record.js
index c5745bb..25ae4e1 100644
--- a/lib/zone_record.js
+++ b/lib/zone_record.js
@@ -5,6 +5,8 @@ import { mapToDbColumn } from './util.js'
const zrDbMap = { id: 'nt_zone_record_id', zid: 'nt_zone_id', owner: 'name' }
const boolFields = ['deleted']
+const keepZeroWeightFor = new Set(['SRV', 'URI'])
+const keepZeroPriorityFor = new Set(['HTTPS', 'SVCB', 'URI'])
class ZoneRecord {
constructor() {
@@ -21,14 +23,16 @@ class ZoneRecord {
args = objectToDb(args)
- return await Mysql.execute(
- ...Mysql.insert(`nt_zone_record`, mapToDbColumn(args, zrDbMap)),
- )
+ return await Mysql.execute(...Mysql.insert(`nt_zone_record`, mapToDbColumn(args, zrDbMap)))
}
async get(args) {
args = JSON.parse(JSON.stringify(args))
if (args.deleted === undefined) args.deleted = false
+ if (args.type !== undefined) {
+ args.type_id = RR.typeMap[args.type]
+ delete args.type
+ }
const rows = await Mysql.execute(
...Mysql.select(
@@ -66,11 +70,7 @@ class ZoneRecord {
const id = args.id
delete args.id
const r = await Mysql.execute(
- ...Mysql.update(
- `nt_zone_record`,
- `nt_zone_record_id=${id}`,
- mapToDbColumn(args, zrDbMap),
- ),
+ ...Mysql.update(`nt_zone_record`, `nt_zone_record_id=${id}`, mapToDbColumn(args, zrDbMap)),
)
return r.changedRows === 1
}
@@ -85,9 +85,7 @@ class ZoneRecord {
}
async destroy(args) {
- const r = await Mysql.execute(
- ...Mysql.delete(`nt_zone_record`, { nt_zone_record_id: args.id }),
- )
+ const r = await Mysql.execute(...Mysql.delete(`nt_zone_record`, { nt_zone_record_id: args.id }))
return r.affectedRows === 1
}
}
@@ -107,15 +105,21 @@ function dbToObject(rows) {
const map = getMap(row.type)
if (map) unApplyMap(row, map)
- for (const f of [
- 'description',
- 'other',
- 'location',
- 'weight',
- 'priority',
- 'timestamp',
- ]) {
- if (null === row[f]) delete row[f]
+ if ([null, ''].includes(row.description)) delete row.description
+ if ([null, '', '0'].includes(row.other)) delete row.other
+ if ([null, ''].includes(row.location)) delete row.location
+ if (row.timestamp === null) delete row.timestamp
+
+ if (row.weight === null) {
+ delete row.weight
+ } else if (row.weight === 0 && !keepZeroWeightFor.has(row.type)) {
+ delete row.weight
+ }
+
+ if (row.priority === null) {
+ delete row.priority
+ } else if (row.priority === 0 && !keepZeroPriorityFor.has(row.type)) {
+ delete row.priority
}
}
@@ -162,12 +166,10 @@ function unApplyMap(obj, map) {
delete map.address
}
if (obj.type === 'NSEC3') {
- const [algo, flags, iters, salt, bitmaps, next] = obj.address
- .slice(1, -1)
- .split("','")
- obj['hash algorithm'] = /^\d+$/.test(algo) ? parseInt(algo) : (algo ?? '')
- obj.flags = /^\d+$/.test(flags) ? parseInt(flags) : (flags ?? '')
- obj.iterations = /^\d+$/.test(iters) ? parseInt(iters) : (iters ?? '')
+ const [algo, flags, iters, salt, bitmaps, next] = obj.address.slice(1, -1).split("','")
+ obj['hash algorithm'] = /^\d+$/.test(algo) ? parseInt(algo) : algo ?? ''
+ obj.flags = /^\d+$/.test(flags) ? parseInt(flags) : flags ?? ''
+ obj.iterations = /^\d+$/.test(iters) ? parseInt(iters) : iters ?? ''
obj.salt = salt
obj['type bit maps'] = bitmaps
obj['next hashed owner name'] = next
@@ -176,17 +178,15 @@ function unApplyMap(obj, map) {
}
if (obj.type === 'NSEC3PARAM') {
const [algo, flags, iters, salt] = obj.address.slice(1, -1).split("','")
- obj['hash algorithm'] = /^\d+$/.test(algo) ? parseInt(algo) : (algo ?? '')
- obj.flags = /^\d+$/.test(flags) ? parseInt(flags) : (flags ?? '')
- obj.iterations = /^\d+$/.test(iters) ? parseInt(iters) : (iters ?? '')
+ obj['hash algorithm'] = /^\d+$/.test(algo) ? parseInt(algo) : algo ?? ''
+ obj.flags = /^\d+$/.test(flags) ? parseInt(flags) : flags ?? ''
+ obj.iterations = /^\d+$/.test(iters) ? parseInt(iters) : iters ?? ''
obj.salt = salt
delete obj.address
delete map.address
}
if (obj.type === 'SOA') {
- const [one, two, three, four, five, six, seven] = obj.address
- .slice(1, -1)
- .split("','")
+ const [one, two, three, four, five, six, seven] = obj.address.slice(1, -1).split("','")
obj.mname = one
obj.rname = two
obj.serial = parseInt(three)
@@ -289,14 +289,7 @@ function getMap(rrType) {
}
case 'NSEC3':
return {
- address: [
- 'hash algorithm',
- 'flags',
- 'iterations',
- 'salt',
- 'type bit maps',
- 'next hashed owner name',
- ],
+ address: ['hash algorithm', 'flags', 'iterations', 'salt', 'type bit maps', 'next hashed owner name'],
}
case 'NSEC3PARAM':
return {
@@ -320,15 +313,7 @@ function getMap(rrType) {
}
case 'SOA':
return {
- address: [
- 'mname',
- 'rname',
- 'serial',
- 'refresh',
- 'retry',
- 'expire',
- 'minimum',
- ],
+ address: ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire', 'minimum'],
}
case 'SPF':
return { address: 'data' }
diff --git a/lib/zone_record.test.js b/lib/zone_record.test.js
index 3184bf0..ee0a4ff 100644
--- a/lib/zone_record.test.js
+++ b/lib/zone_record.test.js
@@ -35,7 +35,11 @@ describe('zone_record', function () {
})
it('GET by name', async () => {
- const zrs = await ZoneRecord.get({ zone_record: testCase.zone_record })
+ const zrs = await ZoneRecord.get({
+ owner: testCase.owner,
+ type: testCase.type,
+ zid: testCase.zid,
+ })
delete zrs[0].last_modified
assert.deepEqual(zrs[0], testCase)
})
diff --git a/package.json b/package.json
index d85acaf..a8d72c0 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,10 @@
{
"name": "@nictool/api",
- "version": "3.0.0-alpha.6",
+ "version": "3.0.0-alpha.7",
"description": "NicTool API",
"main": "index.js",
"type": "module",
+ "files": [ "CHANGELOG.md", "conf.d", "html", "lib", "routes", "sql", "server.js" ],
"scripts": {
"format": "npm run lint:fix && npm run prettier:fix",
"lint": "npx eslint *.js **/*.js",
@@ -13,6 +14,7 @@
"start": "NODE_ENV=production node ./server",
"develop": "NODE_ENV=development node --watch server.js ./server",
"test": "./test.sh",
+ "test:develop": "NODE_ENV=development ./test.sh",
"versions": "npx dependency-version-checker check",
"versions:fix": "npx dependency-version-checker update",
"watch": "./test.sh watch"
@@ -51,5 +53,11 @@
"mysql2": "^3.14.0",
"qs": "^6.14.0",
"yaml": "^2.7.1"
+ },
+ "prettier": {
+ "printWidth": 110,
+ "semi": false,
+ "singleQuote": true,
+ "trailingComma": "all"
}
}
\ No newline at end of file
diff --git a/routes/group.test.js b/routes/group.test.js
index d3d662a..00073e7 100644
--- a/routes/group.test.js
+++ b/routes/group.test.js
@@ -23,7 +23,7 @@ after(async () => {
})
describe('group routes', () => {
- let auth = { headers: { } }
+ let auth = { headers: {} }
it('POST /session establishes a session', async () => {
const res = await server.inject({
diff --git a/routes/index.js b/routes/index.js
index b33c66a..f4a1ba1 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -40,10 +40,7 @@ async function setup() {
routes: {
cors: true,
files: {
- relativeTo: path.join(
- path.dirname(url.fileURLToPath(import.meta.url)),
- 'html',
- ),
+ relativeTo: path.join(path.dirname(url.fileURLToPath(import.meta.url)), 'html'),
},
},
})
@@ -113,9 +110,7 @@ async function setup() {
server.events.on('request', (request, event, tags) => {
if (tags.error) {
- console.error(
- `Request ${event.request} error: ${event.error ? event.error.message : 'unknown'}`,
- )
+ console.error(`Request ${event.request} error: ${event.error ? event.error.message : 'unknown'}`)
}
})
diff --git a/routes/nameserver.test.js b/routes/nameserver.test.js
index c93038c..33ec97e 100644
--- a/routes/nameserver.test.js
+++ b/routes/nameserver.test.js
@@ -27,7 +27,7 @@ after(async () => {
})
describe('nameserver routes', () => {
- let auth = { headers: { } }
+ let auth = { headers: {} }
it('POST /session establishes a session', async () => {
const res = await server.inject({
diff --git a/routes/permission.test.js b/routes/permission.test.js
index 3c4c7bb..730fd7a 100644
--- a/routes/permission.test.js
+++ b/routes/permission.test.js
@@ -26,7 +26,7 @@ after(async () => {
})
describe('permission routes', () => {
- let auth = { headers: { } }
+ let auth = { headers: {} }
it('POST /session establishes a session', async () => {
const res = await server.inject({
diff --git a/routes/session.test.js b/routes/session.test.js
index 9e3bd1f..fc5859c 100644
--- a/routes/session.test.js
+++ b/routes/session.test.js
@@ -42,7 +42,7 @@ describe('session routes', () => {
})
describe('with session, can retrieve private URIs', () => {
- let auth = { headers: { } }
+ let auth = { headers: {} }
before(async () => {
const res = await server.inject({
diff --git a/routes/test/nameserver.json b/routes/test/nameserver.json
index ee6237d..a5366be 100644
--- a/routes/test/nameserver.json
+++ b/routes/test/nameserver.json
@@ -12,7 +12,7 @@
"interval": 0,
"serials": true,
"status": "last run:03-05 15:25
last cp :09-20 12:59",
- "type": "NSD"
+ "type": "nsd"
},
"ttl": 3600,
"deleted": false
diff --git a/routes/user.test.js b/routes/user.test.js
index 2a0e6d1..5d2fdbc 100644
--- a/routes/user.test.js
+++ b/routes/user.test.js
@@ -8,7 +8,8 @@ import Group from '../lib/group.js'
import groupCase from './test/group.json' with { type: 'json' }
import userCase from './test/user.json' with { type: 'json' }
-let server, auth = { headers: { } }
+let server,
+ auth = { headers: {} }
before(async () => {
server = await init()
diff --git a/routes/zone.test.js b/routes/zone.test.js
index 6f090cd..821548e 100644
--- a/routes/zone.test.js
+++ b/routes/zone.test.js
@@ -14,6 +14,7 @@ let server
let case2Id = 4094
before(async () => {
+ await Zone.destroy({ id: nsCase.id })
await Zone.destroy({ id: case2Id })
await Group.create(groupCase)
await User.create(userCase)
@@ -27,7 +28,7 @@ after(async () => {
})
describe('zone routes', () => {
- let auth = { headers: { } }
+ let auth = { headers: {} }
it('POST /session establishes a session', async () => {
const res = await server.inject({
@@ -50,7 +51,7 @@ describe('zone routes', () => {
})
// console.log(res.result)
assert.equal(res.statusCode, 200)
- assert.equal(res.result.zone[0].name, nsCase.name)
+ assert.equal(res.result.zone[0].zone, nsCase.zone)
})
it(`POST /zone (${case2Id})`, async () => {
diff --git a/sql/04_nt_nameserver.sql b/sql/04_nt_nameserver.sql
index 2e4841f..afbe6d9 100644
--- a/sql/04_nt_nameserver.sql
+++ b/sql/04_nt_nameserver.sql
@@ -66,7 +66,7 @@ VALUES (1,'djbdns','djbdns (tinydns & axfrdns)','cr.yp.to/djbdns.html'),
(3,'maradns','MaraDNS', 'maradns.samiam.org'),
(4,'powerdns','PowerDNS','www.powerdns.com'),
(5,'bind-nsupdate','BIND (nsupdate protocol)',''),
- (6,'NSD','Name Server Daemon (NSD)','www.nlnetlabs.nl/projects/nsd/'),
+ (6,'nsd','Name Server Daemon (NSD)','www.nlnetlabs.nl/projects/nsd/'),
(7,'dynect','DynECT Standard DNS','dyn.com/managed-dns/'),
(8,'knot','Knot DNS','www.knot-dns.cz');
diff --git a/test-fixtures.js b/test-fixtures.js
index 8d599df..c852a44 100644
--- a/test-fixtures.js
+++ b/test-fixtures.js
@@ -26,9 +26,7 @@ switch (process.argv[2]) {
teardown()
break
default:
- console.log(
- `\nusage:\tnode ${path.basename(process.argv[1])} [ setup | teardown ]\n`,
- )
+ console.log(`\nusage:\tnode ${path.basename(process.argv[1])} [ setup | teardown ]\n`)
}
async function setup() {