Skip to content

2.0.0: error-contract fixes, callback bugs, non-root import - #30

Merged
wmantly merged 2 commits into
masterfrom
2.0.0-fixes
Jul 18, 2026
Merged

wmantly merged 2 commits into
masterfrom
2.0.0-fixes

Conversation

@wmantly

@wmantly wmantly commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

Bug-fix + feature release. Breaking error-contract change, plus a new read-only (non-root) import path. Bumps version to 2.0.0.

Breaking

  • spawnWrapper now returns Error | null (was stderr/true) and fires the callback at most once.
  • removeUser / addUserToGroup pass Error | null instead of the raw numeric exit code.
  • addUser / addGroup propagate errors and no longer invoke the callback a second time.

Fixed

  • addUser no longer swallows the useradd error or double-calls its callback.
  • addSSHtoUser no longer crashes (Cannot read properties of null) on a missing user; uses spawn with arg arrays instead of a shell exec string, removing homedir injection risk.
  • getExpiration returns the error instead of throwing when chage fails; parses under the C locale and is not index/order-dependent.
  • setPassword reports a non-zero exit instead of silently succeeding.
  • build_user_command no longer injects null argv entries.
  • getUsers / getGroups no longer drop the last record when the file has no trailing newline.
  • promise() no longer hangs on the synchronous validateUsername.

Added

  • require('linux-user/non-root') — read-only subset that does not require root and emits no root warning. Also available as require('linux-user').nonRoot.
  • Read-only promise set via promise.nonRoot().
  • Optional spawn timeout support (opts.timeout).
  • Types: selinux_user → string, other_args → string | string[], plus nonRoot/promise typings.

Tests

  • Root-dependent tests now auto-skip when not running as root.
  • Full suite verified: 28 passing as root, 19 passing / 9 pending (skipped) as non-root.
  • npm run lint clean.

See CHANGELOG.md for the full list.

🤖 Generated with Claude Code

Breaking: spawnWrapper now returns Error|null (was stderr/true) and fires the
callback at most once; removeUser/addUserToGroup pass Error|null instead of the
raw exit code. addUser/addGroup propagate errors and no longer call back twice.
addSSHtoUser no longer crashes on a missing user and uses spawn (no shell exec)
to avoid homedir injection. getExpiration returns the error instead of throwing
and parses chage output under the C locale. setPassword reports non-zero exits.
build_user_command no longer injects null argv. getUsers/getGroups no longer
drop the last record without a trailing newline. promise() no longer hangs on
the synchronous validateUsername.

Added: require('linux-user/non-root') read-only subset (no root warning), read-
only promise set (promise.nonRoot()), and optional spawn timeout support.

Types: selinux_user -> string, other_args -> string|string[], plus nonRoot and
promise typings.

Tests now auto-skip root-dependent cases when not running as root.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@wmantly
wmantly merged commit 281f5bb into master Jul 18, 2026
2 checks passed
@wmantly
wmantly deleted the 2.0.0-fixes branch July 18, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant