@sdods/cli 0.5.2 → 0.6.0
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/dist/.tsbuildinfo +1 -1
- package/dist/commands/users.js +73 -5
- package/package.json +8 -8
package/dist/commands/users.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { SdodsError } from '@sdods/core';
|
|
2
2
|
import { MIN_PASSWORD_LENGTH } from '@sdods/contracts/names';
|
|
3
3
|
import { createContext } from '../context.js';
|
|
4
|
-
import { json, ok, table } from '../ui.js';
|
|
4
|
+
import { info, json, ok, table, warn } from '../ui.js';
|
|
5
5
|
async function openDb() {
|
|
6
6
|
const db = await import('@sdods/db');
|
|
7
7
|
return db.openDb();
|
|
8
8
|
}
|
|
9
|
+
function assertPassword(password) {
|
|
10
|
+
if (String(password).length < MIN_PASSWORD_LENGTH)
|
|
11
|
+
throw new SdodsError('CONFIG_INVALID', `Password must be at least ${MIN_PASSWORD_LENGTH} characters.`, { exitCode: 2 });
|
|
12
|
+
}
|
|
9
13
|
export function register(program) {
|
|
10
14
|
const users = program
|
|
11
15
|
.command('users')
|
|
@@ -21,10 +25,7 @@ export function register(program) {
|
|
|
21
25
|
.option('--org-owner', 'grant organization owner on orgs without an owner')
|
|
22
26
|
.action(async (opts, cmd) => {
|
|
23
27
|
const ctx = createContext(cmd);
|
|
24
|
-
|
|
25
|
-
throw new SdodsError('CONFIG_INVALID', 'Password must be at least 8 characters.', {
|
|
26
|
-
exitCode: 2,
|
|
27
|
-
});
|
|
28
|
+
assertPassword(opts.password);
|
|
28
29
|
const adb = await openDb();
|
|
29
30
|
try {
|
|
30
31
|
const db = await import('@sdods/db');
|
|
@@ -132,6 +133,73 @@ export function register(program) {
|
|
|
132
133
|
await adb.close();
|
|
133
134
|
}
|
|
134
135
|
});
|
|
136
|
+
users
|
|
137
|
+
.command('set-password <username>')
|
|
138
|
+
.description('Set a password and sign the user out everywhere; --activate re-enables the account')
|
|
139
|
+
.requiredOption('--password <password>', `new password (min ${MIN_PASSWORD_LENGTH} chars)`)
|
|
140
|
+
.option('--activate', 're-enable a deactivated account')
|
|
141
|
+
.action(async (username, opts, cmd) => {
|
|
142
|
+
const ctx = createContext(cmd);
|
|
143
|
+
assertPassword(opts.password);
|
|
144
|
+
const adb = await openDb();
|
|
145
|
+
try {
|
|
146
|
+
const db = await import('@sdods/db');
|
|
147
|
+
const { hashPassword } = await import('@sdods/server');
|
|
148
|
+
const u = await db.getUserByUsername(adb.db, username);
|
|
149
|
+
if (!u)
|
|
150
|
+
throw new SdodsError('CONFIG_NOT_FOUND', `User ${username} not found.`, {
|
|
151
|
+
exitCode: 2,
|
|
152
|
+
});
|
|
153
|
+
await db.updateUser(adb.db, adb.driver, u.id, {
|
|
154
|
+
passwordHash: await hashPassword(opts.password),
|
|
155
|
+
...(opts.activate ? { active: true } : {}),
|
|
156
|
+
});
|
|
157
|
+
await db.deleteSessionsForUser(adb.db, u.id);
|
|
158
|
+
await db.audit(adb.db, {
|
|
159
|
+
actorType: 'cli',
|
|
160
|
+
action: 'user.password',
|
|
161
|
+
targetType: 'user',
|
|
162
|
+
targetId: u.id,
|
|
163
|
+
details: { username, activated: Boolean(opts.activate) },
|
|
164
|
+
});
|
|
165
|
+
const active = opts.activate ? true : u.active;
|
|
166
|
+
if (ctx.opts.json)
|
|
167
|
+
return json({ id: u.id, username, active });
|
|
168
|
+
ok(`Password set for ${username}; existing sessions signed out`);
|
|
169
|
+
if (!active)
|
|
170
|
+
warn(`${username} is deactivated; pass --activate to let them sign in`);
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
await adb.close();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
users
|
|
177
|
+
.command('reset')
|
|
178
|
+
.description('Remove every user, session, API token and membership; projects and runs stay (next serve offers /setup)')
|
|
179
|
+
.option('--yes', 'confirm')
|
|
180
|
+
.action(async (opts, cmd) => {
|
|
181
|
+
const ctx = createContext(cmd);
|
|
182
|
+
if (!opts.yes)
|
|
183
|
+
throw new SdodsError('NOT_SUPPORTED', 'users reset removes every user; pass --yes to confirm.', { exitCode: 2 });
|
|
184
|
+
const adb = await openDb();
|
|
185
|
+
try {
|
|
186
|
+
const db = await import('@sdods/db');
|
|
187
|
+
const removed = await db.deleteAllUsers(adb.db);
|
|
188
|
+
await db.audit(adb.db, {
|
|
189
|
+
actorType: 'cli',
|
|
190
|
+
action: 'users.reset',
|
|
191
|
+
targetType: 'user',
|
|
192
|
+
details: { removed },
|
|
193
|
+
});
|
|
194
|
+
if (ctx.opts.json)
|
|
195
|
+
return json({ removed });
|
|
196
|
+
ok(`Removed ${removed} user${removed === 1 ? '' : 's'}; projects, runs and schedules are kept`);
|
|
197
|
+
info('Restart `sdods serve` for a one-time /setup link, or run: sdods users create --admin --username <name> --password <pw>');
|
|
198
|
+
}
|
|
199
|
+
finally {
|
|
200
|
+
await adb.close();
|
|
201
|
+
}
|
|
202
|
+
});
|
|
135
203
|
users
|
|
136
204
|
.command('grant <username>')
|
|
137
205
|
.description('Grant a membership role: --org <slug> --role owner|admin|member, or --workspace <slug> --role admin|editor|viewer')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdods/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "SDODS command line: run, record, analyze, agents, MCP server, scheduler and the web server.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "SDODS <admin@sdods.com>",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"node": ">=22"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@sdods/contracts": "0.
|
|
27
|
-
"@sdods/core": "0.
|
|
26
|
+
"@sdods/contracts": "0.6.0",
|
|
27
|
+
"@sdods/core": "0.6.0",
|
|
28
28
|
"commander": "^15.0.0",
|
|
29
29
|
"execa": "^10.0.1",
|
|
30
30
|
"picocolors": "^1.1.1",
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"zod": "^4.5.4",
|
|
34
34
|
"@playwright/test": "^1.63.0",
|
|
35
35
|
"playwright-core": "^1.63.0",
|
|
36
|
-
"@sdods/integrations": "0.
|
|
37
|
-
"@sdods/mcp": "0.
|
|
38
|
-
"@sdods/agents": "0.
|
|
39
|
-
"@sdods/db": "0.
|
|
36
|
+
"@sdods/integrations": "0.6.0",
|
|
37
|
+
"@sdods/mcp": "0.6.0",
|
|
38
|
+
"@sdods/agents": "0.6.0",
|
|
39
|
+
"@sdods/db": "0.6.0",
|
|
40
40
|
"csv-parse": "^7.0.2",
|
|
41
|
-
"@sdods/server": "0.
|
|
41
|
+
"@sdods/server": "0.6.0"
|
|
42
42
|
},
|
|
43
43
|
"homepage": "https://sdods.com",
|
|
44
44
|
"bugs": {
|