@axium/server 0.18.2 → 0.18.4
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/build/client/_app/immutable/chunks/{BvHJY3uo.js → BPkdKBlw.js} +1 -1
- package/build/client/_app/immutable/chunks/BPkdKBlw.js.br +0 -0
- package/build/client/_app/immutable/chunks/BPkdKBlw.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Br3pmvj9.js → C2G00Wo_.js} +1 -1
- package/build/client/_app/immutable/chunks/C2G00Wo_.js.br +0 -0
- package/build/client/_app/immutable/chunks/C2G00Wo_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DGggq7PZ.js → Che41mwa.js} +1 -1
- package/build/client/_app/immutable/chunks/Che41mwa.js.br +0 -0
- package/build/client/_app/immutable/chunks/Che41mwa.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{C1nOBSvD.js → DOU_MWYN.js} +2 -2
- package/build/client/_app/immutable/chunks/DOU_MWYN.js.br +0 -0
- package/build/client/_app/immutable/chunks/DOU_MWYN.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.Q0IljhGV.js → app.BbBU38hK.js} +2 -2
- package/build/client/_app/immutable/entry/app.BbBU38hK.js.br +0 -0
- package/build/client/_app/immutable/entry/app.BbBU38hK.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.Da9-9H3m.js +1 -0
- package/build/client/_app/immutable/entry/start.Da9-9H3m.js.br +2 -0
- package/build/client/_app/immutable/entry/start.Da9-9H3m.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.Co8h7Wzc.js → 1.Cmx8cGI-.js} +1 -1
- package/build/client/_app/immutable/nodes/1.Cmx8cGI-.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.Cmx8cGI-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.CzUUjv5D.js → 3.CHH7rvxu.js} +1 -1
- package/build/client/_app/immutable/nodes/3.CHH7rvxu.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CHH7rvxu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.C4UhmqdK.js → 4.D9IcRvFq.js} +1 -1
- package/build/client/_app/immutable/nodes/4.D9IcRvFq.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.D9IcRvFq.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.C2-lE2kM.js +1 -0
- package/build/client/_app/immutable/nodes/5.C2-lE2kM.js.br +2 -0
- package/build/client/_app/immutable/nodes/5.C2-lE2kM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{6.BBiAuqXe.js → 6.BIv1GUh7.js} +1 -1
- package/build/client/_app/immutable/nodes/6.BIv1GUh7.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BIv1GUh7.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/{1-Bxj6uY_D.js → 1-CbHAdNVA.js} +2 -2
- package/build/server/chunks/{1-Bxj6uY_D.js.map → 1-CbHAdNVA.js.map} +1 -1
- package/build/server/chunks/{3-B8XM00zf.js → 3-D-f3CysO.js} +2 -2
- package/build/server/chunks/{3-B8XM00zf.js.map → 3-D-f3CysO.js.map} +1 -1
- package/build/server/chunks/{4-rWZmsmZJ.js → 4-DzUqqu1u.js} +2 -2
- package/build/server/chunks/{4-rWZmsmZJ.js.map → 4-DzUqqu1u.js.map} +1 -1
- package/build/server/chunks/{5-BQyd9qam.js → 5-C4XhViZP.js} +2 -2
- package/build/server/chunks/{5-BQyd9qam.js.map → 5-C4XhViZP.js.map} +1 -1
- package/build/server/chunks/{6-uUMo7iR2.js → 6-BosXK7US.js} +2 -2
- package/build/server/chunks/{6-uUMo7iR2.js.map → 6-BosXK7US.js.map} +1 -1
- package/build/server/chunks/{hooks.server-C9d9yKyi.js → hooks.server-DmgUjoZV.js} +3 -2
- package/build/server/chunks/hooks.server-DmgUjoZV.js.map +1 -0
- package/build/server/index.js +2 -2
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +6 -6
- package/build/server/manifest.js.map +1 -1
- package/dist/api/session.js +1 -2
- package/dist/api/users.js +1 -2
- package/dist/auth.js +1 -14
- package/dist/cli.js +133 -225
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -0
- package/dist/database.js +158 -254
- package/dist/serve.d.ts +1 -0
- package/dist/serve.js +1 -2
- package/package.json +1 -1
- package/web/hooks.server.ts +2 -1
- package/build/client/_app/immutable/chunks/Br3pmvj9.js.br +0 -0
- package/build/client/_app/immutable/chunks/Br3pmvj9.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BvHJY3uo.js.br +0 -0
- package/build/client/_app/immutable/chunks/BvHJY3uo.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C1nOBSvD.js.br +0 -0
- package/build/client/_app/immutable/chunks/C1nOBSvD.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DGggq7PZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/DGggq7PZ.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.Q0IljhGV.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Q0IljhGV.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BKfmGsvo.js +0 -1
- package/build/client/_app/immutable/entry/start.BKfmGsvo.js.br +0 -2
- package/build/client/_app/immutable/entry/start.BKfmGsvo.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.Co8h7Wzc.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.Co8h7Wzc.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CzUUjv5D.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CzUUjv5D.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.C4UhmqdK.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.C4UhmqdK.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.BiedHsaj.js +0 -1
- package/build/client/_app/immutable/nodes/5.BiedHsaj.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.BiedHsaj.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BBiAuqXe.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BBiAuqXe.js.gz +0 -0
- package/build/server/chunks/hooks.server-C9d9yKyi.js.map +0 -1
package/dist/config.js
CHANGED
|
@@ -54,6 +54,7 @@ export const config = _unique('config', {
|
|
|
54
54
|
show_duplicate_state: false,
|
|
55
55
|
web: {
|
|
56
56
|
assets: '',
|
|
57
|
+
build: '../build/handler.js',
|
|
57
58
|
disable_cache: false,
|
|
58
59
|
port: 443,
|
|
59
60
|
prefix: '',
|
|
@@ -114,6 +115,7 @@ export const FileSchema = z
|
|
|
114
115
|
web: z
|
|
115
116
|
.looseObject({
|
|
116
117
|
assets: z.string(),
|
|
118
|
+
build: z.string(),
|
|
117
119
|
disable_cache: z.boolean(),
|
|
118
120
|
port: z.number().min(1).max(65535),
|
|
119
121
|
prefix: z.string(),
|
package/dist/database.js
CHANGED
|
@@ -1,55 +1,3 @@
|
|
|
1
|
-
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
-
if (value !== null && value !== void 0) {
|
|
3
|
-
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
-
var dispose, inner;
|
|
5
|
-
if (async) {
|
|
6
|
-
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
-
dispose = value[Symbol.asyncDispose];
|
|
8
|
-
}
|
|
9
|
-
if (dispose === void 0) {
|
|
10
|
-
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
-
dispose = value[Symbol.dispose];
|
|
12
|
-
if (async) inner = dispose;
|
|
13
|
-
}
|
|
14
|
-
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
-
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
-
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
-
}
|
|
18
|
-
else if (async) {
|
|
19
|
-
env.stack.push({ async: true });
|
|
20
|
-
}
|
|
21
|
-
return value;
|
|
22
|
-
};
|
|
23
|
-
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
-
return function (env) {
|
|
25
|
-
function fail(e) {
|
|
26
|
-
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
-
env.hasError = true;
|
|
28
|
-
}
|
|
29
|
-
var r, s = 0;
|
|
30
|
-
function next() {
|
|
31
|
-
while (r = env.stack.pop()) {
|
|
32
|
-
try {
|
|
33
|
-
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
-
if (r.dispose) {
|
|
35
|
-
var result = r.dispose.call(r.value);
|
|
36
|
-
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
-
}
|
|
38
|
-
else s |= 1;
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
fail(e);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
-
if (env.hasError) throw env.error;
|
|
46
|
-
}
|
|
47
|
-
return next();
|
|
48
|
-
};
|
|
49
|
-
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
-
var e = new Error(message);
|
|
51
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
-
});
|
|
53
1
|
import { Kysely, PostgresDialect, sql } from 'kysely';
|
|
54
2
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
|
55
3
|
import { randomBytes } from 'node:crypto';
|
|
@@ -65,14 +13,9 @@ export function connect() {
|
|
|
65
13
|
return database;
|
|
66
14
|
if (globalThis[sym])
|
|
67
15
|
return (database = globalThis[sym]);
|
|
68
|
-
|
|
16
|
+
database = new Kysely({
|
|
69
17
|
dialect: new PostgresDialect({ pool: new pg.Pool(config.db) }),
|
|
70
18
|
});
|
|
71
|
-
database = Object.assign(_db, {
|
|
72
|
-
async [Symbol.asyncDispose]() {
|
|
73
|
-
await _db.destroy();
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
19
|
globalThis[sym] = database;
|
|
77
20
|
return database;
|
|
78
21
|
}
|
|
@@ -155,130 +98,118 @@ export async function createIndex(table, column, mod) {
|
|
|
155
98
|
await query.execute().then(io.done).catch(warnExists);
|
|
156
99
|
}
|
|
157
100
|
export async function init(opt) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
config.save({ db: { password: randomBytes(32).toString('base64') } }, true);
|
|
162
|
-
io.debug('Generated password and wrote to global config');
|
|
163
|
-
}
|
|
164
|
-
await io.run('Checking for sudo', 'which sudo');
|
|
165
|
-
await io.run('Checking for psql', 'which psql');
|
|
166
|
-
await _sql('CREATE DATABASE axium', 'Creating database').catch(async (error) => {
|
|
167
|
-
if (error != 'database "axium" already exists')
|
|
168
|
-
throw error;
|
|
169
|
-
if (shouldRecreate(opt))
|
|
170
|
-
return;
|
|
171
|
-
await _sql('DROP DATABASE axium', 'Dropping database');
|
|
172
|
-
await _sql('CREATE DATABASE axium', 'Re-creating database');
|
|
173
|
-
});
|
|
174
|
-
const createQuery = `CREATE USER axium WITH ENCRYPTED PASSWORD '${config.db.password}' LOGIN`;
|
|
175
|
-
await _sql(createQuery, 'Creating user').catch(async (error) => {
|
|
176
|
-
if (error != 'role "axium" already exists')
|
|
177
|
-
throw error;
|
|
178
|
-
if (shouldRecreate(opt))
|
|
179
|
-
return;
|
|
180
|
-
await _sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
|
|
181
|
-
await _sql('DROP USER axium', 'Dropping user');
|
|
182
|
-
await _sql(createQuery, 'Re-creating user');
|
|
183
|
-
});
|
|
184
|
-
await _sql('GRANT ALL PRIVILEGES ON DATABASE axium TO axium', 'Granting database privileges');
|
|
185
|
-
await _sql('GRANT ALL PRIVILEGES ON SCHEMA public TO axium', 'Granting schema privileges');
|
|
186
|
-
await _sql('ALTER DATABASE axium OWNER TO axium', 'Setting database owner');
|
|
187
|
-
await getHBA(opt)
|
|
188
|
-
.then(([content, writeBack]) => {
|
|
189
|
-
io.start('Checking for Axium HBA configuration');
|
|
190
|
-
if (content.includes(pgHba))
|
|
191
|
-
throw 'already exists.';
|
|
192
|
-
io.done();
|
|
193
|
-
io.start('Adding Axium HBA configuration');
|
|
194
|
-
const newContent = content.replace(/^local\s+all\s+all.*$/m, `$&\n${pgHba}`);
|
|
195
|
-
io.done();
|
|
196
|
-
writeBack(newContent);
|
|
197
|
-
})
|
|
198
|
-
.catch(io.warn);
|
|
199
|
-
await _sql('SELECT pg_reload_conf()', 'Reloading configuration');
|
|
200
|
-
io.start('Connecting to database');
|
|
201
|
-
const db = __addDisposableResource(env_1, connect(), true);
|
|
202
|
-
io.done();
|
|
203
|
-
function maybeCheck(table) {
|
|
204
|
-
return (e) => {
|
|
205
|
-
warnExists(e);
|
|
206
|
-
if (opt.check)
|
|
207
|
-
return checkTableTypes(table, expectedTypes[table], opt);
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
io.start('Creating table users');
|
|
211
|
-
await db.schema
|
|
212
|
-
.createTable('users')
|
|
213
|
-
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
214
|
-
.addColumn('name', 'text')
|
|
215
|
-
.addColumn('email', 'text', col => col.unique().notNull())
|
|
216
|
-
.addColumn('emailVerified', 'timestamptz')
|
|
217
|
-
.addColumn('image', 'text')
|
|
218
|
-
.addColumn('isAdmin', 'boolean', col => col.notNull().defaultTo(false))
|
|
219
|
-
.addColumn('roles', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
|
|
220
|
-
.addColumn('tags', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
|
|
221
|
-
.addColumn('preferences', 'jsonb', col => col.notNull().defaultTo(sql `'{}'::jsonb`))
|
|
222
|
-
.addColumn('registeredAt', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
223
|
-
.execute()
|
|
224
|
-
.then(io.done)
|
|
225
|
-
.catch(maybeCheck('users'));
|
|
226
|
-
io.start('Creating table sessions');
|
|
227
|
-
await db.schema
|
|
228
|
-
.createTable('sessions')
|
|
229
|
-
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
230
|
-
.addColumn('userId', 'uuid', col => col.references('users.id').onDelete('cascade').notNull())
|
|
231
|
-
.addColumn('token', 'text', col => col.notNull().unique())
|
|
232
|
-
.addColumn('created', 'timestamptz', col => col.notNull())
|
|
233
|
-
.addColumn('expires', 'timestamptz', col => col.notNull())
|
|
234
|
-
.addColumn('elevated', 'boolean', col => col.notNull())
|
|
235
|
-
.execute()
|
|
236
|
-
.then(io.done)
|
|
237
|
-
.catch(maybeCheck('sessions'));
|
|
238
|
-
await createIndex('sessions', 'id');
|
|
239
|
-
io.start('Creating table verifications');
|
|
240
|
-
await db.schema
|
|
241
|
-
.createTable('verifications')
|
|
242
|
-
.addColumn('userId', 'uuid', col => col.references('users.id').onDelete('cascade').notNull())
|
|
243
|
-
.addColumn('token', 'text', col => col.notNull().unique())
|
|
244
|
-
.addColumn('expires', 'timestamptz', col => col.notNull())
|
|
245
|
-
.addColumn('role', 'text', col => col.notNull())
|
|
246
|
-
.execute()
|
|
247
|
-
.then(io.done)
|
|
248
|
-
.catch(maybeCheck('verifications'));
|
|
249
|
-
io.start('Creating table passkeys');
|
|
250
|
-
await db.schema
|
|
251
|
-
.createTable('passkeys')
|
|
252
|
-
.addColumn('id', 'text', col => col.primaryKey().notNull())
|
|
253
|
-
.addColumn('name', 'text')
|
|
254
|
-
.addColumn('createdAt', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
255
|
-
.addColumn('userId', 'uuid', col => col.notNull().references('users.id').onDelete('cascade').notNull())
|
|
256
|
-
.addColumn('publicKey', 'bytea', col => col.notNull())
|
|
257
|
-
.addColumn('counter', 'integer', col => col.notNull())
|
|
258
|
-
.addColumn('deviceType', 'text', col => col.notNull())
|
|
259
|
-
.addColumn('backedUp', 'boolean', col => col.notNull())
|
|
260
|
-
.addColumn('transports', sql `text[]`)
|
|
261
|
-
.execute()
|
|
262
|
-
.then(io.done)
|
|
263
|
-
.catch(maybeCheck('passkeys'));
|
|
264
|
-
await createIndex('passkeys', 'userId');
|
|
265
|
-
io.start('Creating schema acl');
|
|
266
|
-
await db.schema.createSchema('acl').execute().then(io.done).catch(warnExists);
|
|
267
|
-
for (const plugin of plugins) {
|
|
268
|
-
if (!plugin.hooks.db_init)
|
|
269
|
-
continue;
|
|
270
|
-
io.plugin(plugin.name);
|
|
271
|
-
await plugin.hooks.db_init(opt);
|
|
272
|
-
}
|
|
101
|
+
if (!config.db.password) {
|
|
102
|
+
config.save({ db: { password: randomBytes(32).toString('base64') } }, true);
|
|
103
|
+
io.debug('Generated password and wrote to global config');
|
|
273
104
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
105
|
+
await io.run('Checking for sudo', 'which sudo');
|
|
106
|
+
await io.run('Checking for psql', 'which psql');
|
|
107
|
+
await _sql('CREATE DATABASE axium', 'Creating database').catch(async (error) => {
|
|
108
|
+
if (error != 'database "axium" already exists')
|
|
109
|
+
throw error;
|
|
110
|
+
if (shouldRecreate(opt))
|
|
111
|
+
return;
|
|
112
|
+
await _sql('DROP DATABASE axium', 'Dropping database');
|
|
113
|
+
await _sql('CREATE DATABASE axium', 'Re-creating database');
|
|
114
|
+
});
|
|
115
|
+
const createQuery = `CREATE USER axium WITH ENCRYPTED PASSWORD '${config.db.password}' LOGIN`;
|
|
116
|
+
await _sql(createQuery, 'Creating user').catch(async (error) => {
|
|
117
|
+
if (error != 'role "axium" already exists')
|
|
118
|
+
throw error;
|
|
119
|
+
if (shouldRecreate(opt))
|
|
120
|
+
return;
|
|
121
|
+
await _sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
|
|
122
|
+
await _sql('DROP USER axium', 'Dropping user');
|
|
123
|
+
await _sql(createQuery, 'Re-creating user');
|
|
124
|
+
});
|
|
125
|
+
await _sql('GRANT ALL PRIVILEGES ON DATABASE axium TO axium', 'Granting database privileges');
|
|
126
|
+
await _sql('GRANT ALL PRIVILEGES ON SCHEMA public TO axium', 'Granting schema privileges');
|
|
127
|
+
await _sql('ALTER DATABASE axium OWNER TO axium', 'Setting database owner');
|
|
128
|
+
await getHBA(opt)
|
|
129
|
+
.then(([content, writeBack]) => {
|
|
130
|
+
io.start('Checking for Axium HBA configuration');
|
|
131
|
+
if (content.includes(pgHba))
|
|
132
|
+
throw 'already exists.';
|
|
133
|
+
io.done();
|
|
134
|
+
io.start('Adding Axium HBA configuration');
|
|
135
|
+
const newContent = content.replace(/^local\s+all\s+all.*$/m, `$&\n${pgHba}`);
|
|
136
|
+
io.done();
|
|
137
|
+
writeBack(newContent);
|
|
138
|
+
})
|
|
139
|
+
.catch(io.warn);
|
|
140
|
+
await _sql('SELECT pg_reload_conf()', 'Reloading configuration');
|
|
141
|
+
io.start('Connecting to database');
|
|
142
|
+
connect();
|
|
143
|
+
io.done();
|
|
144
|
+
function maybeCheck(table) {
|
|
145
|
+
return (e) => {
|
|
146
|
+
warnExists(e);
|
|
147
|
+
if (opt.check)
|
|
148
|
+
return checkTableTypes(table, expectedTypes[table], opt);
|
|
149
|
+
};
|
|
277
150
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
151
|
+
io.start('Creating table users');
|
|
152
|
+
await database.schema
|
|
153
|
+
.createTable('users')
|
|
154
|
+
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
155
|
+
.addColumn('name', 'text')
|
|
156
|
+
.addColumn('email', 'text', col => col.unique().notNull())
|
|
157
|
+
.addColumn('emailVerified', 'timestamptz')
|
|
158
|
+
.addColumn('image', 'text')
|
|
159
|
+
.addColumn('isAdmin', 'boolean', col => col.notNull().defaultTo(false))
|
|
160
|
+
.addColumn('roles', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
|
|
161
|
+
.addColumn('tags', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
|
|
162
|
+
.addColumn('preferences', 'jsonb', col => col.notNull().defaultTo('{}'))
|
|
163
|
+
.addColumn('registeredAt', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
164
|
+
.execute()
|
|
165
|
+
.then(io.done)
|
|
166
|
+
.catch(maybeCheck('users'));
|
|
167
|
+
io.start('Creating table sessions');
|
|
168
|
+
await database.schema
|
|
169
|
+
.createTable('sessions')
|
|
170
|
+
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
171
|
+
.addColumn('userId', 'uuid', col => col.references('users.id').onDelete('cascade').notNull())
|
|
172
|
+
.addColumn('token', 'text', col => col.notNull().unique())
|
|
173
|
+
.addColumn('created', 'timestamptz', col => col.notNull())
|
|
174
|
+
.addColumn('expires', 'timestamptz', col => col.notNull())
|
|
175
|
+
.addColumn('elevated', 'boolean', col => col.notNull())
|
|
176
|
+
.execute()
|
|
177
|
+
.then(io.done)
|
|
178
|
+
.catch(maybeCheck('sessions'));
|
|
179
|
+
await createIndex('sessions', 'id');
|
|
180
|
+
io.start('Creating table verifications');
|
|
181
|
+
await database.schema
|
|
182
|
+
.createTable('verifications')
|
|
183
|
+
.addColumn('userId', 'uuid', col => col.references('users.id').onDelete('cascade').notNull())
|
|
184
|
+
.addColumn('token', 'text', col => col.notNull().unique())
|
|
185
|
+
.addColumn('expires', 'timestamptz', col => col.notNull())
|
|
186
|
+
.addColumn('role', 'text', col => col.notNull())
|
|
187
|
+
.execute()
|
|
188
|
+
.then(io.done)
|
|
189
|
+
.catch(maybeCheck('verifications'));
|
|
190
|
+
io.start('Creating table passkeys');
|
|
191
|
+
await database.schema
|
|
192
|
+
.createTable('passkeys')
|
|
193
|
+
.addColumn('id', 'text', col => col.primaryKey().notNull())
|
|
194
|
+
.addColumn('name', 'text')
|
|
195
|
+
.addColumn('createdAt', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
196
|
+
.addColumn('userId', 'uuid', col => col.notNull().references('users.id').onDelete('cascade').notNull())
|
|
197
|
+
.addColumn('publicKey', 'bytea', col => col.notNull())
|
|
198
|
+
.addColumn('counter', 'integer', col => col.notNull())
|
|
199
|
+
.addColumn('deviceType', 'text', col => col.notNull())
|
|
200
|
+
.addColumn('backedUp', 'boolean', col => col.notNull())
|
|
201
|
+
.addColumn('transports', sql `text[]`)
|
|
202
|
+
.execute()
|
|
203
|
+
.then(io.done)
|
|
204
|
+
.catch(maybeCheck('passkeys'));
|
|
205
|
+
await createIndex('passkeys', 'userId');
|
|
206
|
+
io.start('Creating schema acl');
|
|
207
|
+
await database.schema.createSchema('acl').execute().then(io.done).catch(warnExists);
|
|
208
|
+
for (const plugin of plugins) {
|
|
209
|
+
if (!plugin.hooks.db_init)
|
|
210
|
+
continue;
|
|
211
|
+
io.plugin(plugin.name);
|
|
212
|
+
await plugin.hooks.db_init(opt);
|
|
282
213
|
}
|
|
283
214
|
}
|
|
284
215
|
export const expectedTypes = {
|
|
@@ -326,7 +257,7 @@ export const expectedTypes = {
|
|
|
326
257
|
export async function checkTableTypes(tableName, types, opt) {
|
|
327
258
|
io.start(`Checking for table ${tableName}`);
|
|
328
259
|
const dbTables = opt._metadata || (await database.introspection.getTables());
|
|
329
|
-
const table = dbTables.find(t => t.name === tableName);
|
|
260
|
+
const table = dbTables.find(t => (t.schema == 'public' ? t.name : `${t.schema}.${t.name}`) === tableName);
|
|
330
261
|
if (!table)
|
|
331
262
|
throw 'missing.';
|
|
332
263
|
io.done();
|
|
@@ -366,49 +297,36 @@ export async function checkTableTypes(tableName, types, opt) {
|
|
|
366
297
|
io.warn(unchecked);
|
|
367
298
|
}
|
|
368
299
|
export async function check(opt) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
await checkTableTypes(table, expectedTypes[table], opt);
|
|
384
|
-
delete tables[table];
|
|
385
|
-
}
|
|
386
|
-
io.start('Checking for extra tables');
|
|
387
|
-
const unchecked = Object.keys(tables).join(', ');
|
|
388
|
-
if (!unchecked.length)
|
|
389
|
-
io.done();
|
|
390
|
-
else if (opt.strict)
|
|
391
|
-
throw unchecked;
|
|
392
|
-
else
|
|
393
|
-
io.warn(unchecked);
|
|
394
|
-
}
|
|
395
|
-
catch (e_2) {
|
|
396
|
-
env_2.error = e_2;
|
|
397
|
-
env_2.hasError = true;
|
|
398
|
-
}
|
|
399
|
-
finally {
|
|
400
|
-
const result_2 = __disposeResources(env_2);
|
|
401
|
-
if (result_2)
|
|
402
|
-
await result_2;
|
|
300
|
+
await io.run('Checking for sudo', 'which sudo');
|
|
301
|
+
await io.run('Checking for psql', 'which psql');
|
|
302
|
+
await _sql(`SELECT 1 FROM pg_database WHERE datname = 'axium'`, 'Checking for database').then(throwUnlessRows);
|
|
303
|
+
await _sql(`SELECT 1 FROM pg_roles WHERE rolname = 'axium'`, 'Checking for user').then(throwUnlessRows);
|
|
304
|
+
io.start('Connecting to database');
|
|
305
|
+
connect();
|
|
306
|
+
io.done();
|
|
307
|
+
io.start('Getting table metadata');
|
|
308
|
+
opt._metadata = await database.introspection.getTables();
|
|
309
|
+
const tables = Object.fromEntries(opt._metadata.map(t => [t.name, t]));
|
|
310
|
+
io.done();
|
|
311
|
+
for (const table of Object.keys(expectedTypes)) {
|
|
312
|
+
await checkTableTypes(table, expectedTypes[table], opt);
|
|
313
|
+
delete tables[table];
|
|
403
314
|
}
|
|
315
|
+
io.start('Checking for extra tables');
|
|
316
|
+
const unchecked = Object.keys(tables).join(', ');
|
|
317
|
+
if (!unchecked.length)
|
|
318
|
+
io.done();
|
|
319
|
+
else if (opt.strict)
|
|
320
|
+
throw unchecked;
|
|
321
|
+
else
|
|
322
|
+
io.warn(unchecked);
|
|
404
323
|
}
|
|
405
324
|
export async function clean(opt) {
|
|
406
325
|
const now = new Date();
|
|
407
|
-
const db = connect();
|
|
408
326
|
io.start('Removing expired sessions');
|
|
409
|
-
await
|
|
327
|
+
await database.deleteFrom('sessions').where('sessions.expires', '<', now).execute().then(io.done);
|
|
410
328
|
io.start('Removing expired verifications');
|
|
411
|
-
await
|
|
329
|
+
await database.deleteFrom('verifications').where('verifications.expires', '<', now).execute().then(io.done);
|
|
412
330
|
for (const plugin of plugins) {
|
|
413
331
|
if (!plugin.hooks.clean)
|
|
414
332
|
continue;
|
|
@@ -420,46 +338,32 @@ export async function clean(opt) {
|
|
|
420
338
|
* Completely remove Axium from the database.
|
|
421
339
|
*/
|
|
422
340
|
export async function uninstall(opt) {
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
continue;
|
|
429
|
-
io.plugin(plugin.name);
|
|
430
|
-
await plugin.hooks.remove(opt);
|
|
431
|
-
}
|
|
432
|
-
await _sql('DROP DATABASE axium', 'Dropping database');
|
|
433
|
-
await _sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
|
|
434
|
-
await _sql('DROP USER axium', 'Dropping user');
|
|
435
|
-
await getHBA(opt)
|
|
436
|
-
.then(([content, writeBack]) => {
|
|
437
|
-
io.start('Checking for Axium HBA configuration');
|
|
438
|
-
if (!content.includes(pgHba))
|
|
439
|
-
throw 'missing.';
|
|
440
|
-
io.done();
|
|
441
|
-
io.start('Removing Axium HBA configuration');
|
|
442
|
-
const newContent = content.replace(pgHba, '');
|
|
443
|
-
io.done();
|
|
444
|
-
writeBack(newContent);
|
|
445
|
-
})
|
|
446
|
-
.catch(io.warn);
|
|
447
|
-
}
|
|
448
|
-
catch (e_3) {
|
|
449
|
-
env_3.error = e_3;
|
|
450
|
-
env_3.hasError = true;
|
|
451
|
-
}
|
|
452
|
-
finally {
|
|
453
|
-
const result_3 = __disposeResources(env_3);
|
|
454
|
-
if (result_3)
|
|
455
|
-
await result_3;
|
|
341
|
+
for (const plugin of plugins) {
|
|
342
|
+
if (!plugin.hooks.remove)
|
|
343
|
+
continue;
|
|
344
|
+
io.plugin(plugin.name);
|
|
345
|
+
await plugin.hooks.remove(opt);
|
|
456
346
|
}
|
|
347
|
+
await _sql('DROP DATABASE axium', 'Dropping database');
|
|
348
|
+
await _sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
|
|
349
|
+
await _sql('DROP USER axium', 'Dropping user');
|
|
350
|
+
await getHBA(opt)
|
|
351
|
+
.then(([content, writeBack]) => {
|
|
352
|
+
io.start('Checking for Axium HBA configuration');
|
|
353
|
+
if (!content.includes(pgHba))
|
|
354
|
+
throw 'missing.';
|
|
355
|
+
io.done();
|
|
356
|
+
io.start('Removing Axium HBA configuration');
|
|
357
|
+
const newContent = content.replace(pgHba, '');
|
|
358
|
+
io.done();
|
|
359
|
+
writeBack(newContent);
|
|
360
|
+
})
|
|
361
|
+
.catch(io.warn);
|
|
457
362
|
}
|
|
458
363
|
/**
|
|
459
364
|
* Removes all data from tables.
|
|
460
365
|
*/
|
|
461
366
|
export async function wipe(opt) {
|
|
462
|
-
const db = connect();
|
|
463
367
|
for (const plugin of plugins) {
|
|
464
368
|
if (!plugin.hooks.db_wipe)
|
|
465
369
|
continue;
|
|
@@ -468,7 +372,7 @@ export async function wipe(opt) {
|
|
|
468
372
|
}
|
|
469
373
|
for (const table of ['users', 'passkeys', 'sessions', 'verifications']) {
|
|
470
374
|
io.start(`Wiping ${table}`);
|
|
471
|
-
await
|
|
375
|
+
await database.deleteFrom(table).execute();
|
|
472
376
|
io.done();
|
|
473
377
|
}
|
|
474
378
|
for (const table of await database.introspection.getTables()) {
|
|
@@ -476,7 +380,7 @@ export async function wipe(opt) {
|
|
|
476
380
|
continue;
|
|
477
381
|
const name = table.name;
|
|
478
382
|
io.debug(`Wiping ${name}`);
|
|
479
|
-
await
|
|
383
|
+
await database.deleteFrom(name).execute();
|
|
480
384
|
}
|
|
481
385
|
}
|
|
482
386
|
export async function rotatePassword() {
|
package/dist/serve.d.ts
CHANGED
package/dist/serve.js
CHANGED
|
@@ -2,9 +2,8 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { createServer } from 'node:http';
|
|
3
3
|
import { createServer as createSecureServer } from 'node:https';
|
|
4
4
|
import config from './config.js';
|
|
5
|
-
const _handlerPath = '../build/handler.js';
|
|
6
5
|
export async function serve(opt) {
|
|
7
|
-
const { handler } = await import(
|
|
6
|
+
const { handler } = await import(opt.build || config.web.build);
|
|
8
7
|
if (!opt.secure && !config.web.secure)
|
|
9
8
|
return createServer(handler);
|
|
10
9
|
return createSecureServer({ key: readFileSync(opt.ssl_key || config.web.ssl_key), cert: readFileSync(opt.ssl_cert || config.web.ssl_cert) }, handler);
|
package/package.json
CHANGED
package/web/hooks.server.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '@axium/server/api/index';
|
|
2
2
|
import { loadDefaultConfigs } from '@axium/server/config';
|
|
3
|
-
import { clean, database } from '@axium/server/database';
|
|
3
|
+
import { clean, connect, database } from '@axium/server/database';
|
|
4
4
|
import { dirs, logger } from '@axium/server/io';
|
|
5
5
|
import { allLogLevels } from 'logzen';
|
|
6
6
|
import { createWriteStream } from 'node:fs';
|
|
@@ -8,6 +8,7 @@ import { join } from 'node:path/posix';
|
|
|
8
8
|
|
|
9
9
|
logger.attach(createWriteStream(join(dirs.at(-1), 'server.log')), { output: allLogLevels });
|
|
10
10
|
await loadDefaultConfigs();
|
|
11
|
+
connect();
|
|
11
12
|
await clean({});
|
|
12
13
|
|
|
13
14
|
process.on('beforeExit', async () => {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as o,a as r}from"../chunks/C1nOBSvD.js";export{o as load_css,r as start};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"../chunks/DsnmJJEf.js";import{L as t}from"../chunks/DGggq7PZ.js";function r(o){t(o,{fullPage:!0})}export{r as component};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.server-C9d9yKyi.js","sources":["../../../.svelte-kit/adapter-node/chunks/hooks.server.js"],"sourcesContent":["import \"@axium/server/api/index\";\nimport { loadDefaultConfigs } from \"@axium/server/config\";\nimport { clean, database } from \"@axium/server/database\";\nimport { logger, dirs } from \"@axium/server/io\";\nimport { allLogLevels } from \"logzen\";\nimport { createWriteStream } from \"node:fs\";\nimport { join } from \"node:path/posix\";\nimport { handle } from \"@axium/server/sveltekit\";\nlogger.attach(createWriteStream(join(dirs.at(-1), \"server.log\")), { output: allLogLevels });\nawait loadDefaultConfigs();\nawait clean({});\nprocess.on(\"beforeExit\", async () => {\n await database.destroy();\n});\nexport {\n handle\n};\n"],"names":[],"mappings":";;;;;;;;;AAQA,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AAC3F,MAAM,kBAAkB,EAAE;AAC1B,MAAM,KAAK,CAAC,EAAE,CAAC;AACf,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY;AACrC,EAAE,MAAM,QAAQ,CAAC,OAAO,EAAE;AAC1B,CAAC,CAAC"}
|