From 86d97de6528671d3d6cbbf013a87fd92dce6ca64 Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Sun, 29 Mar 2026 17:55:42 -0700 Subject: [PATCH 1/5] chore(release): v0.8.9 - updates in sync with `api` and `server` --- .release | 2 +- CHANGELOG.md | 8 +++++++- CONTRIBUTORS.md | 4 ++-- lib/group.js | 18 ++++++++++++++++++ lib/nameserver.js | 34 +++++++++++++++++++++++++++++----- lib/session.js | 2 +- lib/user.js | 11 +++++++++++ lib/zone.js | 29 ++++++++++++++++++++++++++--- lib/zone_record.js | 4 +++- package.json | 4 ++-- 10 files changed, 100 insertions(+), 16 deletions(-) diff --git a/.release b/.release index 0d06b1c..6ad30e5 160000 --- a/.release +++ b/.release @@ -1 +1 @@ -Subproject commit 0d06b1cbb2a5ef38840cd3d2346842795dc72865 +Subproject commit 6ad30e5df5fc026b332bbae7a0a4dfd47baf5898 diff --git a/CHANGELOG.md b/CHANGELOG.md index 37c4966..270dd93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). ### Unreleased +### [0.8.9] - 2026-03-29 + +- + + ### [0.8.8] - 2026-03-25 - zone_rec: delete request has id in param @@ -108,7 +113,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). [0.5.0]: https://github.com/NicTool/validate/releases/tag/0.5.0 [0.6.0]: https://github.com/NicTool/validate/releases/tag/0.6.0 [0.6.1]: https://github.com/NicTool/validate/releases/tag/0.6.1 -[0.6.3]: https://github.com/NicTool/validate/releases/tag/v0.6.3 +[0.6.3]: https://github.com/NicTool/validate/releases/tag/0.6.3 [0.7.0]: https://github.com/NicTool/validate/releases/tag/0.7.0 [0.7.1]: https://github.com/NicTool/validate/releases/tag/v0.7.1 [0.7.2]: https://github.com/NicTool/validate/releases/tag/v0.7.2 @@ -122,3 +127,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). [0.8.5]: https://github.com/NicTool/validate/releases/tag/v0.8.5 [0.8.7]: https://github.com/NicTool/validate/releases/tag/v0.8.7 [0.8.8]: https://github.com/NicTool/validate/releases/tag/v0.8.8 +[0.8.9]: https://github.com/NicTool/validate/releases/tag/v0.8.9 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 158d764..0cf9761 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -2,8 +2,8 @@ This handcrafted artisanal software is brought to you by: -|
msimerson (27) | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +|
msimerson (28)| +| :---: | 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/group.js b/lib/group.js index b83329e..187bc51 100644 --- a/lib/group.js +++ b/lib/group.js @@ -48,6 +48,24 @@ export const GET_res = Joi.object({ meta: shared.meta, }) +export const GET_list_req = Joi.object({ + parent_gid: pid, + name: name, + deleted: Joi.boolean(), +}) + +export const GET_list_res = Joi.object({ + group: Joi.array().items( + Joi.object({ + id: pid, + name: name, + parent_gid: pid, + deleted: Joi.boolean(), + }), + ), + meta: shared.meta, +}) + export const POST = Joi.object({ id: id, name: name, diff --git a/lib/nameserver.js b/lib/nameserver.js index 2514ada..dce8a4d 100644 --- a/lib/nameserver.js +++ b/lib/nameserver.js @@ -45,17 +45,41 @@ export const v3 = Joi.object({ export const GET_req = Joi.object({ id: id, name: name, + gid: shared.uint32, deleted: Joi.boolean(), }) -export const GET_res = Joi.object({ - nameserver: Joi.array().items(v3), - meta: shared.meta, -}) - export const POST = v3 +export const PUT = Joi.object({ + name: name, + ttl: shared.ttl, + description: Joi.string().empty('').max(255), + address: shared.ipv4, + address6: shared.ipv6.empty(''), + remote_login: remote_login, + export: Joi.object({ + interval: shared.uint16, + serials: Joi.boolean(), + status: Joi.string().empty('').max(255), + type: type, + }), + deleted: Joi.boolean(), +}) + export const DELETE = Joi.object({ id: id, deleted: Joi.boolean(), }) + +// GET_res uses a looser name check so records with legacy/missing trailing dots +// don't fail the entire response. +const v3_out = v3 + .fork(['name'], () => Joi.string().min(1).max(255).allow('')) + .fork(['address'], () => shared.ipv4.allow('').optional()) + .fork(['gid', 'ttl'], (s) => s.optional()) + +export const GET_res = Joi.object({ + nameserver: Joi.array().items(v3_out), + meta: shared.meta, +}) diff --git a/lib/session.js b/lib/session.js index bc4336d..a20d93b 100644 --- a/lib/session.js +++ b/lib/session.js @@ -8,7 +8,7 @@ export const id = shared.uint32 export const POST = Joi.object({ username: user.username.required(), - password: user.password.required(), + password: Joi.string().min(1).required(), }) export const GET_res = Joi.object({ diff --git a/lib/user.js b/lib/user.js index 5f415a5..f7186b8 100644 --- a/lib/user.js +++ b/lib/user.js @@ -34,6 +34,7 @@ export const v3 = Joi.object({ export const GET_req = Joi.object({ id: id, + gid: group.id, deleted: Joi.boolean(), }) @@ -57,6 +58,16 @@ export const POST = Joi.object({ is_admin: Joi.boolean(), }) +export const PUT = Joi.object({ + first_name: Joi.string().min(1), + last_name: Joi.string().min(1), + username: username, + email: email, + password: password, + is_admin: Joi.boolean(), + deleted: Joi.boolean(), +}) + export const DELETE = Joi.object({ id: id, }) diff --git a/lib/zone.js b/lib/zone.js index 402ac3a..2873b81 100644 --- a/lib/zone.js +++ b/lib/zone.js @@ -8,7 +8,7 @@ export const zone = Joi.string().min(3).max(255) // .domain({ allowFullyQualified: true, allowUnderscore: true, tlds: false }) export const v3 = Joi.object({ - id: id, + id, gid: shared.uint32.required(), @@ -41,6 +41,7 @@ export const v3 = Joi.object({ export const GET_req = Joi.object({ id: id, + gid: shared.uint32, zone: zone, search: Joi.string().max(255).allow(''), zone_like: Joi.string().max(255).allow(''), @@ -50,16 +51,38 @@ export const GET_req = Joi.object({ sort_by: Joi.string().valid('id', 'zone', 'description', 'last_modified'), sort_dir: Joi.string().lowercase().valid('asc', 'desc'), deleted: Joi.boolean(), +}).options({ allowUnknown: true }) + +export const GET_ns_res = Joi.object({ + ns: Joi.array().items( + Joi.object({ + owner: Joi.string().required(), + ttl: shared.ttl.required(), + dname: Joi.string().required(), + }), + ), + meta: shared.meta, }) export const GET_res = Joi.object({ zone: Joi.array().items(v3), meta: shared.meta, + deleted: Joi.boolean(), }) export const POST = v3 -export const DELETE = Joi.object({ - id: id, +export const PUT = Joi.object({ + description: Joi.string().empty('').allow(null), + mailaddr: Joi.string().empty('').allow(null), + ttl: shared.ttl, + refresh: shared.int32, + retry: shared.int32, + expire: shared.int32, + minimum: shared.int32, deleted: Joi.boolean(), }) + +export const DELETE = Joi.object({ + id, +}) diff --git a/lib/zone_record.js b/lib/zone_record.js index 99516b7..d5be903 100644 --- a/lib/zone_record.js +++ b/lib/zone_record.js @@ -227,7 +227,7 @@ export const GET_req = Joi.object({ id: shared.uint32, zid: shared.uint32, deleted: Joi.boolean(), -}) +}).options({ allowUnknown: true }) export const GET_res = Joi.object({ zone_record: Joi.array().items(v3), @@ -236,6 +236,8 @@ export const GET_res = Joi.object({ export const POST = v3.fork(['id', 'ttl'], (schema) => schema.optional()) +export const PUT = v3.fork(['id', 'zid', 'owner', 'ttl', 'type'], (schema) => schema.optional()) + export const DELETE = Joi.object({ deleted: Joi.boolean(), }) diff --git a/package.json b/package.json index 1e4acb3..728dd07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nictool/validate", - "version": "0.8.8", + "version": "0.8.9", "description": "NicTool Object Validation", "type": "module", "files": [ @@ -63,4 +63,4 @@ "trailingComma": "all", "printWidth": 100 } -} +} \ No newline at end of file From d19e78eb82ba59d4565ff585b39cda699dd1aa4c Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Sun, 29 Mar 2026 21:28:21 -0700 Subject: [PATCH 2/5] adding permission objects --- lib/group.js | 27 +++++++++++++++++++++------ lib/permission.js | 10 +++++----- lib/user.js | 6 ++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/lib/group.js b/lib/group.js index 187bc51..e740572 100644 --- a/lib/group.js +++ b/lib/group.js @@ -20,6 +20,7 @@ export const v3 = Joi.object({ deleted: Joi.boolean(), has_children: Joi.boolean(), permission: permission.v3, + usable_ns: Joi.array().items(shared.uint32), }) // legacy group format @@ -36,15 +37,19 @@ export const GET_req = Joi.object({ id: pid, name: name, deleted: Joi.boolean(), + include_subgroups: Joi.boolean(), }) export const GET_res = Joi.object({ - group: Joi.object({ - id: pid, - name: name, - parent_gid: pid, - deleted: Joi.boolean(), - }), + group: Joi.array().items( + Joi.object({ + id: pid, + name: name, + parent_gid: pid, + deleted: Joi.boolean(), + permissions: permission.v3, + }), + ), meta: shared.meta, }) @@ -52,6 +57,7 @@ export const GET_list_req = Joi.object({ parent_gid: pid, name: name, deleted: Joi.boolean(), + include_subgroups: Joi.boolean(), }) export const GET_list_res = Joi.object({ @@ -61,6 +67,7 @@ export const GET_list_res = Joi.object({ name: name, parent_gid: pid, deleted: Joi.boolean(), + permissions: permission.v3, }), ), meta: shared.meta, @@ -71,6 +78,14 @@ export const POST = Joi.object({ name: name, parent_gid: pid, deleted: Joi.boolean(), + usable_ns: Joi.array().items(shared.uint32), +}) + +export const PUT = Joi.object({ + name: name, + parent_gid: pid, + deleted: Joi.boolean(), + usable_ns: Joi.array().items(shared.uint32), }) export const DELETE = Joi.object({ diff --git a/lib/permission.js b/lib/permission.js index e08a2e4..b321264 100644 --- a/lib/permission.js +++ b/lib/permission.js @@ -2,12 +2,12 @@ import Joi from 'joi' import * as shared from './shared.js' -export const id = Joi.number().integer().min(1).max(4294967295) +export const id = Joi.number().integer().min(0).max(4294967295) export const v3 = Joi.object({ id: id, - name: Joi.string().empty(''), - inherit: Joi.boolean(), + name: Joi.string().allow('', null), + inherit: Joi.boolean().allow(null), self_write: Joi.boolean(), deleted: Joi.boolean(), group: Joi.object({ @@ -17,13 +17,13 @@ export const v3 = Joi.object({ delete: Joi.boolean(), }), user: Joi.object({ - id: id, + id: id.allow(null), write: Joi.boolean(), create: Joi.boolean(), delete: Joi.boolean(), }), nameserver: Joi.object({ - usable: Joi.array().items(Joi.number().integer().positive()), + usable: Joi.array().items(Joi.number().integer().min(0)), write: Joi.boolean(), create: Joi.boolean(), delete: Joi.boolean(), diff --git a/lib/user.js b/lib/user.js index f7186b8..91d8cc1 100644 --- a/lib/user.js +++ b/lib/user.js @@ -4,6 +4,7 @@ const JoiPassword = Joi.extend(joiPasswordExtendCore) import * as shared from './shared.js' import * as group from './group.js' +import * as permission from './permission.js' export const id = Joi.number().integer().min(1).max(4294967295) @@ -30,12 +31,15 @@ export const v3 = Joi.object({ password: password, is_admin: Joi.boolean(), deleted: Joi.boolean(), + permissions: permission.v3, + inherit_group_permissions: Joi.boolean(), }) export const GET_req = Joi.object({ id: id, gid: group.id, deleted: Joi.boolean(), + include_subgroups: Joi.boolean(), }) export const GET_res = Joi.object({ @@ -56,6 +60,7 @@ export const POST = Joi.object({ email: email, password: password, is_admin: Joi.boolean(), + inherit_group_permissions: Joi.boolean(), }) export const PUT = Joi.object({ @@ -66,6 +71,7 @@ export const PUT = Joi.object({ password: password, is_admin: Joi.boolean(), deleted: Joi.boolean(), + inherit_group_permissions: Joi.boolean(), }) export const DELETE = Joi.object({ From 5d1d2f3fb88852a5399266ab5da13638640f9735 Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Tue, 7 Apr 2026 23:22:06 -0700 Subject: [PATCH 3/5] group: single or list --- lib/group.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/group.js b/lib/group.js index e740572..0e2e3cd 100644 --- a/lib/group.js +++ b/lib/group.js @@ -40,16 +40,16 @@ export const GET_req = Joi.object({ include_subgroups: Joi.boolean(), }) +const groupItem = Joi.object({ + id: pid, + name: name, + parent_gid: pid, + deleted: Joi.boolean(), + permissions: permission.v3, +}) + export const GET_res = Joi.object({ - group: Joi.array().items( - Joi.object({ - id: pid, - name: name, - parent_gid: pid, - deleted: Joi.boolean(), - permissions: permission.v3, - }), - ), + group: Joi.alternatives().try(groupItem, Joi.array().items(groupItem)), meta: shared.meta, }) From 332d8cddd109c7de0d44373ca0166e6fde42866c Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Tue, 7 Apr 2026 23:22:14 -0700 Subject: [PATCH 4/5] chore: format --- CHANGELOG.md | 3 +-- CONTRIBUTORS.md | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 270dd93..2cbcf62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). ### [0.8.9] - 2026-03-29 -- - +- ### [0.8.8] - 2026-03-25 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0cf9761..6fd2b97 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -2,8 +2,8 @@ This handcrafted artisanal software is brought to you by: -|
msimerson (28)| -| :---: | +|
msimerson (28) | +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | 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/package.json b/package.json index 728dd07..301bf29 100644 --- a/package.json +++ b/package.json @@ -63,4 +63,4 @@ "trailingComma": "all", "printWidth": 100 } -} \ No newline at end of file +} From 827f18adb80339227641b0e6a155f2f9f9382fbe Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Tue, 7 Apr 2026 23:33:59 -0700 Subject: [PATCH 5/5] update changelog --- CHANGELOG.md | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cbcf62..736616c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). ### [0.8.9] - 2026-03-29 -- +- group: GET can return one group or array +- PUT added to: group, ns, user, zone, zr ### [0.8.8] - 2026-03-25 diff --git a/package.json b/package.json index 301bf29..20ac64c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "scripts": { "format:check": "npm run prettier; npm run lint", - "format": "npm run prettier -- --write && npm run lint --fix", + "format": "npm run prettier -- --write && npm run lint:fix", "lint": "npx eslint .", "lint:fix": "npx eslint --fix .", "prettier": "npx prettier --ignore-path .gitignore --check .",