diff --git a/package-lock.json b/package-lock.json index 2b53587..4eb1a00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,9 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/crud-ui": "^0.0.17", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.7.7", - "@sealcode/jdd-editor": "^0.1.23", - "@sealcode/sealgen": "^0.17.35", + "@sealcode/jdd": "^0.8.0", + "@sealcode/jdd-editor": "^0.2.0", + "@sealcode/sealgen": "^0.18.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/ts-predicates": "^0.6.2", "@types/kill-port": "^2.0.0", @@ -40,7 +40,7 @@ "nodemon": "^3.0.1", "object-path": "^0.11.8", "qs": "^6.12.0", - "sealious": "^0.20.1", + "sealious": "^0.21.2", "slug": "^9.1.0", "stimulus": "^3.2.2", "tempstream": "^0.4.6", @@ -1261,6 +1261,279 @@ "node": ">= 18" } }, + "node_modules/@sealcode/crud-ui/node_modules/@sealcode/sealgen": { + "version": "0.17.35", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.17.35.tgz", + "integrity": "sha512-gbh9r2KtZFMrzPuley1SSfRC4C+3gOGf7v1PewgaPFBZHsfP7D2Bsgs8Gp0kgf2eWGcBvm1RECLn82p5w67r6g==", + "dependencies": { + "@koa/router": "^12.0.1", + "@sealcode/file-manager": "^1.0.2", + "@sealcode/ts-predicates": "^0.4.3", + "chokidar": "^3.6.0", + "colord": "^2.9.3", + "deepmerge": "^4.3.1", + "esbuild": "^0.20.0", + "escape-goat": "^4.0.0", + "fonsta": "^1.1.1", + "google-fonts-helper": "^3.4.1", + "husky": "^9.1.7", + "is-what": "^4.1.16", + "js-convert-case": "^4.2.0", + "json5": "^2.2.3", + "locreq": "^3.0.0", + "md5": "^2.3.0", + "merge": "^2.1.1", + "prettier": "^2.7.1", + "prompts": "^2.4.2", + "recursive-readdir": "^2.2.3", + "tempfile": "^5.0.0", + "tempstream": "^0.4.6", + "tiny-glob": "^0.2.9", + "ws": "^8.16.0", + "yargs": "^17.6.2" + }, + "bin": { + "sealgen": "lib/cli.js" + }, + "peerDependencies": { + "koa": "^2.13.0", + "koa-responsive-image-router": "^0.2.24", + "sealious": "^0.20" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/@sealcode/sealgen/node_modules/@koa/router": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.2.tgz", + "integrity": "sha512-sYcHglGKTxGF+hQ6x67xDfkE9o+NhVlRHBqq6gLywaMc6CojK/5vFZByphdonKinYlMLkEkacm+HEse9HzwgTA==", + "dependencies": { + "debug": "^4.3.4", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.3.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/@sealcode/ts-predicates": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.4.3.tgz", + "integrity": "sha512-UNSEacu7Ye8q0N8AJCJy37oJvv3w2OXKGkUnP7xO5lOY9DQviDPRDQhVaZdJ3/xMzXLm4UE3389ihctrPaov/A==" + }, + "node_modules/@sealcode/crud-ui/node_modules/@types/object-hash": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz", + "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==", + "peer": true + }, + "node_modules/@sealcode/crud-ui/node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "peer": true + }, + "node_modules/@sealcode/crud-ui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "peer": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "peer": true + }, + "node_modules/@sealcode/crud-ui/node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "peer": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/sealious": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.20.1.tgz", + "integrity": "sha512-DDzIDNYWtdSnZ5wqPdlIK/PKpkPER1lqoMgsxEPw0AjDZxYOLAl3Okil8z36T8nHsNPelmSntndgDfgads91xQ==", + "peer": true, + "dependencies": { + "@koa/router": "^12.0.1", + "@sealcode/file-manager": "^1.0.1", + "@sealcode/ts-predicates": "^0.4.3", + "@types/boom": "^7.3.0", + "@types/clone": "^0.1.30", + "@types/color": "^3.0.1", + "@types/color-hash": "^1.0.0", + "@types/escape-html": "^1.0.0", + "@types/koa": "^2.11.6", + "@types/koa-mount": "^4.0.0", + "@types/koa-qs": "^2.0.0", + "@types/koa-send": "^4.1.2", + "@types/koa-static": "^4.0.1", + "@types/mjml": "^4.0.4", + "@types/mongodb": "^3.5.20", + "@types/node": "^20.0", + "@types/nodemailer": "^6.4.0", + "@types/object-hash": "^1.3.3", + "@types/sanitize-html": "^2.11.0", + "@types/uuid": "^8.3.0", + "boom": "^7.3.0", + "chalk": "^4.1.0", + "clone": "^1.0.2", + "color": "latest", + "color-hash": "^1.0.3", + "commonmark": "^0.31.0", + "cron": "^2.1.0", + "csv-stringify": "^6.4.5", + "deepmerge": "^4.2.2", + "dot-prop": "^8.0.2", + "emittery": "0.8.1", + "escape-html": "^1.0.3", + "get-port": "^5.1.1", + "koa": "^2.13.0", + "koa-body": "^4.2.0", + "koa-mount": "^4.0.0", + "koa-qs": "^3.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "locreq": "^3.0.0", + "mjml": "^4.2.0", + "mongodb": "^6.5.0", + "nanoid": "^5.0.9", + "nodemailer": "^6.4.6", + "object-hash": "^2.0.3", + "pg": "^8.13.1", + "pretty-ms": "^7.0.0", + "qs": "^6.12.0", + "sanitize-html": "^1.13.0", + "typedoc": "^0.17.8", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=21.0" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/sealious/node_modules/@koa/router": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.2.tgz", + "integrity": "sha512-sYcHglGKTxGF+hQ6x67xDfkE9o+NhVlRHBqq6gLywaMc6CojK/5vFZByphdonKinYlMLkEkacm+HEse9HzwgTA==", + "peer": true, + "dependencies": { + "debug": "^4.3.4", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.3.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@sealcode/file-manager": { "version": "1.0.2", "license": "ISC", @@ -1273,9 +1546,9 @@ } }, "node_modules/@sealcode/jdd": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.7.7.tgz", - "integrity": "sha512-L99aj9q6V1sRqFmMmtwKuzS6wNId22mKxJQc0pQH1StumYVpDfiSmtknPD6ZNLRWMGtmN7PYqal3cqBk+X4vTQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.0.tgz", + "integrity": "sha512-0esGO0j922FK3rYs+OmWbp0SWAQWkPaidNzvrq2dyaj0SyPU7B0vZZOYjzboICyvqBkMZWbf+YXNK/zzYs18EA==", "dependencies": { "@sealcode/file-manager": "^1.0.2", "@sealcode/ts-predicates": "^0.5.3", @@ -1292,23 +1565,23 @@ "uuid": "^9.0.1" }, "peerDependencies": { - "sealious": "^0.20" + "sealious": "^0.21" } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.1.23", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.1.23.tgz", - "integrity": "sha512-PUogLAYskZ4LtbOwixP/KyexTUoWT8Z/Ht4r+k1spa6+4t+z0MK15AD6Oj3Gs8vfr20/YHZjMHiG+5NHvsDdDg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.0.tgz", + "integrity": "sha512-zZGcfqanv/c5IefPASpLjB12YM3SG0pWpIjlpxIVh0XuvvLLPPtUemFyAJD4evgA+MXmph9fTlj4F8ki/9ImCw==", "dependencies": { "@koa/router": "^13.1.0", - "@sealcode/jdd": "^0.7.7", + "@sealcode/jdd": "^0.8.0", "@sealcode/sealcodemirror": "^5.70.0-beta5", - "@sealcode/sealgen": "^0.17.31", + "@sealcode/sealgen": "^0.18", "@types/object-path": "^0.11.4", "@types/throttle-debounce": "^5.0.2", "@types/turndown": "^5.0.5", "object-path": "^0.11.8", - "sealious": "^0.20.0", + "sealious": "^0.21.0", "stimulus": "^3.2.2", "tempstream": "^0.4.6", "throttle-debounce": "^5.0.2", @@ -1352,9 +1625,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "node_modules/@sealcode/sealgen": { - "version": "0.17.35", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.17.35.tgz", - "integrity": "sha512-gbh9r2KtZFMrzPuley1SSfRC4C+3gOGf7v1PewgaPFBZHsfP7D2Bsgs8Gp0kgf2eWGcBvm1RECLn82p5w67r6g==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.18.0.tgz", + "integrity": "sha512-R6D5NWILQDjZKkhQ4Q854T+o/fG+fcQKaj8dFQmEPiX7lsXYaQ4zQ5YuyRBfavM0RyuXl8Nj0DQqpt8D5NB8jQ==", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", @@ -1388,7 +1661,7 @@ "peerDependencies": { "koa": "^2.13.0", "koa-responsive-image-router": "^0.2.24", - "sealious": "^0.20" + "sealious": "^0.21" } }, "node_modules/@sealcode/sealgen/node_modules/@sealcode/ts-predicates": { @@ -1543,6 +1816,14 @@ "version": "0.1.30", "license": "MIT" }, + "node_modules/@types/color": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.6.tgz", + "integrity": "sha512-NMiNcZFRUAiUUCCf7zkAelY8eV3aKqfbzyFQlXpPIEeoNDbsEHGpb854V3gzTsGKYj830I5zPuOwU/TP5/cW6A==", + "dependencies": { + "@types/color-convert": "*" + } + }, "node_modules/@types/color-convert": { "version": "2.0.3", "license": "MIT", @@ -11488,9 +11769,9 @@ } }, "node_modules/sealious": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.20.1.tgz", - "integrity": "sha512-DDzIDNYWtdSnZ5wqPdlIK/PKpkPER1lqoMgsxEPw0AjDZxYOLAl3Okil8z36T8nHsNPelmSntndgDfgads91xQ==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.2.tgz", + "integrity": "sha512-JNLVBJ2PqhZbktmkNheLFBfj+GgMcpUZ40Bpm9Qyi2z6Md3bgBgF+Yh9856AoktemO7pR2eRSIxKOX9eFxKjUw==", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.1", @@ -11552,15 +11833,6 @@ "version": "0.4.3", "license": "ISC" }, - "node_modules/sealious/node_modules/@types/color": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.6.tgz", - "integrity": "sha512-NMiNcZFRUAiUUCCf7zkAelY8eV3aKqfbzyFQlXpPIEeoNDbsEHGpb854V3gzTsGKYj830I5zPuOwU/TP5/cW6A==", - "license": "MIT", - "dependencies": { - "@types/color-convert": "*" - } - }, "node_modules/sealious/node_modules/@types/object-hash": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz", diff --git a/package.json b/package.json index 0ae436e..3afd35f 100644 --- a/package.json +++ b/package.json @@ -76,9 +76,9 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/crud-ui": "^0.0.17", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.7.7", - "@sealcode/jdd-editor": "^0.1.23", - "@sealcode/sealgen": "^0.17.35", + "@sealcode/jdd": "^0.8.0", + "@sealcode/jdd-editor": "^0.2.0", + "@sealcode/sealgen": "^0.18.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/ts-predicates": "^0.6.2", "@types/kill-port": "^2.0.0", @@ -101,7 +101,7 @@ "nodemon": "^3.0.1", "object-path": "^0.11.8", "qs": "^6.12.0", - "sealious": "^0.20.1", + "sealious": "^0.21.2", "slug": "^9.1.0", "stimulus": "^3.2.2", "tempstream": "^0.4.6", diff --git a/src/back/collections/collections.ts b/src/back/collections/collections.ts index 5a23f97..e7f0f5a 100644 --- a/src/back/collections/collections.ts +++ b/src/back/collections/collections.ts @@ -8,7 +8,6 @@ import _NavbarLinks from "./navbar-links.js"; import _Pages from "./pages.js"; import _PasswordResetIntents from "./password-reset-intents.js"; import _Redirects from "./redirects.js"; -import _UserRoles from "./user-roles.js"; import _Users from "./users.js"; export const Globals = new _Globals(); @@ -18,7 +17,6 @@ export const NavbarLinks = new _NavbarLinks(); export const Pages = new _Pages(); export const PasswordResetIntents = new _PasswordResetIntents(); export const Redirects = new _Redirects(); -export const UserRoles = new _UserRoles(); export const Users = new _Users(); export const collections = { @@ -30,6 +28,5 @@ export const collections = { pages: Pages, "password-reset-intents": PasswordResetIntents, redirects: Redirects, - "user-roles": UserRoles, users: Users, }; diff --git a/src/back/collections/user-roles.test.ts b/src/back/collections/user-roles.test.ts deleted file mode 100644 index 79a4763..0000000 --- a/src/back/collections/user-roles.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import assert from "assert"; -import axios from "axios"; -import { Context, TestUtils } from "sealious"; -import { withProdApp } from "../test_utils/with-prod-app.js"; -import { createAdmin, createAUser } from "../test_utils/users.js"; -import Users from "./users.js"; - -describe("user-roles", () => { - it("rejects when given an empty role", async () => - withProdApp(async ({ app, rest_api }) => { - const [user, session] = await createAdmin(app, rest_api); - await TestUtils.assertThrowsAsync( - async () => { - return rest_api.post( - `/api/v1/collections/user-roles`, - { - user: user.id, - }, - session - ); - }, - (e) => { - console.error(e); - assert.equal( - e?.response.data.data.field_messages.role?.message, - "Missing value for field 'role'." - ); - } - ); - })); - - it("accepts correct dataset", async () => - withProdApp(async ({ app, base_url, rest_api }) => { - const [user, session] = await createAdmin(app, rest_api); - const response = await axios.post( - `${base_url}/api/v1/collections/user-roles`, - { - user: user.id, - role: "admin", - }, - session - ); - assert.equal(response.status, 201); - })); - - it("get user roles with admin", async () => - withProdApp(async ({ app, rest_api }) => { - const [user] = await createAdmin(app, rest_api); - const roles = await Users.getRoles( - new Context(app, new Date().getTime(), user.id) - ); - assert.ok(roles.includes("admin")); - })); - - it("get user with no roles", async () => - withProdApp(async ({ app }) => { - const user = await createAUser(app, "normal"); - const roles = await Users.getRoles( - new Context(app, new Date().getTime(), user.id) - ); - assert.ok(roles.length === 0); - })); - - it("get no roles for no logged user", async () => - withProdApp(async ({ app }) => { - const roles = await Users.getRoles( - new Context(app, new Date().getTime(), null) - ); - assert.ok(roles.length === 0); - })); -}); diff --git a/src/back/collections/user-roles.ts b/src/back/collections/user-roles.ts deleted file mode 100644 index befb05d..0000000 --- a/src/back/collections/user-roles.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { App, Policy } from "sealious"; -import { Collection, FieldTypes, Policies } from "sealious"; -import { Roles } from "../policy-types/roles.js"; - -export default class UserRoles extends Collection { - name = "user-roles"; - fields = { - role: new FieldTypes.Text().setRequired(true), - user: new FieldTypes.SingleReference("users"), - }; - - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - policies = { - create: new Roles(["admin"]), - delete: new Roles(["admin"]), - show: new Policies.Or([ - new Policies.UserReferencedInField("user"), - new Roles(["admin"]), - ]), - edit: new Policies.Noone(), - } as { [policy: string]: Policy }; // this `as` statement allows the policies to be overwritten; - - async init(app: App, collection_name: string) { - await super.init(app, collection_name); - app.on("started", async () => { - const roles = app.collections["user-roles"]; - if (!roles) { - throw new Error("roles undefined"); - } - for (const action of ["create", "delete"]) { - const policy = roles?.getPolicy(action); - if (policy instanceof Policies.Public) { - app.Logger.warn( - "USER POLICY", - ` collection is using access strategy for ${action} action. Anyone can change anyone elses role. This is the default behavior and you should overwrite it with ` - ); - } - } - }); - } -} diff --git a/src/back/collections/users.ts b/src/back/collections/users.ts index 3357bbb..f1e2c11 100644 --- a/src/back/collections/users.ts +++ b/src/back/collections/users.ts @@ -1,4 +1,3 @@ -import type { Context } from "sealious"; import { App, Collections, FieldTypes, Policies } from "sealious"; import assert from "assert"; import TheApp from "../app.js"; @@ -9,10 +8,10 @@ export default class Users extends Collections.users { fields = { ...App.BaseCollections.users.fields, email: new FieldTypes.Email().setRequired(true), - roles: new FieldTypes.ReverseSingleReference({ - referencing_collection: "user-roles", - referencing_field: "user", - }), + roles: new FieldTypes.SettableBy( + new FieldTypes.StructuredArray({ role: new FieldTypes.Text() }), + new Roles(["admin"]) + ), }; defaultPolicy = new Policies.Or([new Policies.Themselves(), new Roles(["admin"])]); @@ -33,25 +32,13 @@ export default class Users extends Collections.users { "ADMIN", `Creating an admin account for ${app.manifest.admin_email}` ); - const { id } = await app.collections.users.suCreate({ + await app.collections.users.suCreate({ username, password: ADMIN_CREDENTIALS.password, email: ADMIN_CREDENTIALS.email, - roles: [], + roles: [{ role: "admin" }], }); - await app.collections["user-roles"].suCreate({ user: id, role: "admin" }); } }); } - - public static async getRoles(ctx: Context) { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - const rolesEntries = await (ctx.app as TheApp).collections["user-roles"] - .list(ctx) - .filter({ user: ctx.user_id || "" }) - .fetch(); - - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return rolesEntries.items.map((item) => item.get("role")); - } } diff --git a/src/back/policy-types/roles.test.ts b/src/back/policy-types/roles.test.ts index 5648824..01616b4 100644 --- a/src/back/policy-types/roles.test.ts +++ b/src/back/policy-types/roles.test.ts @@ -10,16 +10,11 @@ describe("roles", () => { roles: [], }); - const admin = await app.collections.users.suCreate({ + await app.collections.users.suCreate({ username: "someadmin", password: "admin-password", email: "admin@example.com", roles: [], }); - - await app.collections["user-roles"].suCreate({ - user: admin.id, - role: "admin", - }); })); }); diff --git a/src/back/policy-types/roles.ts b/src/back/policy-types/roles.ts index 5e11d4d..8b2c647 100644 --- a/src/back/policy-types/roles.ts +++ b/src/back/policy-types/roles.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/consistent-type-assertions */ -import type { ActionName, Collection, Context } from "sealious"; +import type { ActionName, Context } from "sealious"; import { Policies } from "sealious"; import { Policy, QueryTypes } from "sealious"; @@ -12,20 +12,12 @@ export class Roles extends Policy { } async countMatchingRoles(context: Context) { - const user_id = context.user_id; + const user_id = context.user_id as string; context.app.Logger.debug2("ROLES", "Checking the roles for user", user_id); const roles = await context.cache("roles_for_this_user", async () => { - const { items: user_roles } = await ( - context.app.collections["user-roles"] as Collection - ) - .suList() - .filter({ user: user_id }) - .fetch(); - const roles = user_roles.map( - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - (user_role) => user_role.get("role") as string - ); - return roles; + const user = await context.app.collections.users.suGetByID(user_id); + const roles = (user.get("roles") as { role: string }[])?.map((e) => e.role); + return roles || []; }); return this.allowed_roles.filter((allowed_role) => roles.includes(allowed_role)) diff --git a/src/back/test_utils/users.ts b/src/back/test_utils/users.ts index 2bb2833..5914481 100644 --- a/src/back/test_utils/users.ts +++ b/src/back/test_utils/users.ts @@ -4,12 +4,12 @@ import type Users from "../collections/users.js"; type Unpromisify = T extends Promise ? R : T; -export function createAUser(app: TheApp, username: string) { +export function createAUser(app: TheApp, username: string, roles: string[]) { return app.collections.users.suCreate({ username, email: `${username}@example.com`, password: "password", - roles: [], + roles: roles.map((role) => ({ role })), }); } @@ -17,11 +17,7 @@ export async function createAdmin( app: TheApp, rest_api: TestUtils.MockRestApi ): Promise<[CollectionItem, Unpromisify>]> { - const user = await createAUser(app, "super_user"); - await app.collections["user-roles"].suCreate({ - user: user.id, - role: "admin", - }); + const user = await createAUser(app, "super_user", ["admin"]); const session = await rest_api.login({ username: "super_user", password: "password",