@axium/server 0.18.3 → 0.18.5
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/{xpJ732Ht.js → CJWcAr_0.js} +1 -1
- package/build/client/_app/immutable/chunks/CJWcAr_0.js.br +0 -0
- package/build/client/_app/immutable/chunks/CJWcAr_0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Bg7BIJPa.js → CQFdLnr8.js} +1 -1
- package/build/client/_app/immutable/chunks/CQFdLnr8.js.br +0 -0
- package/build/client/_app/immutable/chunks/CQFdLnr8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DHWjxoyj.js → CdcSwQVL.js} +1 -1
- package/build/client/_app/immutable/chunks/CdcSwQVL.js.br +0 -0
- package/build/client/_app/immutable/chunks/CdcSwQVL.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Cml_y0zA.js → D6xzogxf.js} +1 -1
- package/build/client/_app/immutable/chunks/D6xzogxf.js.br +0 -0
- package/build/client/_app/immutable/chunks/D6xzogxf.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.CweUSyiW.js → app.CdOv6_es.js} +2 -2
- package/build/client/_app/immutable/entry/app.CdOv6_es.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CdOv6_es.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BmBZ80bb.js +1 -0
- package/build/client/_app/immutable/entry/start.BmBZ80bb.js.br +2 -0
- package/build/client/_app/immutable/entry/start.BmBZ80bb.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.C4aGDlhm.js → 1.BY5ftKcy.js} +1 -1
- package/build/client/_app/immutable/nodes/1.BY5ftKcy.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.BY5ftKcy.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.BGzXyyB3.js → 3.J_fMYI1u.js} +1 -1
- package/build/client/_app/immutable/nodes/3.J_fMYI1u.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.J_fMYI1u.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.BsqgrCbd.js → 4.B41jn4HJ.js} +1 -1
- package/build/client/_app/immutable/nodes/4.B41jn4HJ.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.B41jn4HJ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.Dt7ICc0L.js +1 -0
- package/build/client/_app/immutable/nodes/5.Dt7ICc0L.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.Dt7ICc0L.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{6.DtBvU7JX.js → 6.DWL9AHsk.js} +1 -1
- package/build/client/_app/immutable/nodes/6.DWL9AHsk.js.br +6 -0
- package/build/client/_app/immutable/nodes/6.DWL9AHsk.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-C-hV5RFm.js → 1-Dj7DykSO.js} +2 -2
- package/build/server/chunks/{1-C-hV5RFm.js.map → 1-Dj7DykSO.js.map} +1 -1
- package/build/server/chunks/{3-CZxs4BgY.js → 3-AzlXjeIu.js} +2 -2
- package/build/server/chunks/{3-CZxs4BgY.js.map → 3-AzlXjeIu.js.map} +1 -1
- package/build/server/chunks/{4-Ix00Mv7-.js → 4-CBbCsKIO.js} +2 -2
- package/build/server/chunks/{4-Ix00Mv7-.js.map → 4-CBbCsKIO.js.map} +1 -1
- package/build/server/chunks/{5-DGRimREi.js → 5-BbpQdkVZ.js} +2 -2
- package/build/server/chunks/{5-DGRimREi.js.map → 5-BbpQdkVZ.js.map} +1 -1
- package/build/server/chunks/{6-CycyCEm-.js → 6-C7Ej35UJ.js} +2 -2
- package/build/server/chunks/{6-CycyCEm-.js.map → 6-C7Ej35UJ.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 -253
- 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/Bg7BIJPa.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bg7BIJPa.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cml_y0zA.js.br +0 -0
- package/build/client/_app/immutable/chunks/Cml_y0zA.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DHWjxoyj.js.br +0 -0
- package/build/client/_app/immutable/chunks/DHWjxoyj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/xpJ732Ht.js.br +0 -0
- package/build/client/_app/immutable/chunks/xpJ732Ht.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CweUSyiW.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CweUSyiW.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BqQA8wwD.js +0 -1
- package/build/client/_app/immutable/entry/start.BqQA8wwD.js.br +0 -2
- package/build/client/_app/immutable/entry/start.BqQA8wwD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.C4aGDlhm.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.C4aGDlhm.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.BGzXyyB3.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.BGzXyyB3.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.BsqgrCbd.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.BsqgrCbd.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.CMxnVfGi.js +0 -1
- package/build/client/_app/immutable/nodes/5.CMxnVfGi.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.CMxnVfGi.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.DtBvU7JX.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.DtBvU7JX.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,15 +13,11 @@ 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;
|
|
20
|
+
io.debug('Connected to database!');
|
|
77
21
|
return database;
|
|
78
22
|
}
|
|
79
23
|
// Helpers
|
|
@@ -155,130 +99,118 @@ export async function createIndex(table, column, mod) {
|
|
|
155
99
|
await query.execute().then(io.done).catch(warnExists);
|
|
156
100
|
}
|
|
157
101
|
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
|
-
}
|
|
102
|
+
if (!config.db.password) {
|
|
103
|
+
config.save({ db: { password: randomBytes(32).toString('base64') } }, true);
|
|
104
|
+
io.debug('Generated password and wrote to global config');
|
|
273
105
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
106
|
+
await io.run('Checking for sudo', 'which sudo');
|
|
107
|
+
await io.run('Checking for psql', 'which psql');
|
|
108
|
+
await _sql('CREATE DATABASE axium', 'Creating database').catch(async (error) => {
|
|
109
|
+
if (error != 'database "axium" already exists')
|
|
110
|
+
throw error;
|
|
111
|
+
if (shouldRecreate(opt))
|
|
112
|
+
return;
|
|
113
|
+
await _sql('DROP DATABASE axium', 'Dropping database');
|
|
114
|
+
await _sql('CREATE DATABASE axium', 'Re-creating database');
|
|
115
|
+
});
|
|
116
|
+
const createQuery = `CREATE USER axium WITH ENCRYPTED PASSWORD '${config.db.password}' LOGIN`;
|
|
117
|
+
await _sql(createQuery, 'Creating user').catch(async (error) => {
|
|
118
|
+
if (error != 'role "axium" already exists')
|
|
119
|
+
throw error;
|
|
120
|
+
if (shouldRecreate(opt))
|
|
121
|
+
return;
|
|
122
|
+
await _sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
|
|
123
|
+
await _sql('DROP USER axium', 'Dropping user');
|
|
124
|
+
await _sql(createQuery, 'Re-creating user');
|
|
125
|
+
});
|
|
126
|
+
await _sql('GRANT ALL PRIVILEGES ON DATABASE axium TO axium', 'Granting database privileges');
|
|
127
|
+
await _sql('GRANT ALL PRIVILEGES ON SCHEMA public TO axium', 'Granting schema privileges');
|
|
128
|
+
await _sql('ALTER DATABASE axium OWNER TO axium', 'Setting database owner');
|
|
129
|
+
await getHBA(opt)
|
|
130
|
+
.then(([content, writeBack]) => {
|
|
131
|
+
io.start('Checking for Axium HBA configuration');
|
|
132
|
+
if (content.includes(pgHba))
|
|
133
|
+
throw 'already exists.';
|
|
134
|
+
io.done();
|
|
135
|
+
io.start('Adding Axium HBA configuration');
|
|
136
|
+
const newContent = content.replace(/^local\s+all\s+all.*$/m, `$&\n${pgHba}`);
|
|
137
|
+
io.done();
|
|
138
|
+
writeBack(newContent);
|
|
139
|
+
})
|
|
140
|
+
.catch(io.warn);
|
|
141
|
+
await _sql('SELECT pg_reload_conf()', 'Reloading configuration');
|
|
142
|
+
io.start('Connecting to database');
|
|
143
|
+
connect();
|
|
144
|
+
io.done();
|
|
145
|
+
function maybeCheck(table) {
|
|
146
|
+
return (e) => {
|
|
147
|
+
warnExists(e);
|
|
148
|
+
if (opt.check)
|
|
149
|
+
return checkTableTypes(table, expectedTypes[table], opt);
|
|
150
|
+
};
|
|
277
151
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
152
|
+
io.start('Creating table users');
|
|
153
|
+
await database.schema
|
|
154
|
+
.createTable('users')
|
|
155
|
+
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
156
|
+
.addColumn('name', 'text')
|
|
157
|
+
.addColumn('email', 'text', col => col.unique().notNull())
|
|
158
|
+
.addColumn('emailVerified', 'timestamptz')
|
|
159
|
+
.addColumn('image', 'text')
|
|
160
|
+
.addColumn('isAdmin', 'boolean', col => col.notNull().defaultTo(false))
|
|
161
|
+
.addColumn('roles', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
|
|
162
|
+
.addColumn('tags', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
|
|
163
|
+
.addColumn('preferences', 'jsonb', col => col.notNull().defaultTo('{}'))
|
|
164
|
+
.addColumn('registeredAt', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
165
|
+
.execute()
|
|
166
|
+
.then(io.done)
|
|
167
|
+
.catch(maybeCheck('users'));
|
|
168
|
+
io.start('Creating table sessions');
|
|
169
|
+
await database.schema
|
|
170
|
+
.createTable('sessions')
|
|
171
|
+
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
172
|
+
.addColumn('userId', 'uuid', col => col.references('users.id').onDelete('cascade').notNull())
|
|
173
|
+
.addColumn('token', 'text', col => col.notNull().unique())
|
|
174
|
+
.addColumn('created', 'timestamptz', col => col.notNull())
|
|
175
|
+
.addColumn('expires', 'timestamptz', col => col.notNull())
|
|
176
|
+
.addColumn('elevated', 'boolean', col => col.notNull())
|
|
177
|
+
.execute()
|
|
178
|
+
.then(io.done)
|
|
179
|
+
.catch(maybeCheck('sessions'));
|
|
180
|
+
await createIndex('sessions', 'id');
|
|
181
|
+
io.start('Creating table verifications');
|
|
182
|
+
await database.schema
|
|
183
|
+
.createTable('verifications')
|
|
184
|
+
.addColumn('userId', 'uuid', col => col.references('users.id').onDelete('cascade').notNull())
|
|
185
|
+
.addColumn('token', 'text', col => col.notNull().unique())
|
|
186
|
+
.addColumn('expires', 'timestamptz', col => col.notNull())
|
|
187
|
+
.addColumn('role', 'text', col => col.notNull())
|
|
188
|
+
.execute()
|
|
189
|
+
.then(io.done)
|
|
190
|
+
.catch(maybeCheck('verifications'));
|
|
191
|
+
io.start('Creating table passkeys');
|
|
192
|
+
await database.schema
|
|
193
|
+
.createTable('passkeys')
|
|
194
|
+
.addColumn('id', 'text', col => col.primaryKey().notNull())
|
|
195
|
+
.addColumn('name', 'text')
|
|
196
|
+
.addColumn('createdAt', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
197
|
+
.addColumn('userId', 'uuid', col => col.notNull().references('users.id').onDelete('cascade').notNull())
|
|
198
|
+
.addColumn('publicKey', 'bytea', col => col.notNull())
|
|
199
|
+
.addColumn('counter', 'integer', col => col.notNull())
|
|
200
|
+
.addColumn('deviceType', 'text', col => col.notNull())
|
|
201
|
+
.addColumn('backedUp', 'boolean', col => col.notNull())
|
|
202
|
+
.addColumn('transports', sql `text[]`)
|
|
203
|
+
.execute()
|
|
204
|
+
.then(io.done)
|
|
205
|
+
.catch(maybeCheck('passkeys'));
|
|
206
|
+
await createIndex('passkeys', 'userId');
|
|
207
|
+
io.start('Creating schema acl');
|
|
208
|
+
await database.schema.createSchema('acl').execute().then(io.done).catch(warnExists);
|
|
209
|
+
for (const plugin of plugins) {
|
|
210
|
+
if (!plugin.hooks.db_init)
|
|
211
|
+
continue;
|
|
212
|
+
io.plugin(plugin.name);
|
|
213
|
+
await plugin.hooks.db_init(opt);
|
|
282
214
|
}
|
|
283
215
|
}
|
|
284
216
|
export const expectedTypes = {
|
|
@@ -366,49 +298,36 @@ export async function checkTableTypes(tableName, types, opt) {
|
|
|
366
298
|
io.warn(unchecked);
|
|
367
299
|
}
|
|
368
300
|
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;
|
|
301
|
+
await io.run('Checking for sudo', 'which sudo');
|
|
302
|
+
await io.run('Checking for psql', 'which psql');
|
|
303
|
+
await _sql(`SELECT 1 FROM pg_database WHERE datname = 'axium'`, 'Checking for database').then(throwUnlessRows);
|
|
304
|
+
await _sql(`SELECT 1 FROM pg_roles WHERE rolname = 'axium'`, 'Checking for user').then(throwUnlessRows);
|
|
305
|
+
io.start('Connecting to database');
|
|
306
|
+
connect();
|
|
307
|
+
io.done();
|
|
308
|
+
io.start('Getting table metadata');
|
|
309
|
+
opt._metadata = await database.introspection.getTables();
|
|
310
|
+
const tables = Object.fromEntries(opt._metadata.map(t => [t.name, t]));
|
|
311
|
+
io.done();
|
|
312
|
+
for (const table of Object.keys(expectedTypes)) {
|
|
313
|
+
await checkTableTypes(table, expectedTypes[table], opt);
|
|
314
|
+
delete tables[table];
|
|
403
315
|
}
|
|
316
|
+
io.start('Checking for extra tables');
|
|
317
|
+
const unchecked = Object.keys(tables).join(', ');
|
|
318
|
+
if (!unchecked.length)
|
|
319
|
+
io.done();
|
|
320
|
+
else if (opt.strict)
|
|
321
|
+
throw unchecked;
|
|
322
|
+
else
|
|
323
|
+
io.warn(unchecked);
|
|
404
324
|
}
|
|
405
325
|
export async function clean(opt) {
|
|
406
326
|
const now = new Date();
|
|
407
|
-
const db = connect();
|
|
408
327
|
io.start('Removing expired sessions');
|
|
409
|
-
await
|
|
328
|
+
await database.deleteFrom('sessions').where('sessions.expires', '<', now).execute().then(io.done);
|
|
410
329
|
io.start('Removing expired verifications');
|
|
411
|
-
await
|
|
330
|
+
await database.deleteFrom('verifications').where('verifications.expires', '<', now).execute().then(io.done);
|
|
412
331
|
for (const plugin of plugins) {
|
|
413
332
|
if (!plugin.hooks.clean)
|
|
414
333
|
continue;
|
|
@@ -420,46 +339,32 @@ export async function clean(opt) {
|
|
|
420
339
|
* Completely remove Axium from the database.
|
|
421
340
|
*/
|
|
422
341
|
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;
|
|
342
|
+
for (const plugin of plugins) {
|
|
343
|
+
if (!plugin.hooks.remove)
|
|
344
|
+
continue;
|
|
345
|
+
io.plugin(plugin.name);
|
|
346
|
+
await plugin.hooks.remove(opt);
|
|
456
347
|
}
|
|
348
|
+
await _sql('DROP DATABASE axium', 'Dropping database');
|
|
349
|
+
await _sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
|
|
350
|
+
await _sql('DROP USER axium', 'Dropping user');
|
|
351
|
+
await getHBA(opt)
|
|
352
|
+
.then(([content, writeBack]) => {
|
|
353
|
+
io.start('Checking for Axium HBA configuration');
|
|
354
|
+
if (!content.includes(pgHba))
|
|
355
|
+
throw 'missing.';
|
|
356
|
+
io.done();
|
|
357
|
+
io.start('Removing Axium HBA configuration');
|
|
358
|
+
const newContent = content.replace(pgHba, '');
|
|
359
|
+
io.done();
|
|
360
|
+
writeBack(newContent);
|
|
361
|
+
})
|
|
362
|
+
.catch(io.warn);
|
|
457
363
|
}
|
|
458
364
|
/**
|
|
459
365
|
* Removes all data from tables.
|
|
460
366
|
*/
|
|
461
367
|
export async function wipe(opt) {
|
|
462
|
-
const db = connect();
|
|
463
368
|
for (const plugin of plugins) {
|
|
464
369
|
if (!plugin.hooks.db_wipe)
|
|
465
370
|
continue;
|
|
@@ -468,7 +373,7 @@ export async function wipe(opt) {
|
|
|
468
373
|
}
|
|
469
374
|
for (const table of ['users', 'passkeys', 'sessions', 'verifications']) {
|
|
470
375
|
io.start(`Wiping ${table}`);
|
|
471
|
-
await
|
|
376
|
+
await database.deleteFrom(table).execute();
|
|
472
377
|
io.done();
|
|
473
378
|
}
|
|
474
379
|
for (const table of await database.introspection.getTables()) {
|
|
@@ -476,7 +381,7 @@ export async function wipe(opt) {
|
|
|
476
381
|
continue;
|
|
477
382
|
const name = table.name;
|
|
478
383
|
io.debug(`Wiping ${name}`);
|
|
479
|
-
await
|
|
384
|
+
await database.deleteFrom(name).execute();
|
|
480
385
|
}
|
|
481
386
|
}
|
|
482
387
|
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/DHWjxoyj.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/Cml_y0zA.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"}
|