From 42a4018a8265cbccdf721de3dc42f399443cb487 Mon Sep 17 00:00:00 2001 From: Daniel Swiatek Date: Mon, 23 Feb 2026 07:58:22 +0100 Subject: [PATCH 01/15] Bump version from 2.8.0 to 2.9.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 42d788b1..790fedfc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "codeanker-project", "author": "CODEANKER GmbH", - "version": "2.8.0", + "version": "2.9.0", "description": "", "license": "CC-BY-3.0-DE", "workspaces": [ From a07c7a25cb75c2d40d0eb1efc7499f8cf74a6ae3 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Fri, 27 Feb 2026 11:41:48 +0100 Subject: [PATCH 02/15] fix: use domain field in gliederung form --- .../components/forms/gliederung/FormGliederungGeneral.vue | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/frontend/src/components/forms/gliederung/FormGliederungGeneral.vue b/apps/frontend/src/components/forms/gliederung/FormGliederungGeneral.vue index 80871dc9..ebe5e98e 100644 --- a/apps/frontend/src/components/forms/gliederung/FormGliederungGeneral.vue +++ b/apps/frontend/src/components/forms/gliederung/FormGliederungGeneral.vue @@ -18,7 +18,7 @@ const fill = (gliederung) => { return { name: gliederung?.name, edv: gliederung?.edv, - email: gliederung?.email, + domain: gliederung?.domain, } } @@ -96,10 +96,9 @@ const handle = async (event: Event) => {
From 29829f4df716ef4ffca39517318fc52a5a105f4e Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Fri, 27 Feb 2026 15:31:55 +0100 Subject: [PATCH 03/15] fix: define table id to fix filter --- apps/frontend/src/components/data/GliederungAccessTable.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/frontend/src/components/data/GliederungAccessTable.vue b/apps/frontend/src/components/data/GliederungAccessTable.vue index fad32da9..d490df6d 100644 --- a/apps/frontend/src/components/data/GliederungAccessTable.vue +++ b/apps/frontend/src/components/data/GliederungAccessTable.vue @@ -40,6 +40,7 @@ const decide = useMutation({ const column = createColumnHelper() const columns = [ column.accessor('gliederung.name', { + id: 'gliederung', header: 'Gliederung', enableColumnFilter: true, enableSorting: true, From 943d1f67be62945f73c047918fd981993745873d Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Fri, 27 Feb 2026 15:54:56 +0100 Subject: [PATCH 04/15] fix: sanitize and render faq answer as html --- apps/frontend/package.json | 2 + apps/frontend/src/helpers/sanitizeHtml.ts | 22 ++++++++ .../views/Anmeldung/components/PublicFAQ.vue | 3 +- pnpm-lock.yaml | 52 ++++++++++++++----- 4 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 apps/frontend/src/helpers/sanitizeHtml.ts diff --git a/apps/frontend/package.json b/apps/frontend/package.json index d403063b..773d5512 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -44,6 +44,7 @@ "radix-vue": "^1.9.5", "reka-ui": "^2.1.1", "remixicon": "^3.5.0", + "sanitize-html": "^2.17.1", "simple-syntax-highlighter": "^3.1.1", "superjson": "catalog:", "tailwind-merge": "^2.6.0", @@ -56,6 +57,7 @@ "@codeanker/eslint-config": "workspace:*", "@codeanker/typescript-config": "workspace:*", "@types/node": "catalog:", + "@types/sanitize-html": "^2.16.0", "@vitejs/plugin-basic-ssl": "^2.1.0", "@vitejs/plugin-vue": "^6.0.2", "autoprefixer": "^10.4.16", diff --git a/apps/frontend/src/helpers/sanitizeHtml.ts b/apps/frontend/src/helpers/sanitizeHtml.ts new file mode 100644 index 00000000..eec0123f --- /dev/null +++ b/apps/frontend/src/helpers/sanitizeHtml.ts @@ -0,0 +1,22 @@ +import doSanitizeHtml from 'sanitize-html' + +export function sanitizeHtml(html: string): string { + return doSanitizeHtml(html, { + allowedTags: [ + 'p', + 'strong', + 'em', + 'u', + 'a', + 'ul', + 'ol', + 'li', + 'img', + ], + allowedAttributes: { + img: [ + 'src', 'alt', 'style', + ], + }, + }) +} diff --git a/apps/frontend/src/views/Anmeldung/components/PublicFAQ.vue b/apps/frontend/src/views/Anmeldung/components/PublicFAQ.vue index 100d3216..0598a36c 100644 --- a/apps/frontend/src/views/Anmeldung/components/PublicFAQ.vue +++ b/apps/frontend/src/views/Anmeldung/components/PublicFAQ.vue @@ -2,6 +2,7 @@ import { injectUnterveranstaltung } from '@/layouts/AnmeldungLayout.vue' import { PlusIcon, MinusIcon } from '@heroicons/vue/24/solid' import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue' +import { sanitizeHtml } from '@/helpers/sanitizeHtml'; const unterveranstaltung = injectUnterveranstaltung() @@ -57,7 +58,7 @@ const unterveranstaltung = injectUnterveranstaltung() as="dd" class="mt-2 pr-12" > -

{{ faq.answer }}

+

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9af0b7e1..94e82143 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -349,6 +349,9 @@ importers: remixicon: specifier: ^3.5.0 version: 3.7.0 + sanitize-html: + specifier: ^2.17.1 + version: 2.17.1 simple-syntax-highlighter: specifier: ^3.1.1 version: 3.1.1(vue@3.5.13(typescript@5.7.2)) @@ -380,6 +383,9 @@ importers: '@types/node': specifier: 'catalog:' version: 22.10.2 + '@types/sanitize-html': + specifier: ^2.16.0 + version: 2.16.0 '@vitejs/plugin-basic-ssl': specifier: ^2.1.0 version: 2.1.0(vite@7.2.4(@types/node@22.10.2)(jiti@1.21.7)(sass@1.83.0)(tsx@4.19.2)(yaml@2.7.0)) @@ -2539,6 +2545,9 @@ packages: '@types/readdir-glob@1.1.5': resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==} + '@types/sanitize-html@2.16.0': + resolution: {integrity: sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==} + '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} @@ -3747,6 +3756,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -4248,6 +4261,9 @@ packages: param-case@2.1.1: resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} + parse-srcset@1.0.2: + resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} + parse5-htmlparser2-tree-adapter@7.1.0: resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} @@ -4363,10 +4379,6 @@ packages: resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -4602,6 +4614,9 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sanitize-html@2.17.1: + resolution: {integrity: sha512-ehFCW+q1a4CSOWRAdX97BX/6/PDEkCqw7/0JXZAGQV57FQB3YOkTa/rrzHPeJ+Aghy4vZAFfWMYyfxIiB7F/gw==} + sass@1.83.0: resolution: {integrity: sha512-qsSxlayzoOjdvXMVLkzF84DJFc2HZEL/rFyGIKbbilYtAvlCxyuzUeff9LawTn4btVnLKg75Z8MMr1lxU1lfGw==} engines: {node: '>=14.0.0'} @@ -7009,6 +7024,10 @@ snapshots: dependencies: '@types/node': 22.10.2 + '@types/sanitize-html@2.16.0': + dependencies: + htmlparser2: 8.0.2 + '@types/triple-beam@1.3.5': {} '@types/unist@3.0.3': {} @@ -7239,7 +7258,7 @@ snapshots: '@vue/shared': 3.5.13 estree-walker: 2.0.2 magic-string: 0.30.17 - postcss: 8.5.1 + postcss: 8.5.6 source-map-js: 1.2.1 '@vue/compiler-sfc@3.5.25': @@ -8402,6 +8421,8 @@ snapshots: is-number@7.0.0: {} + is-plain-object@5.0.0: {} + is-stream@2.0.1: {} is-what@4.1.16: {} @@ -9065,6 +9086,8 @@ snapshots: dependencies: no-case: 2.3.2 + parse-srcset@1.0.2: {} + parse5-htmlparser2-tree-adapter@7.1.0: dependencies: domhandler: 5.0.3 @@ -9160,12 +9183,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.3: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -9522,6 +9539,15 @@ snapshots: safer-buffer@2.1.2: {} + sanitize-html@2.17.1: + dependencies: + deepmerge: 4.3.1 + escape-string-regexp: 4.0.0 + htmlparser2: 8.0.2 + is-plain-object: 5.0.0 + parse-srcset: 1.0.2 + postcss: 8.5.6 + sass@1.83.0: dependencies: chokidar: 4.0.3 @@ -9963,7 +9989,7 @@ snapshots: vite@5.4.14(@types/node@22.10.2)(sass@1.83.0): dependencies: esbuild: 0.21.5 - postcss: 8.5.1 + postcss: 8.5.6 rollup: 4.34.4 optionalDependencies: '@types/node': 22.10.2 @@ -9973,7 +9999,7 @@ snapshots: vite@6.2.4(@types/node@22.10.2)(jiti@1.21.7)(sass@1.83.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: esbuild: 0.25.2 - postcss: 8.5.3 + postcss: 8.5.6 rollup: 4.38.0 optionalDependencies: '@types/node': 22.10.2 From aca945e1fa49287b2b1e828fac82d72f1bab4749 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Fri, 27 Feb 2026 16:12:36 +0100 Subject: [PATCH 05/15] fix: show persons without gliederung --- apps/api/src/services/person/personList.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/api/src/services/person/personList.ts b/apps/api/src/services/person/personList.ts index ae78473b..968cb94a 100644 --- a/apps/api/src/services/person/personList.ts +++ b/apps/api/src/services/person/personList.ts @@ -39,9 +39,9 @@ export const personListProcedure = defineProtectedQueryProcedure({ }, ] : undefined, - gliederung: { + gliederung: filter?.gliederung_name === undefined ? undefined : { name: { - contains: filter?.gliederung_name, + contains: filter.gliederung_name, mode: 'insensitive', }, }, @@ -58,8 +58,6 @@ export const personListProcedure = defineProtectedQueryProcedure({ const total = await prisma.person.count({ where }) const { pageIndex, pageSize, pages } = calculatePagination(total, pagination) - console.log(orderBy) - const persons = await prisma.person.findMany({ take: pageSize, skip: pageSize * pageIndex, From 8cf0c53c032bdd1e3362b5ed88264680e38f7592 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Fri, 27 Feb 2026 16:12:46 +0100 Subject: [PATCH 06/15] feat: add link to person detail --- .../src/services/account/accountVerwaltungGet.ts | 1 + .../forms/account/FormAccountGeneral.vue | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/apps/api/src/services/account/accountVerwaltungGet.ts b/apps/api/src/services/account/accountVerwaltungGet.ts index 4cd9654a..ee913896 100644 --- a/apps/api/src/services/account/accountVerwaltungGet.ts +++ b/apps/api/src/services/account/accountVerwaltungGet.ts @@ -22,6 +22,7 @@ export const accountVerwaltungGetProcedure = defineProtectedQueryProcedure({ status: true, role: true, dlrgOauthId: true, + personId: true, person: { select: { firstname: true, diff --git a/apps/frontend/src/components/forms/account/FormAccountGeneral.vue b/apps/frontend/src/components/forms/account/FormAccountGeneral.vue index 473f5924..c64f3958 100644 --- a/apps/frontend/src/components/forms/account/FormAccountGeneral.vue +++ b/apps/frontend/src/components/forms/account/FormAccountGeneral.vue @@ -1,6 +1,7 @@