@axium/server 0.44.0 → 0.44.2
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/{cli.d.ts → cli/common.d.ts} +1 -1
- package/dist/{cli.js → cli/common.js} +2 -2
- package/dist/cli/config.d.ts +1 -0
- package/dist/cli/config.js +69 -0
- package/dist/{db/cli.js → cli/db.js} +10 -32
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +303 -0
- package/dist/cli/plugins.d.ts +1 -0
- package/dist/cli/plugins.js +148 -0
- package/dist/cli/user.d.ts +1 -0
- package/dist/cli/user.js +102 -0
- package/dist/io.d.ts +1 -1
- package/dist/io.js +9 -4
- package/dist/linking.d.ts +1 -2
- package/dist/main.d.ts +2 -1
- package/dist/main.js +6 -584
- package/package.json +4 -3
- package/patches/patch.js +12 -0
- package/routes/admin/+page.svelte +2 -2
- package/routes/admin/plugins/+page.svelte +2 -2
- /package/dist/{db/cli.d.ts → cli/db.d.ts} +0 -0
package/dist/cli/user.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { formatDateRange } from '@axium/core/format';
|
|
2
|
+
import { Argument, Option, program } from 'commander';
|
|
3
|
+
import * as io from 'ioium/node';
|
|
4
|
+
import { styleText } from 'node:util';
|
|
5
|
+
import * as z from 'zod';
|
|
6
|
+
import { audit } from '../audit.js';
|
|
7
|
+
import { diffUpdate, lookupUser, rl, userText } from './common.js';
|
|
8
|
+
import config from '../config.js';
|
|
9
|
+
import * as db from '../db/index.js';
|
|
10
|
+
const argUserLookup = new Argument('<user>', 'the UUID or email of the user to operate on').argParser(lookupUser);
|
|
11
|
+
program
|
|
12
|
+
.command('user')
|
|
13
|
+
.description('Get or change information about a user')
|
|
14
|
+
.addArgument(argUserLookup)
|
|
15
|
+
.option('-S, --sessions', 'show user sessions')
|
|
16
|
+
.option('-P, --passkeys', 'show user passkeys')
|
|
17
|
+
.option('--add-role <role...>', 'add roles to the user')
|
|
18
|
+
.option('--remove-role <role...>', 'remove roles from the user')
|
|
19
|
+
.option('--tag <tag...>', 'Add tags to the user')
|
|
20
|
+
.option('--untag <tag...>', 'Remove tags from the user')
|
|
21
|
+
.option('--delete', 'Delete the user')
|
|
22
|
+
.option('--suspend', 'Suspend the user')
|
|
23
|
+
.addOption(new Option('--unsuspend', 'Un-suspend the user').conflicts('suspend'))
|
|
24
|
+
.action(async (_user, opt) => {
|
|
25
|
+
let user = await _user;
|
|
26
|
+
const [updatedRoles, roles, rolesDiff] = diffUpdate(user.roles, opt.addRole, opt.removeRole);
|
|
27
|
+
const [updatedTags, tags, tagsDiff] = diffUpdate(user.tags, opt.tag, opt.untag);
|
|
28
|
+
const changeSuspend = (opt.suspend || opt.unsuspend) && user.isSuspended != (opt.suspend ?? !opt.unsuspend);
|
|
29
|
+
if (updatedRoles || updatedTags || changeSuspend) {
|
|
30
|
+
user = await db.database
|
|
31
|
+
.updateTable('users')
|
|
32
|
+
.where('id', '=', user.id)
|
|
33
|
+
.set({ roles, tags, isSuspended: !changeSuspend ? user.isSuspended : (opt.suspend ?? !opt.unsuspend) })
|
|
34
|
+
.returningAll()
|
|
35
|
+
.executeTakeFirstOrThrow()
|
|
36
|
+
.then(u => {
|
|
37
|
+
if (updatedRoles && rolesDiff)
|
|
38
|
+
console.log(`> Updated roles: ${rolesDiff}`);
|
|
39
|
+
if (updatedTags && tagsDiff)
|
|
40
|
+
console.log(`> Updated tags: ${tagsDiff}`);
|
|
41
|
+
if (changeSuspend)
|
|
42
|
+
console.log(opt.suspend ? '> Suspended' : '> Un-suspended');
|
|
43
|
+
return u;
|
|
44
|
+
})
|
|
45
|
+
.catch(e => io.exit('Failed to update user: ' + e.message));
|
|
46
|
+
}
|
|
47
|
+
if (opt.delete) {
|
|
48
|
+
const confirmed = await rl
|
|
49
|
+
.question(`Are you sure you want to delete ${userText(user, true)}? (y/N) `)
|
|
50
|
+
.then(v => z.stringbool().parseAsync(v))
|
|
51
|
+
.catch(() => false);
|
|
52
|
+
if (!confirmed)
|
|
53
|
+
console.log(styleText('dim', '> Delete aborted.'));
|
|
54
|
+
else
|
|
55
|
+
await db.database
|
|
56
|
+
.deleteFrom('users')
|
|
57
|
+
.where('id', '=', user.id)
|
|
58
|
+
.executeTakeFirstOrThrow()
|
|
59
|
+
.then(() => console.log(styleText(['red', 'bold'], '> Deleted')))
|
|
60
|
+
.catch(e => io.exit('Failed to delete user: ' + e.message));
|
|
61
|
+
}
|
|
62
|
+
console.log([
|
|
63
|
+
user.isSuspended && styleText('yellowBright', 'Suspended'),
|
|
64
|
+
user.isAdmin && styleText('redBright', 'Administrator'),
|
|
65
|
+
'UUID: ' + user.id,
|
|
66
|
+
'Name: ' + user.name,
|
|
67
|
+
`Email: ${user.email}, ${user.emailVerified ? 'verified on ' + formatDateRange(user.emailVerified) : styleText(config.auth.email_verification ? 'yellow' : 'dim', 'not verified')}`,
|
|
68
|
+
'Registered ' + formatDateRange(user.registeredAt),
|
|
69
|
+
`Roles: ${user.roles.length ? user.roles.join(', ') : styleText('dim', '(none)')}`,
|
|
70
|
+
`Tags: ${user.tags.length ? user.tags.join(', ') : styleText('dim', '(none)')}`,
|
|
71
|
+
]
|
|
72
|
+
.filter(v => v)
|
|
73
|
+
.join('\n'));
|
|
74
|
+
if (opt.sessions) {
|
|
75
|
+
const sessions = await db.database.selectFrom('sessions').where('userId', '=', user.id).selectAll().execute();
|
|
76
|
+
console.log(styleText('bold', 'Sessions:'));
|
|
77
|
+
if (!sessions.length)
|
|
78
|
+
console.log(styleText('dim', '(none)'));
|
|
79
|
+
else
|
|
80
|
+
for (const session of sessions) {
|
|
81
|
+
console.log(`\t${session.id}\tcreated ${formatDateRange(session.created).padEnd(40)}\texpires ${formatDateRange(session.expires).padEnd(40)}\t${session.elevated ? styleText('yellow', '(elevated)') : ''}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (opt.passkeys) {
|
|
85
|
+
const passkeys = await db.database.selectFrom('passkeys').where('userId', '=', user.id).selectAll().execute();
|
|
86
|
+
console.log(styleText('bold', 'Passkeys:'));
|
|
87
|
+
for (const passkey of passkeys) {
|
|
88
|
+
console.log(`\t${passkey.id}: created ${formatDateRange(passkey.createdAt).padEnd(40)} used ${passkey.counter} times. ${passkey.deviceType}, ${passkey.backedUp ? '' : 'not '}backed up; transports are [${passkey.transports.join(', ')}], ${passkey.name ? 'named ' + JSON.stringify(passkey.name) : 'unnamed'}.`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
program
|
|
93
|
+
.command('toggle-admin')
|
|
94
|
+
.description('Toggle whether a user is an administrator')
|
|
95
|
+
.addArgument(argUserLookup)
|
|
96
|
+
.action(async (_user) => {
|
|
97
|
+
const user = await _user;
|
|
98
|
+
const isAdmin = !user.isAdmin;
|
|
99
|
+
await db.database.updateTable('users').set({ isAdmin }).where('id', '=', user.id).executeTakeFirstOrThrow();
|
|
100
|
+
await audit('admin_change', undefined, { user: user.id });
|
|
101
|
+
console.log(`${userText(user)} is ${isAdmin ? 'now' : 'no longer'} an administrator. (${styleText(['whiteBright', 'bold'], isAdmin.toString())})`);
|
|
102
|
+
});
|
package/dist/io.d.ts
CHANGED
package/dist/io.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as io from 'ioium/node';
|
|
2
|
+
import { fetchPackageMetadata } from '@axium/core/packages';
|
|
2
3
|
import { getVersionInfo } from '@axium/core/node/packages';
|
|
3
4
|
import { plugins } from '@axium/core/plugins';
|
|
4
5
|
import { Logger } from 'logzen';
|
|
5
6
|
import * as fs from 'node:fs';
|
|
6
7
|
import { dirname, join, resolve } from 'node:path/posix';
|
|
7
8
|
import { _unique } from './state.js';
|
|
9
|
+
import { pick } from 'utilium';
|
|
8
10
|
export const systemDir = '/etc/axium';
|
|
9
11
|
export const dirs = _unique('dirs', [systemDir]);
|
|
10
12
|
for (let dir = resolve(process.cwd()); dir !== '/'; dir = dirname(dir)) {
|
|
@@ -81,9 +83,12 @@ export async function restrictedPorts(opt) {
|
|
|
81
83
|
}
|
|
82
84
|
export async function getAllVersions() {
|
|
83
85
|
return await Array.fromAsync([
|
|
84
|
-
...plugins.values().map(p =>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
...plugins.values().map(async (p) => ({
|
|
87
|
+
...pick(p, 'name', 'version'),
|
|
88
|
+
latest: (p.update_checks ? await fetchPackageMetadata(p.name) : null)?._latest,
|
|
89
|
+
})),
|
|
90
|
+
getVersionInfo('@axium/server', import.meta.dirname),
|
|
91
|
+
getVersionInfo('@axium/core', import.meta.dirname),
|
|
92
|
+
getVersionInfo('@axium/client', import.meta.dirname),
|
|
88
93
|
]);
|
|
89
94
|
}
|
package/dist/linking.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
interface LinkInfo {
|
|
1
|
+
export interface LinkInfo {
|
|
2
2
|
id: string;
|
|
3
3
|
from: string;
|
|
4
4
|
to: string;
|
|
@@ -13,4 +13,3 @@ export declare function listRouteLinks(options?: LinkOptions): Generator<LinkInf
|
|
|
13
13
|
export declare function linkRoutes(options?: LinkOptions): void;
|
|
14
14
|
export declare function writePluginHooks(): void;
|
|
15
15
|
export declare function unlinkRoutes(options?: LinkOptions): void;
|
|
16
|
-
export {};
|
package/dist/main.d.ts
CHANGED