@axium/server 0.20.6 → 0.21.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.
Files changed (58) hide show
  1. package/build/client/_app/immutable/chunks/BT6JVi7A.js +3 -0
  2. package/build/client/_app/immutable/chunks/BT6JVi7A.js.br +0 -0
  3. package/build/client/_app/immutable/chunks/BT6JVi7A.js.gz +0 -0
  4. package/build/client/_app/immutable/entry/{app.DN-14WEp.js → app.ZFo0Iz7Y.js} +2 -2
  5. package/build/client/_app/immutable/entry/app.ZFo0Iz7Y.js.br +0 -0
  6. package/build/client/_app/immutable/entry/app.ZFo0Iz7Y.js.gz +0 -0
  7. package/build/client/_app/immutable/entry/start.BeJCp-7l.js +1 -0
  8. package/build/client/_app/immutable/entry/start.BeJCp-7l.js.br +2 -0
  9. package/build/client/_app/immutable/entry/start.BeJCp-7l.js.gz +0 -0
  10. package/build/client/_app/immutable/nodes/{1.CYGWa5Ht.js → 1.jmd85CY0.js} +1 -1
  11. package/build/client/_app/immutable/nodes/1.jmd85CY0.js.br +0 -0
  12. package/build/client/_app/immutable/nodes/1.jmd85CY0.js.gz +0 -0
  13. package/build/client/_app/version.json +1 -1
  14. package/build/client/_app/version.json.br +0 -0
  15. package/build/client/_app/version.json.gz +0 -0
  16. package/build/server/chunks/{1-ChHp-lcj.js → 1-IUsQDUky.js} +2 -2
  17. package/build/server/chunks/{1-ChHp-lcj.js.map → 1-IUsQDUky.js.map} +1 -1
  18. package/build/server/chunks/{3-qz4gvEJj.js → 3-BfZcxicd.js} +2 -2
  19. package/build/server/chunks/{3-qz4gvEJj.js.map → 3-BfZcxicd.js.map} +1 -1
  20. package/build/server/chunks/{_page.svelte-CNZCbT6U.js → _page.svelte-DnC0rUFy.js} +2 -2
  21. package/build/server/chunks/{_page.svelte-CNZCbT6U.js.map → _page.svelte-DnC0rUFy.js.map} +1 -1
  22. package/build/server/chunks/{hooks.server-D31Irsqw.js → hooks.server-DHvv3JCJ.js} +162 -29
  23. package/build/server/chunks/hooks.server-DHvv3JCJ.js.map +1 -0
  24. package/build/server/chunks/{string-CafUlmcI.js → string-SLyGnEy-.js} +6 -1
  25. package/build/server/chunks/{string-CafUlmcI.js.map → string-SLyGnEy-.js.map} +1 -1
  26. package/build/server/index.js +2 -2
  27. package/build/server/index.js.map +1 -1
  28. package/build/server/manifest.js +3 -3
  29. package/build/server/manifest.js.map +1 -1
  30. package/dist/api/metadata.js +15 -4
  31. package/dist/api/register.js +2 -0
  32. package/dist/api/session.js +2 -0
  33. package/dist/api/users.js +6 -1
  34. package/dist/audit.d.ts +84 -0
  35. package/dist/audit.js +125 -0
  36. package/dist/auth.d.ts +1 -0
  37. package/dist/auth.js +10 -2
  38. package/dist/cli.js +95 -31
  39. package/dist/config.d.ts +14 -8
  40. package/dist/config.js +20 -10
  41. package/dist/database.d.ts +12 -0
  42. package/dist/database.js +28 -2
  43. package/dist/io.d.ts +4 -0
  44. package/dist/io.js +9 -0
  45. package/dist/requests.d.ts +1 -2
  46. package/dist/requests.js +1 -1
  47. package/package.json +1 -1
  48. package/build/client/_app/immutable/chunks/LvObEX8u.js +0 -3
  49. package/build/client/_app/immutable/chunks/LvObEX8u.js.br +0 -0
  50. package/build/client/_app/immutable/chunks/LvObEX8u.js.gz +0 -0
  51. package/build/client/_app/immutable/entry/app.DN-14WEp.js.br +0 -0
  52. package/build/client/_app/immutable/entry/app.DN-14WEp.js.gz +0 -0
  53. package/build/client/_app/immutable/entry/start.AjI7jPvA.js +0 -1
  54. package/build/client/_app/immutable/entry/start.AjI7jPvA.js.br +0 -2
  55. package/build/client/_app/immutable/entry/start.AjI7jPvA.js.gz +0 -0
  56. package/build/client/_app/immutable/nodes/1.CYGWa5Ht.js.br +0 -0
  57. package/build/client/_app/immutable/nodes/1.CYGWa5Ht.js.gz +0 -0
  58. package/build/server/chunks/hooks.server-D31Irsqw.js.map +0 -1
@@ -10,12 +10,12 @@ return {
10
10
  assets: new Set(["icons/brands.svg","icons/light.svg","icons/regular.svg","icons/solid.svg","styles.css"]),
11
11
  mimeTypes: {".svg":"image/svg+xml",".css":"text/css"},
12
12
  _: {
13
- client: {start:"_app/immutable/entry/start.AjI7jPvA.js",app:"_app/immutable/entry/app.DN-14WEp.js",imports:["_app/immutable/entry/start.AjI7jPvA.js","_app/immutable/chunks/LvObEX8u.js","_app/immutable/chunks/BZOe2Jko.js","_app/immutable/chunks/uU8Mt6Mg.js","_app/immutable/chunks/BK1-xGGj.js","_app/immutable/chunks/sfKJ2mhH.js","_app/immutable/entry/app.DN-14WEp.js","_app/immutable/chunks/uU8Mt6Mg.js","_app/immutable/chunks/BK1-xGGj.js","_app/immutable/chunks/DsnmJJEf.js","_app/immutable/chunks/BZOe2Jko.js","_app/immutable/chunks/sfKJ2mhH.js","_app/immutable/chunks/DGhIdZ_j.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
13
+ client: {start:"_app/immutable/entry/start.BeJCp-7l.js",app:"_app/immutable/entry/app.ZFo0Iz7Y.js",imports:["_app/immutable/entry/start.BeJCp-7l.js","_app/immutable/chunks/BT6JVi7A.js","_app/immutable/chunks/BZOe2Jko.js","_app/immutable/chunks/uU8Mt6Mg.js","_app/immutable/chunks/BK1-xGGj.js","_app/immutable/chunks/sfKJ2mhH.js","_app/immutable/entry/app.ZFo0Iz7Y.js","_app/immutable/chunks/uU8Mt6Mg.js","_app/immutable/chunks/BK1-xGGj.js","_app/immutable/chunks/DsnmJJEf.js","_app/immutable/chunks/BZOe2Jko.js","_app/immutable/chunks/sfKJ2mhH.js","_app/immutable/chunks/DGhIdZ_j.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
14
14
  nodes: [
15
15
  __memo(() => import('./chunks/0-B8fDicB8.js')),
16
- __memo(() => import('./chunks/1-ChHp-lcj.js')),
16
+ __memo(() => import('./chunks/1-IUsQDUky.js')),
17
17
  __memo(() => import('./chunks/2-CVTt4PZM.js')),
18
- __memo(() => import('./chunks/3-qz4gvEJj.js')),
18
+ __memo(() => import('./chunks/3-BfZcxicd.js')),
19
19
  __memo(() => import('./chunks/4-3AO_VRm0.js')),
20
20
  __memo(() => import('./chunks/5-sUeA0D7s.js')),
21
21
  __memo(() => import('./chunks/6-BqCt3ZcB.js'))
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sources":["../../.svelte-kit/adapter-node/manifest.js"],"sourcesContent":["export const manifest = (() => {\nfunction __memo(fn) {\n\tlet value;\n\treturn () => value ??= (value = fn());\n}\n\nreturn {\n\tappDir: \"_app\",\n\tappPath: \"_app\",\n\tassets: new Set([\"icons/brands.svg\",\"icons/light.svg\",\"icons/regular.svg\",\"icons/solid.svg\",\"styles.css\"]),\n\tmimeTypes: {\".svg\":\"image/svg+xml\",\".css\":\"text/css\"},\n\t_: {\n\t\tclient: {start:\"_app/immutable/entry/start.AjI7jPvA.js\",app:\"_app/immutable/entry/app.DN-14WEp.js\",imports:[\"_app/immutable/entry/start.AjI7jPvA.js\",\"_app/immutable/chunks/LvObEX8u.js\",\"_app/immutable/chunks/BZOe2Jko.js\",\"_app/immutable/chunks/uU8Mt6Mg.js\",\"_app/immutable/chunks/BK1-xGGj.js\",\"_app/immutable/chunks/sfKJ2mhH.js\",\"_app/immutable/entry/app.DN-14WEp.js\",\"_app/immutable/chunks/uU8Mt6Mg.js\",\"_app/immutable/chunks/BK1-xGGj.js\",\"_app/immutable/chunks/DsnmJJEf.js\",\"_app/immutable/chunks/BZOe2Jko.js\",\"_app/immutable/chunks/sfKJ2mhH.js\",\"_app/immutable/chunks/DGhIdZ_j.js\"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},\n\t\tnodes: [\n\t\t\t__memo(() => import('./nodes/0.js')),\n\t\t\t__memo(() => import('./nodes/1.js')),\n\t\t\t__memo(() => import('./nodes/2.js')),\n\t\t\t__memo(() => import('./nodes/3.js')),\n\t\t\t__memo(() => import('./nodes/4.js')),\n\t\t\t__memo(() => import('./nodes/5.js')),\n\t\t\t__memo(() => import('./nodes/6.js'))\n\t\t],\n\t\tremotes: {\n\t\t\t\n\t\t},\n\t\troutes: [\n\t\t\t{\n\t\t\t\tid: \"/_axium/default\",\n\t\t\t\tpattern: /^\\/_axium\\/default\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 2 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/account\",\n\t\t\t\tpattern: /^\\/account\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 3 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/login\",\n\t\t\t\tpattern: /^\\/login\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 4 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/logout\",\n\t\t\t\tpattern: /^\\/logout\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 5 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/register\",\n\t\t\t\tpattern: /^\\/register\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 6 },\n\t\t\t\tendpoint: null\n\t\t\t}\n\t\t],\n\t\tprerendered_routes: new Set([]),\n\t\tmatchers: async () => {\n\t\t\t\n\t\t\treturn { };\n\t\t},\n\t\tserver_assets: {}\n\t}\n}\n})();\n\nexport const prerendered = new Set([]);\n\nexport const base = \"\";"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sources":["../../.svelte-kit/adapter-node/manifest.js"],"sourcesContent":["export const manifest = (() => {\nfunction __memo(fn) {\n\tlet value;\n\treturn () => value ??= (value = fn());\n}\n\nreturn {\n\tappDir: \"_app\",\n\tappPath: \"_app\",\n\tassets: new Set([\"icons/brands.svg\",\"icons/light.svg\",\"icons/regular.svg\",\"icons/solid.svg\",\"styles.css\"]),\n\tmimeTypes: {\".svg\":\"image/svg+xml\",\".css\":\"text/css\"},\n\t_: {\n\t\tclient: {start:\"_app/immutable/entry/start.BeJCp-7l.js\",app:\"_app/immutable/entry/app.ZFo0Iz7Y.js\",imports:[\"_app/immutable/entry/start.BeJCp-7l.js\",\"_app/immutable/chunks/BT6JVi7A.js\",\"_app/immutable/chunks/BZOe2Jko.js\",\"_app/immutable/chunks/uU8Mt6Mg.js\",\"_app/immutable/chunks/BK1-xGGj.js\",\"_app/immutable/chunks/sfKJ2mhH.js\",\"_app/immutable/entry/app.ZFo0Iz7Y.js\",\"_app/immutable/chunks/uU8Mt6Mg.js\",\"_app/immutable/chunks/BK1-xGGj.js\",\"_app/immutable/chunks/DsnmJJEf.js\",\"_app/immutable/chunks/BZOe2Jko.js\",\"_app/immutable/chunks/sfKJ2mhH.js\",\"_app/immutable/chunks/DGhIdZ_j.js\"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},\n\t\tnodes: [\n\t\t\t__memo(() => import('./nodes/0.js')),\n\t\t\t__memo(() => import('./nodes/1.js')),\n\t\t\t__memo(() => import('./nodes/2.js')),\n\t\t\t__memo(() => import('./nodes/3.js')),\n\t\t\t__memo(() => import('./nodes/4.js')),\n\t\t\t__memo(() => import('./nodes/5.js')),\n\t\t\t__memo(() => import('./nodes/6.js'))\n\t\t],\n\t\tremotes: {\n\t\t\t\n\t\t},\n\t\troutes: [\n\t\t\t{\n\t\t\t\tid: \"/_axium/default\",\n\t\t\t\tpattern: /^\\/_axium\\/default\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 2 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/account\",\n\t\t\t\tpattern: /^\\/account\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 3 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/login\",\n\t\t\t\tpattern: /^\\/login\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 4 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/logout\",\n\t\t\t\tpattern: /^\\/logout\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 5 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/register\",\n\t\t\t\tpattern: /^\\/register\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 6 },\n\t\t\t\tendpoint: null\n\t\t\t}\n\t\t],\n\t\tprerendered_routes: new Set([]),\n\t\tmatchers: async () => {\n\t\t\t\n\t\t\treturn { };\n\t\t},\n\t\tserver_assets: {}\n\t}\n}\n})();\n\nexport const prerendered = new Set([]);\n\nexport const base = \"\";"],"names":[],"mappings":"AAAY,MAAC,QAAQ,GAAG,CAAC,MAAM;AAC/B,SAAS,MAAM,CAAC,EAAE,EAAE;AACpB,CAAC,IAAI,KAAK;AACV,CAAC,OAAO,MAAM,KAAK,MAAM,KAAK,GAAG,EAAE,EAAE,CAAC;AACtC;;AAEA,OAAO;AACP,CAAC,MAAM,EAAE,MAAM;AACf,CAAC,OAAO,EAAE,MAAM;AAChB,CAAC,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;AAC3G,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC;AACtD,CAAC,CAAC,EAAE;AACJ,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,wCAAwC,CAAC,GAAG,CAAC,sCAAsC,CAAC,OAAO,CAAC,CAAC,wCAAwC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,sCAAsC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAAC,KAAK,CAAC;AACjoB,EAAE,KAAK,EAAE;AACT,GAAG,MAAM,CAAC,MAAM,OAAO,wBAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,wBAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,wBAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,wBAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,wBAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,wBAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,wBAAc,CAAC;AACtC,GAAG;AACH,EAAE,OAAO,EAAE;AACX;AACA,GAAG;AACH,EAAE,MAAM,EAAE;AACV,GAAG;AACH,IAAI,EAAE,EAAE,iBAAiB;AACzB,IAAI,OAAO,EAAE,wBAAwB;AACrC,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAClD,IAAI,QAAQ,EAAE;AACd,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,UAAU;AAClB,IAAI,OAAO,EAAE,gBAAgB;AAC7B,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAClD,IAAI,QAAQ,EAAE;AACd,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,QAAQ;AAChB,IAAI,OAAO,EAAE,cAAc;AAC3B,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAClD,IAAI,QAAQ,EAAE;AACd,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,SAAS;AACjB,IAAI,OAAO,EAAE,eAAe;AAC5B,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAClD,IAAI,QAAQ,EAAE;AACd,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,WAAW;AACnB,IAAI,OAAO,EAAE,iBAAiB;AAC9B,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAClD,IAAI,QAAQ,EAAE;AACd;AACA,GAAG;AACH,EAAE,kBAAkB,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;AACjC,EAAE,QAAQ,EAAE,YAAY;AACxB;AACA,GAAG,OAAO,IAAI;AACd,EAAE,CAAC;AACH,EAAE,aAAa,EAAE;AACjB;AACA;AACA,CAAC;;AAEW,MAAC,WAAW,GAAG,IAAI,GAAG,CAAC,EAAE;;AAEzB,MAAC,IAAI,GAAG;;;;"}
@@ -2,13 +2,24 @@ import { requestMethods } from '@axium/core/requests';
2
2
  import pkg from '../../package.json' with { type: 'json' };
3
3
  import { config } from '../config.js';
4
4
  import { plugins } from '../plugins.js';
5
- import { error } from '../requests.js';
5
+ import { error, getToken } from '../requests.js';
6
6
  import { addRoute, routes } from '../routes.js';
7
+ import { getSessionAndUser } from '../auth.js';
7
8
  addRoute({
8
9
  path: '/api/metadata',
9
- async GET() {
10
- if (config.api.disable_metadata)
11
- error(401, 'API metadata is disabled');
10
+ async GET(event) {
11
+ if (!config.debug) {
12
+ const token = getToken(event);
13
+ if (!token)
14
+ error(401, 'Missing session token');
15
+ const session = await getSessionAndUser(token);
16
+ if (!session)
17
+ error(401, 'Invalid session');
18
+ if (!session.user.isAdmin)
19
+ error(403, 'User is not an administrator');
20
+ if (session.user.isSuspended)
21
+ error(403, 'User is suspended');
22
+ }
12
23
  return {
13
24
  version: pkg.version,
14
25
  routes: Object.fromEntries(routes
@@ -7,6 +7,7 @@ import config from '../config.js';
7
7
  import { database as db } from '../database.js';
8
8
  import { createSessionData, error, parseBody, withError } from '../requests.js';
9
9
  import { addRoute } from '../routes.js';
10
+ import { audit } from '../audit.js';
10
11
  // Map of user ID => challenge
11
12
  const registrations = new Map();
12
13
  async function OPTIONS(event) {
@@ -56,6 +57,7 @@ async function POST(event) {
56
57
  .values({ id: userId, name, email: email.toLowerCase() })
57
58
  .executeTakeFirstOrThrow()
58
59
  .catch(withError('Failed to create user'));
60
+ await audit('user_created', userId);
59
61
  await createPasskey({
60
62
  transports: [],
61
63
  ...registrationInfo.credential,
@@ -3,6 +3,7 @@ import { getSessionAndUser } from '../auth.js';
3
3
  import { database as db } from '../database.js';
4
4
  import { error, getToken, stripUser, withError } from '../requests.js';
5
5
  import { addRoute } from '../routes.js';
6
+ import { audit } from '../audit.js';
6
7
  addRoute({
7
8
  path: '/api/session',
8
9
  async GET(event) {
@@ -25,6 +26,7 @@ addRoute({
25
26
  .returningAll()
26
27
  .executeTakeFirstOrThrow()
27
28
  .catch((e) => (e.message == 'no result' ? error(404, 'Session does not exist') : error(400, 'Invalid session')));
29
+ await audit('logout', result.userId, { sessions: [result.id] });
28
30
  return omit(result, 'token');
29
31
  },
30
32
  });
package/dist/api/users.js CHANGED
@@ -8,6 +8,7 @@ import { config } from '../config.js';
8
8
  import { database as db } from '../database.js';
9
9
  import { createSessionData, error, parseBody, stripUser, withError } from '../requests.js';
10
10
  import { addRoute } from '../routes.js';
11
+ import { audit } from '../audit.js';
11
12
  const challenges = new Map();
12
13
  const params = { id: z.uuid() };
13
14
  /**
@@ -59,6 +60,7 @@ addRoute({
59
60
  .returningAll()
60
61
  .executeTakeFirstOrThrow()
61
62
  .catch(withError('Failed to delete user'));
63
+ await audit('user_deleted', userId);
62
64
  return result;
63
65
  },
64
66
  });
@@ -81,7 +83,9 @@ addRoute({
81
83
  async OPTIONS(event) {
82
84
  const userId = event.params.id;
83
85
  const { type } = await parseBody(event, UserAuthOptions);
84
- await getUser(userId).catch(withError('User does not exist', 404));
86
+ const user = await getUser(userId).catch(withError('User does not exist', 404));
87
+ if (user.isSuspended)
88
+ error(403, 'User is suspended');
85
89
  const passkeys = await getPasskeysByUserId(userId);
86
90
  if (!passkeys)
87
91
  error(409, 'No passkeys exists for this user');
@@ -211,6 +215,7 @@ addRoute({
211
215
  .returningAll()
212
216
  .execute()
213
217
  .catch(withError('Failed to delete one or more sessions'));
218
+ await audit('logout', userId, { sessions: result.map(s => s.id) });
214
219
  return result.map(s => omit(s, 'token'));
215
220
  },
216
221
  });
@@ -0,0 +1,84 @@
1
+ import type { Insertable } from 'kysely';
2
+ import * as z from 'zod';
3
+ import { type Schema } from './database.js';
4
+ export declare enum Severity {
5
+ Emergency = 0,
6
+ Alert = 1,
7
+ Critical = 2,
8
+ Error = 3,
9
+ Warning = 4,
10
+ Notice = 5,
11
+ Info = 6,
12
+ Debug = 7
13
+ }
14
+ export declare function styleSeverity(sev: Severity, align?: boolean): string;
15
+ export interface AuditEvent<T extends Record<string, unknown> = Record<string, unknown>> {
16
+ /** UUID of the event */
17
+ id: string;
18
+ /** UUID of the user that triggered the event. `null` for events triggered via the server CLI */
19
+ userID?: string | null;
20
+ /** When the event happened */
21
+ timestamp: Date;
22
+ /** How severe the event is */
23
+ severity: Severity;
24
+ /** Snake case name for the event */
25
+ name: string;
26
+ /** The source of the event. This should be a package name */
27
+ source: string;
28
+ /** Tags for the event. For example, `auth` for authentication events */
29
+ tags: string[];
30
+ /** Additional event specific data. */
31
+ extra: T;
32
+ }
33
+ export interface AuditEventInit extends Insertable<Schema['audit_log']> {
34
+ }
35
+ export declare function audit_raw(event: AuditEventInit): Promise<void>;
36
+ export interface $EventTypes {
37
+ user_created: never;
38
+ user_deleted: never;
39
+ new_session: {
40
+ id: string;
41
+ };
42
+ logout: {
43
+ sessions: string[];
44
+ };
45
+ acl_id_mismatch: {
46
+ item: string;
47
+ };
48
+ admin_change: {
49
+ user: string;
50
+ };
51
+ }
52
+ export type EventName = keyof $EventTypes;
53
+ export type EventExtra<T extends EventName> = $EventTypes[T];
54
+ export interface AuditEventConfigInit {
55
+ name: EventName;
56
+ source: string;
57
+ severity: Severity;
58
+ tags: string[];
59
+ /** Schema for the extra data */
60
+ extra?: z.core.$ZodShape;
61
+ noAutoSuspend?: boolean;
62
+ }
63
+ export interface AuditEventConfig {
64
+ name: EventName;
65
+ source: string;
66
+ severity: Severity;
67
+ tags: string[];
68
+ /** Schema for the extra data */
69
+ extra?: z.ZodObject;
70
+ noAutoSuspend?: boolean;
71
+ }
72
+ export declare function addEvent(init: AuditEventConfigInit): void;
73
+ export declare function audit<T extends EventName>(eventName: T, userId?: string, extra?: EventExtra<T>): Promise<void>;
74
+ export interface AuditFilter {
75
+ since?: Date;
76
+ until?: Date;
77
+ user?: string;
78
+ severity?: Severity;
79
+ source?: string;
80
+ tags?: string[];
81
+ event?: string;
82
+ cli?: boolean;
83
+ }
84
+ export declare function getEvents(filter: AuditFilter): Promise<AuditEvent[]>;
package/dist/audit.js ADDED
@@ -0,0 +1,125 @@
1
+ import { styleText } from 'node:util';
2
+ import { capitalize, omit } from 'utilium';
3
+ import * as z from 'zod';
4
+ import config from './config.js';
5
+ import { database } from './database.js';
6
+ import * as io from './io.js';
7
+ export var Severity;
8
+ (function (Severity) {
9
+ Severity[Severity["Emergency"] = 0] = "Emergency";
10
+ Severity[Severity["Alert"] = 1] = "Alert";
11
+ Severity[Severity["Critical"] = 2] = "Critical";
12
+ Severity[Severity["Error"] = 3] = "Error";
13
+ Severity[Severity["Warning"] = 4] = "Warning";
14
+ Severity[Severity["Notice"] = 5] = "Notice";
15
+ Severity[Severity["Info"] = 6] = "Info";
16
+ Severity[Severity["Debug"] = 7] = "Debug";
17
+ })(Severity || (Severity = {}));
18
+ const severityFormat = {
19
+ [Severity.Emergency]: ['bgRedBright', 'white', 'underline'],
20
+ [Severity.Alert]: ['bgRedBright', 'white'],
21
+ [Severity.Critical]: ['bold', 'redBright'],
22
+ [Severity.Error]: 'redBright',
23
+ [Severity.Warning]: 'yellowBright',
24
+ [Severity.Notice]: 'cyanBright',
25
+ [Severity.Info]: [],
26
+ [Severity.Debug]: ['dim'],
27
+ };
28
+ export function styleSeverity(sev, align = false) {
29
+ const text = align ? Severity[sev].padEnd(9) : Severity[sev];
30
+ return styleText(severityFormat[sev], text.toUpperCase());
31
+ }
32
+ function output(event) {
33
+ if (event.severity > Severity[capitalize(config.audit.min_severity)])
34
+ return;
35
+ console.error('[audit]', styleText('dim', io.prettyDate(event.timestamp)), styleSeverity(event.severity), event.name);
36
+ }
37
+ export async function audit_raw(event) {
38
+ if (!config.audit.allow_raw) {
39
+ io.warn('[audit] Ignoring raw event (disabled)');
40
+ return;
41
+ }
42
+ const result = await database.insertInto('audit_log').values(event).returningAll().executeTakeFirstOrThrow();
43
+ output(result);
44
+ }
45
+ const events = new Map();
46
+ export function addEvent(init) {
47
+ if (events.has(init.name))
48
+ throw io.error(`Can not register multiple events with the same name ("${init.name}")`);
49
+ const config = {
50
+ ...init,
51
+ extra: init.extra ? z.object(init.extra) : undefined,
52
+ };
53
+ events.set(init.name, config);
54
+ }
55
+ export async function audit(eventName, userId, extra) {
56
+ const cfg = events.get(eventName);
57
+ if (!cfg) {
58
+ io.warn('Ignoring audit event with unknown event name: ' + eventName);
59
+ return;
60
+ }
61
+ try {
62
+ if (cfg.extra)
63
+ extra = cfg.extra.parse(extra);
64
+ }
65
+ catch (e) {
66
+ io.error('Audit event has invalid extra data: ' + eventName);
67
+ return;
68
+ }
69
+ const event = await database
70
+ .insertInto('audit_log')
71
+ .values({ ...omit(cfg, 'extra'), extra, userId })
72
+ .returningAll()
73
+ .executeTakeFirstOrThrow();
74
+ output(event);
75
+ if (userId && !cfg.noAutoSuspend && event.severity < Severity[capitalize(config.audit.auto_suspend)]) {
76
+ await database
77
+ .updateTable('users')
78
+ .set({ isSuspended: true })
79
+ .where('id', '=', userId)
80
+ .returningAll()
81
+ .executeTakeFirstOrThrow()
82
+ .then(user => console.error('[audit] Auto-suspended user:', user.id, `<${user.email}>`))
83
+ .catch(() => null);
84
+ }
85
+ }
86
+ export async function getEvents(filter) {
87
+ let query = database.selectFrom('audit_log').selectAll();
88
+ if (filter.cli)
89
+ query = query.where('userId', 'is', null);
90
+ else if (filter.user)
91
+ query = query.where('userId', '=', filter.user);
92
+ if (filter.source)
93
+ query = query.where('source', '=', filter.source);
94
+ if (filter.event)
95
+ query = query.where('name', '=', filter.event);
96
+ if (filter.tags)
97
+ query = query.where('tags', '@>', filter.tags);
98
+ if (filter.severity)
99
+ query = query.where('severity', '<=', filter.severity);
100
+ if (filter.since)
101
+ query = query.where('timestamp', '>=', filter.since);
102
+ if (filter.until)
103
+ query = query.where('timestamp', '<=', filter.until);
104
+ return await query.execute();
105
+ }
106
+ // Register built-ins
107
+ addEvent({ source: '@axium/server', name: 'user_created', severity: Severity.Info, tags: ['user'] });
108
+ addEvent({ source: '@axium/server', name: 'user_deleted', severity: Severity.Info, tags: ['user'] });
109
+ addEvent({ source: '@axium/server', name: 'new_session', severity: Severity.Info, tags: ['user'], extra: { id: z.string() } });
110
+ addEvent({ source: '@axium/server', name: 'logout', severity: Severity.Info, tags: ['user'], extra: { sessions: z.array(z.string()) } });
111
+ addEvent({
112
+ source: '@axium/server',
113
+ name: 'admin_change',
114
+ severity: Severity.Notice,
115
+ tags: ['cli'],
116
+ extra: { user: z.string() },
117
+ });
118
+ addEvent({
119
+ source: '@axium/server',
120
+ name: 'acl_id_mismatch',
121
+ severity: Severity.Critical,
122
+ tags: ['acl', 'auth'],
123
+ extra: { item: z.string() },
124
+ noAutoSuspend: true,
125
+ });
package/dist/auth.d.ts CHANGED
@@ -7,6 +7,7 @@ import { type Schema } from './database.js';
7
7
  import type { RequestEvent } from './requests.js';
8
8
  export interface UserInternal extends User {
9
9
  isAdmin: boolean;
10
+ isSuspended: boolean;
10
11
  /** Tags are internal, roles are public */
11
12
  tags: string[];
12
13
  }
package/dist/auth.js CHANGED
@@ -3,6 +3,7 @@ import { omit } from 'utilium';
3
3
  import * as acl from './acl.js';
4
4
  import { database as db, userFromId } from './database.js';
5
5
  import { error, getToken, withError } from './requests.js';
6
+ import { audit } from './audit.js';
6
7
  export async function getUser(id) {
7
8
  return await db.selectFrom('users').selectAll().where('id', '=', id).executeTakeFirstOrThrow();
8
9
  }
@@ -22,6 +23,7 @@ export async function createSession(userId, elevated = false) {
22
23
  created: new Date(),
23
24
  };
24
25
  await db.insertInto('sessions').values(session).execute();
26
+ await audit('new_session', userId, { id: session.id });
25
27
  return session;
26
28
  }
27
29
  export async function getSessionAndUser(token) {
@@ -90,6 +92,8 @@ export async function checkAuthForUser(event, userId, sensitive = false) {
90
92
  if (!token)
91
93
  throw error(401, 'Missing token');
92
94
  const session = await getSessionAndUser(token).catch(withError('Invalid or expired session', 401));
95
+ if (session.user.isSuspended)
96
+ error(403, 'User is suspended');
93
97
  if (session.userId !== userId) {
94
98
  if (!session.user?.isAdmin)
95
99
  error(403, 'User ID mismatch');
@@ -125,14 +129,18 @@ export async function checkAuthForItem(event, itemType, itemId, permission) {
125
129
  return result;
126
130
  if (!session)
127
131
  error(403, 'Access denied');
132
+ if (session.user.isSuspended)
133
+ error(403, 'User is suspended');
128
134
  if (session.userId == item.userId)
129
135
  return result;
130
136
  result.fromACL = true;
131
137
  if (!item.acl || !item.acl.length)
132
138
  error(403, 'Access denied');
133
139
  const [control] = item.acl;
134
- if (control.userId !== session.userId)
135
- error(500, 'Access control entry does not match session user'); // @todo: audit log
140
+ if (control.userId !== session.userId) {
141
+ await audit('acl_id_mismatch', session.userId, { item: itemId });
142
+ error(500, 'Access control entry does not match session user');
143
+ }
136
144
  if (control.permission >= permission)
137
145
  return result;
138
146
  error(403, 'Access denied');