@axium/server 0.8.0 → 0.9.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/auth.d.ts +0 -10
- package/dist/auth.js +8 -16
- package/dist/cli.js +145 -38
- package/dist/config.d.ts +39 -474
- package/dist/config.js +53 -43
- package/dist/database.d.ts +3 -3
- package/dist/database.js +53 -24
- package/dist/plugins.d.ts +1 -0
- package/dist/plugins.js +1 -0
- package/package.json +10 -7
- package/web/api/metadata.ts +3 -3
- package/web/api/passkeys.ts +3 -3
- package/web/api/register.ts +4 -4
- package/web/api/session.ts +2 -2
- package/web/api/users.ts +29 -18
- package/web/api/utils.ts +2 -2
- package/web/hooks.server.ts +8 -2
- package/web/lib/ClipboardCopy.svelte +42 -0
- package/web/lib/FormDialog.svelte +9 -1
- package/web/lib/auth.ts +2 -2
- package/web/lib/icons/Icon.svelte +2 -6
- package/web/lib/styles.css +7 -1
- package/web/routes/[...path]/+page.server.ts +1 -1
- package/web/routes/[appId]/[...page]/+page.server.ts +1 -1
- package/web/routes/account/+page.svelte +115 -48
- package/web/routes/api/[...path]/+server.ts +2 -2
package/dist/auth.d.ts
CHANGED
|
@@ -30,23 +30,13 @@ export declare function updateUser({ id, ...user }: UserInternal): Promise<{
|
|
|
30
30
|
}>;
|
|
31
31
|
export interface SessionInternal extends Session {
|
|
32
32
|
token: string;
|
|
33
|
-
elevated: boolean;
|
|
34
33
|
}
|
|
35
34
|
export declare function createSession(userId: string, elevated?: boolean): Promise<SessionInternal>;
|
|
36
|
-
export declare function checkExpiration(session: SessionInternal): Promise<void>;
|
|
37
35
|
export declare function getSessionAndUser(token: string): Promise<SessionInternal & {
|
|
38
36
|
user: UserInternal | null;
|
|
39
37
|
}>;
|
|
40
38
|
export declare function getSession(sessionId: string): Promise<SessionInternal>;
|
|
41
39
|
export declare function getSessions(userId: string): Promise<SessionInternal[]>;
|
|
42
|
-
export declare function updateSession(session: SessionInternal): Promise<{
|
|
43
|
-
id: string;
|
|
44
|
-
expires: Date;
|
|
45
|
-
token: string;
|
|
46
|
-
userId: string;
|
|
47
|
-
created: Date;
|
|
48
|
-
elevated: boolean;
|
|
49
|
-
}>;
|
|
50
40
|
export type VerificationRole = 'verify_email' | 'login';
|
|
51
41
|
export interface VerificationInternal extends Verification {
|
|
52
42
|
token: string;
|
package/dist/auth.js
CHANGED
|
@@ -35,12 +35,6 @@ export async function createSession(userId, elevated = false) {
|
|
|
35
35
|
await db.insertInto('sessions').values(session).execute();
|
|
36
36
|
return session;
|
|
37
37
|
}
|
|
38
|
-
export async function checkExpiration(session) {
|
|
39
|
-
if (session.expires.getTime() > Date.now())
|
|
40
|
-
return;
|
|
41
|
-
await db.deleteFrom('sessions').where('sessions.id', '=', session.id).executeTakeFirstOrThrow();
|
|
42
|
-
throw new Error('Session expired');
|
|
43
|
-
}
|
|
44
38
|
export async function getSessionAndUser(token) {
|
|
45
39
|
connect();
|
|
46
40
|
const result = await db
|
|
@@ -48,26 +42,24 @@ export async function getSessionAndUser(token) {
|
|
|
48
42
|
.selectAll()
|
|
49
43
|
.select(eb => jsonObjectFrom(eb.selectFrom('users').selectAll().whereRef('users.id', '=', 'sessions.userId')).as('user'))
|
|
50
44
|
.where('sessions.token', '=', token)
|
|
45
|
+
.where('sessions.expires', '>', new Date())
|
|
51
46
|
.executeTakeFirst();
|
|
52
47
|
if (!result)
|
|
53
48
|
throw new Error('Session not found');
|
|
54
|
-
await checkExpiration(result);
|
|
55
49
|
return result;
|
|
56
50
|
}
|
|
57
51
|
export async function getSession(sessionId) {
|
|
58
52
|
connect();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
return await db
|
|
54
|
+
.selectFrom('sessions')
|
|
55
|
+
.selectAll()
|
|
56
|
+
.where('id', '=', sessionId)
|
|
57
|
+
.where('sessions.expires', '>', new Date())
|
|
58
|
+
.executeTakeFirstOrThrow();
|
|
62
59
|
}
|
|
63
60
|
export async function getSessions(userId) {
|
|
64
61
|
connect();
|
|
65
|
-
return await db.selectFrom('sessions').selectAll().where('userId', '=', userId).execute();
|
|
66
|
-
}
|
|
67
|
-
export async function updateSession(session) {
|
|
68
|
-
connect();
|
|
69
|
-
const query = db.updateTable('sessions').set(session).where('sessions.token', '=', session.token);
|
|
70
|
-
return await query.returningAll().executeTakeFirstOrThrow();
|
|
62
|
+
return await db.selectFrom('sessions').selectAll().where('userId', '=', userId).where('sessions.expires', '>', new Date()).execute();
|
|
71
63
|
}
|
|
72
64
|
/**
|
|
73
65
|
* Create a verification
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,56 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
3
|
+
if (value !== null && value !== void 0) {
|
|
4
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
5
|
+
var dispose, inner;
|
|
6
|
+
if (async) {
|
|
7
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
8
|
+
dispose = value[Symbol.asyncDispose];
|
|
9
|
+
}
|
|
10
|
+
if (dispose === void 0) {
|
|
11
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
12
|
+
dispose = value[Symbol.dispose];
|
|
13
|
+
if (async) inner = dispose;
|
|
14
|
+
}
|
|
15
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
16
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
17
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
18
|
+
}
|
|
19
|
+
else if (async) {
|
|
20
|
+
env.stack.push({ async: true });
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
};
|
|
24
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
25
|
+
return function (env) {
|
|
26
|
+
function fail(e) {
|
|
27
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
28
|
+
env.hasError = true;
|
|
29
|
+
}
|
|
30
|
+
var r, s = 0;
|
|
31
|
+
function next() {
|
|
32
|
+
while (r = env.stack.pop()) {
|
|
33
|
+
try {
|
|
34
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
35
|
+
if (r.dispose) {
|
|
36
|
+
var result = r.dispose.call(r.value);
|
|
37
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
38
|
+
}
|
|
39
|
+
else s |= 1;
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
fail(e);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
46
|
+
if (env.hasError) throw env.error;
|
|
47
|
+
}
|
|
48
|
+
return next();
|
|
49
|
+
};
|
|
50
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
51
|
+
var e = new Error(message);
|
|
52
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
53
|
+
});
|
|
2
54
|
import { Argument, Option, program } from 'commander';
|
|
3
55
|
import { styleText } from 'node:util';
|
|
4
56
|
import { getByString, isJSON, setByString } from 'utilium';
|
|
@@ -76,32 +128,56 @@ axiumDB
|
|
|
76
128
|
.description('Drop the Axium database and user')
|
|
77
129
|
.addOption(opts.force)
|
|
78
130
|
.action(async (opt) => {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
131
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
132
|
+
try {
|
|
133
|
+
const _ = __addDisposableResource(env_1, db.connect(), true);
|
|
134
|
+
const stats = await db.status().catch(exit);
|
|
135
|
+
if (!opt.force)
|
|
136
|
+
for (const key of ['users', 'passkeys', 'sessions']) {
|
|
137
|
+
if (stats[key] == 0)
|
|
138
|
+
continue;
|
|
139
|
+
output.warn(`Database has existing ${key}. Use --force if you really want to drop the database.`);
|
|
140
|
+
process.exit(2);
|
|
141
|
+
}
|
|
142
|
+
await db.uninstall(opt).catch(exit);
|
|
143
|
+
}
|
|
144
|
+
catch (e_1) {
|
|
145
|
+
env_1.error = e_1;
|
|
146
|
+
env_1.hasError = true;
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
const result_1 = __disposeResources(env_1);
|
|
150
|
+
if (result_1)
|
|
151
|
+
await result_1;
|
|
152
|
+
}
|
|
89
153
|
});
|
|
90
154
|
axiumDB
|
|
91
155
|
.command('wipe')
|
|
92
156
|
.description('Wipe the database')
|
|
93
157
|
.addOption(opts.force)
|
|
94
158
|
.action(async (opt) => {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
159
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
160
|
+
try {
|
|
161
|
+
const _ = __addDisposableResource(env_2, db.connect(), true);
|
|
162
|
+
const stats = await db.status().catch(exit);
|
|
163
|
+
if (!opt.force)
|
|
164
|
+
for (const key of ['users', 'passkeys', 'sessions']) {
|
|
165
|
+
if (stats[key] == 0)
|
|
166
|
+
continue;
|
|
167
|
+
output.warn(`Database has existing ${key}. Use --force if you really want to wipe the database.`);
|
|
168
|
+
process.exit(2);
|
|
169
|
+
}
|
|
170
|
+
await db.wipe(opt).catch(exit);
|
|
171
|
+
}
|
|
172
|
+
catch (e_2) {
|
|
173
|
+
env_2.error = e_2;
|
|
174
|
+
env_2.hasError = true;
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
const result_2 = __disposeResources(env_2);
|
|
178
|
+
if (result_2)
|
|
179
|
+
await result_2;
|
|
180
|
+
}
|
|
105
181
|
});
|
|
106
182
|
axiumDB
|
|
107
183
|
.command('check')
|
|
@@ -109,6 +185,26 @@ axiumDB
|
|
|
109
185
|
.action(async (opt) => {
|
|
110
186
|
await db.check(opt).catch(exit);
|
|
111
187
|
});
|
|
188
|
+
axiumDB
|
|
189
|
+
.command('clean')
|
|
190
|
+
.description('Remove expired rows')
|
|
191
|
+
.addOption(opts.force)
|
|
192
|
+
.action(async (opt) => {
|
|
193
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
194
|
+
try {
|
|
195
|
+
const _ = __addDisposableResource(env_3, db.connect(), true);
|
|
196
|
+
await db.clean(opt).catch(exit);
|
|
197
|
+
}
|
|
198
|
+
catch (e_3) {
|
|
199
|
+
env_3.error = e_3;
|
|
200
|
+
env_3.hasError = true;
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
const result_3 = __disposeResources(env_3);
|
|
204
|
+
if (result_3)
|
|
205
|
+
await result_3;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
112
208
|
const axiumConfig = program
|
|
113
209
|
.command('config')
|
|
114
210
|
.description('Manage the configuration')
|
|
@@ -117,7 +213,6 @@ const axiumConfig = program
|
|
|
117
213
|
.option('-r, --redact', 'Do not output sensitive values');
|
|
118
214
|
function configReplacer(opt) {
|
|
119
215
|
return (key, value) => {
|
|
120
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
121
216
|
return opt.redact && ['password', 'secret'].includes(key) ? '[redacted]' : value;
|
|
122
217
|
};
|
|
123
218
|
}
|
|
@@ -224,27 +319,39 @@ program
|
|
|
224
319
|
.description('Get information about the server')
|
|
225
320
|
.addOption(opts.host)
|
|
226
321
|
.action(async () => {
|
|
227
|
-
|
|
228
|
-
console.log(styleText('whiteBright', 'Debug mode:'), config.debug ? styleText('yellow', 'enabled') : 'disabled');
|
|
229
|
-
console.log(styleText('whiteBright', 'Loaded config files:'), config.files.keys().toArray().join(', '));
|
|
230
|
-
process.stdout.write(styleText('whiteBright', 'Database: '));
|
|
322
|
+
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
231
323
|
try {
|
|
232
|
-
console.log(
|
|
324
|
+
console.log('Axium Server v' + program.version());
|
|
325
|
+
console.log(styleText('whiteBright', 'Debug mode:'), config.debug ? styleText('yellow', 'enabled') : 'disabled');
|
|
326
|
+
console.log(styleText('whiteBright', 'Loaded config files:'), config.files.keys().toArray().join(', '));
|
|
327
|
+
process.stdout.write(styleText('whiteBright', 'Database: '));
|
|
328
|
+
const _ = __addDisposableResource(env_4, db.connect(), true);
|
|
329
|
+
try {
|
|
330
|
+
console.log(await db.statusText());
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
output.error('Unavailable');
|
|
334
|
+
}
|
|
335
|
+
console.log(styleText('whiteBright', 'Credentials authentication:'), config.auth.credentials ? styleText('yellow', 'enabled') : 'disabled');
|
|
336
|
+
console.log(styleText('whiteBright', 'Loaded plugins:'), Array.from(plugins)
|
|
337
|
+
.map(plugin => plugin.id)
|
|
338
|
+
.join(', ') || styleText('dim', '(none)'));
|
|
339
|
+
for (const plugin of plugins) {
|
|
340
|
+
if (!plugin.statusText)
|
|
341
|
+
continue;
|
|
342
|
+
console.log(styleText('bold', plugin.name), plugin.version + ':');
|
|
343
|
+
console.log(await plugin.statusText());
|
|
344
|
+
}
|
|
233
345
|
}
|
|
234
|
-
catch {
|
|
235
|
-
|
|
346
|
+
catch (e_4) {
|
|
347
|
+
env_4.error = e_4;
|
|
348
|
+
env_4.hasError = true;
|
|
236
349
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
for (const plugin of plugins) {
|
|
242
|
-
if (!plugin.statusText)
|
|
243
|
-
continue;
|
|
244
|
-
console.log(styleText('bold', plugin.name), plugin.version + ':');
|
|
245
|
-
console.log(await plugin.statusText());
|
|
350
|
+
finally {
|
|
351
|
+
const result_4 = __disposeResources(env_4);
|
|
352
|
+
if (result_4)
|
|
353
|
+
await result_4;
|
|
246
354
|
}
|
|
247
|
-
await db.database.destroy();
|
|
248
355
|
});
|
|
249
356
|
program
|
|
250
357
|
.command('ports')
|