nsauditor-ai 0.1.72 → 0.1.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.mjs +79 -1
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -1038,6 +1038,84 @@ Docs: https://www.nsauditor.com/ai/ | Pricing: https://www.nsauditor.com/ai/
|
|
|
1038
1038
|
console.log('── Installation provenance ──');
|
|
1039
1039
|
console.log(` nsauditor-ai (CE): ${ceVersion}`);
|
|
1040
1040
|
console.log(` @nsasoft/nsauditor-ai-ee (EE): ${eeVersion}`);
|
|
1041
|
+
} else if (rawArgs.includes('--reset')) {
|
|
1042
|
+
// CE-0.1.73 — atomic dual-channel license-state reset for macOS
|
|
1043
|
+
// license-rotation flow. Discovered EE 0.11.0 first-install
|
|
1044
|
+
// rehearsal (2026-05-23): customer rotates EE license, gets
|
|
1045
|
+
// `license_id_mismatch` because the persisted licenseId binding
|
|
1046
|
+
// (from a prior install) doesn't match the new JWT's licenseId.
|
|
1047
|
+
//
|
|
1048
|
+
// Single-surface clearing ("rm ~/.nsauditor/license-state.json")
|
|
1049
|
+
// is a HALF-fix on macOS — _readLicenseState (license.mjs:402-434)
|
|
1050
|
+
// ALSO reads from Keychain NSAUDITOR_LICENSE_ID, and Keychain wins
|
|
1051
|
+
// on read (license.mjs:429: `state.licenseId = kcId; // Keychain
|
|
1052
|
+
// wins`). Customer must additionally run
|
|
1053
|
+
// `security delete-generic-password -s nsauditor-ai -a
|
|
1054
|
+
// NSAUDITOR_LICENSE_ID` for the replay-defense check
|
|
1055
|
+
// (license.mjs:664-670) to pass. This subcommand does both
|
|
1056
|
+
// atomically so customers don't have to run cryptic `security`
|
|
1057
|
+
// commands blind from a support email.
|
|
1058
|
+
//
|
|
1059
|
+
// Default: preserves NSAUDITOR_LICENSE_KEY (the JWT itself) for
|
|
1060
|
+
// immediate re-activation on next license check. --purge also
|
|
1061
|
+
// removes the JWT (forces full re-install with `license install`).
|
|
1062
|
+
const purge = rawArgs.includes('--purge');
|
|
1063
|
+
const { _getLicenseStateFilePath } = await import('./utils/license.mjs');
|
|
1064
|
+
const { keychainDelete } = await import('./utils/keychain.mjs');
|
|
1065
|
+
const fsp = await import('fs/promises');
|
|
1066
|
+
|
|
1067
|
+
const cleared = { stateFile: false, keychainId: false, jwtPurged: false };
|
|
1068
|
+
|
|
1069
|
+
// 1. Delete license-state.json (cross-platform path resolver).
|
|
1070
|
+
const statePath = _getLicenseStateFilePath();
|
|
1071
|
+
try {
|
|
1072
|
+
await fsp.unlink(statePath);
|
|
1073
|
+
cleared.stateFile = true;
|
|
1074
|
+
} catch (e) {
|
|
1075
|
+
if (e && e.code !== 'ENOENT') {
|
|
1076
|
+
console.warn(`⚠ Could not delete ${statePath}: ${e.message}`);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
// 2. Delete macOS Keychain NSAUDITOR_LICENSE_ID entry. Linux /
|
|
1081
|
+
// Windows have no Keychain side-channel — file delete is
|
|
1082
|
+
// sufficient there.
|
|
1083
|
+
if (process.platform === 'darwin') {
|
|
1084
|
+
try {
|
|
1085
|
+
cleared.keychainId = await keychainDelete('NSAUDITOR_LICENSE_ID');
|
|
1086
|
+
} catch { /* not fatal — file delete is the primary surface */ }
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// 3. Optionally purge the JWT itself (forces full re-install).
|
|
1090
|
+
// Darwin-only for now; file-based JWT purge on Linux/Windows
|
|
1091
|
+
// requires editing ~/.nsauditor/.env which we leave to the
|
|
1092
|
+
// operator (deleting the file would also remove unrelated env
|
|
1093
|
+
// vars the operator may have placed there).
|
|
1094
|
+
if (purge && process.platform === 'darwin') {
|
|
1095
|
+
try {
|
|
1096
|
+
cleared.jwtPurged = await keychainDelete('NSAUDITOR_LICENSE_KEY');
|
|
1097
|
+
} catch { /* not fatal */ }
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
console.log('✓ License state reset');
|
|
1101
|
+
console.log(` License state file: ${cleared.stateFile ? 'deleted (' + statePath + ')' : 'not found (already clean)'}`);
|
|
1102
|
+
if (process.platform === 'darwin') {
|
|
1103
|
+
console.log(` Keychain NSAUDITOR_LICENSE_ID: ${cleared.keychainId ? 'deleted' : 'not found (already clean)'}`);
|
|
1104
|
+
}
|
|
1105
|
+
if (purge) {
|
|
1106
|
+
if (process.platform === 'darwin') {
|
|
1107
|
+
console.log(` Keychain NSAUDITOR_LICENSE_KEY (JWT): ${cleared.jwtPurged ? 'purged' : 'not found (already clean)'}`);
|
|
1108
|
+
} else {
|
|
1109
|
+
console.log(' JWT (NSAUDITOR_LICENSE_KEY): file-based JWT not purged on this platform — remove the NSAUDITOR_LICENSE_KEY line manually from ~/.nsauditor/.env if needed.');
|
|
1110
|
+
}
|
|
1111
|
+
console.log('');
|
|
1112
|
+
console.log(' Re-install with: nsauditor-ai license install <KEY>');
|
|
1113
|
+
} else {
|
|
1114
|
+
console.log(' JWT (NSAUDITOR_LICENSE_KEY): preserved (default) — next license check will re-bind.');
|
|
1115
|
+
console.log('');
|
|
1116
|
+
console.log(' Verify with: nsauditor-ai license --status');
|
|
1117
|
+
console.log(' (Add --purge to additionally clear the JWT for full uninstall.)');
|
|
1118
|
+
}
|
|
1041
1119
|
} else if (rawArgs.includes('install')) {
|
|
1042
1120
|
// CE-0.1.30.4 — install command. Verify the JWT FIRST, then persist
|
|
1043
1121
|
// to a platform-appropriate location (macOS Keychain / file).
|
|
@@ -1099,7 +1177,7 @@ Docs: https://www.nsauditor.com/ai/ | Pricing: https://www.nsauditor.com/ai/
|
|
|
1099
1177
|
console.log('');
|
|
1100
1178
|
console.log(' Verify with: nsauditor-ai license --status');
|
|
1101
1179
|
} else {
|
|
1102
|
-
console.log('Usage: nsauditor-ai license --status | --capabilities | --plugins | install <KEY>');
|
|
1180
|
+
console.log('Usage: nsauditor-ai license --status | --capabilities | --plugins | install <KEY> | --reset [--purge]');
|
|
1103
1181
|
}
|
|
1104
1182
|
process.exit(0);
|
|
1105
1183
|
}
|