From ebff67e8a7695600508df40f98b55f93632f8300 Mon Sep 17 00:00:00 2001 From: thiloho <123883702+thiloho@users.noreply.github.com> Date: Thu, 10 Apr 2025 18:35:09 +0200 Subject: [PATCH 1/4] Remove rollback migrations and fix filesystem deletion on user delete --- .../migrations/20240719071602_main_tables.sql | 38 -------- ...73454_automatic_schema_cache_reloading.sql | 4 - ...240720074103_user_management_roles_jwt.sql | 20 ----- ...20240720132802_exposed_views_functions.sql | 22 ----- .../20240724191017_row_level_security.sql | 74 ---------------- .../20240805132306_last_modified_triggers.sql | 18 ---- .../20240808141708_collaborator_not_owner.sql | 4 - .../20240810115846_image_upload_function.sql | 6 -- .../migrations/20240911070907_change_log.sql | 26 ------ .../20241006165029_administrator.sql | 26 ------ .../20241011092744_filesystem_triggers.sql | 6 -- .../20241029160539_export_articles.sql | 2 - .../20241206191942_username_blocklist.sql | 3 - .../20250323134405_username_blocklist.sql | 6 -- .../20250410150518_filesystem_triggers.sql | 88 +++++++++++++++++++ 15 files changed, 88 insertions(+), 255 deletions(-) create mode 100644 rest-api/db/migrations/20250410150518_filesystem_triggers.sql diff --git a/rest-api/db/migrations/20240719071602_main_tables.sql b/rest-api/db/migrations/20240719071602_main_tables.sql index 5d88225..d50ad10 100644 --- a/rest-api/db/migrations/20240719071602_main_tables.sql +++ b/rest-api/db/migrations/20240719071602_main_tables.sql @@ -157,41 +157,3 @@ CREATE TABLE internal.collab ( ); -- migrate:down -DROP TABLE internal.collab; - -DROP TABLE internal.footer; - -DROP TABLE internal.article; - -DROP TABLE internal.docs_category; - -DROP TABLE internal.home; - -DROP TABLE internal.header; - -DROP TABLE internal.settings; - -DROP TABLE internal.media; - -DROP TABLE internal.website; - -DROP TABLE internal.user; - -DROP SCHEMA api; - -DROP FUNCTION internal.generate_slug; - -DROP SCHEMA internal; - -DROP ROLE anon; - -DROP ROLE authenticated_user; - -DROP ROLE administrator; - -DROP ROLE authenticator; - -ALTER DEFAULT PRIVILEGES GRANT EXECUTE ON FUNCTIONS TO PUBLIC; - -DROP EXTENSION unaccent; - diff --git a/rest-api/db/migrations/20240720073454_automatic_schema_cache_reloading.sql b/rest-api/db/migrations/20240720073454_automatic_schema_cache_reloading.sql index 1c9c1c9..97e8e94 100644 --- a/rest-api/db/migrations/20240720073454_automatic_schema_cache_reloading.sql +++ b/rest-api/db/migrations/20240720073454_automatic_schema_cache_reloading.sql @@ -13,7 +13,3 @@ CREATE EVENT TRIGGER pgrst_watch ON ddl_command_end EXECUTE FUNCTION internal.pgrst_watch (); -- migrate:down -DROP EVENT TRIGGER pgrst_watch; - -DROP FUNCTION internal.pgrst_watch; - diff --git a/rest-api/db/migrations/20240720074103_user_management_roles_jwt.sql b/rest-api/db/migrations/20240720074103_user_management_roles_jwt.sql index fb5a582..eb1188c 100644 --- a/rest-api/db/migrations/20240720074103_user_management_roles_jwt.sql +++ b/rest-api/db/migrations/20240720074103_user_management_roles_jwt.sql @@ -170,23 +170,3 @@ GRANT EXECUTE ON FUNCTION api.login TO anon; GRANT EXECUTE ON FUNCTION api.delete_account TO authenticated_user; -- migrate:down -DROP TRIGGER encrypt_pass ON internal.user; - -DROP TRIGGER ensure_user_role_exists ON internal.user; - -DROP FUNCTION api.register; - -DROP FUNCTION api.login; - -DROP FUNCTION api.delete_account; - -DROP FUNCTION internal.user_role; - -DROP FUNCTION internal.encrypt_pass; - -DROP FUNCTION internal.check_role_exists; - -DROP EXTENSION pgjwt; - -DROP EXTENSION pgcrypto; - diff --git a/rest-api/db/migrations/20240720132802_exposed_views_functions.sql b/rest-api/db/migrations/20240720132802_exposed_views_functions.sql index 734d308..6d5ed37 100644 --- a/rest-api/db/migrations/20240720132802_exposed_views_functions.sql +++ b/rest-api/db/migrations/20240720132802_exposed_views_functions.sql @@ -163,25 +163,3 @@ GRANT SELECT, INSERT (website_id, user_id, permission_level), UPDATE (permission GRANT SELECT, INSERT, UPDATE, DELETE ON api.collab TO authenticated_user; -- migrate:down -DROP FUNCTION api.create_website; - -DROP VIEW api.collab; - -DROP VIEW api.footer; - -DROP VIEW api.home; - -DROP VIEW api.docs_category; - -DROP VIEW api.article; - -DROP VIEW api.header; - -DROP VIEW api.settings; - -DROP VIEW api.website; - -DROP VIEW api.user; - -DROP VIEW api.account; - diff --git a/rest-api/db/migrations/20240724191017_row_level_security.sql b/rest-api/db/migrations/20240724191017_row_level_security.sql index e6bfd5e..1d799c9 100644 --- a/rest-api/db/migrations/20240724191017_row_level_security.sql +++ b/rest-api/db/migrations/20240724191017_row_level_security.sql @@ -170,77 +170,3 @@ CREATE POLICY delete_collaborations ON internal.collab USING (internal.user_has_website_access (website_id, 30, collaborator_permission_level => permission_level, collaborator_user_id => user_id)); -- migrate:down -DROP POLICY view_user ON internal.user; - -DROP POLICY update_user ON internal.user; - -DROP POLICY delete_user ON internal.user; - -DROP POLICY view_websites ON internal.website; - -DROP POLICY delete_website ON internal.website; - -DROP POLICY update_website ON internal.website; - -DROP POLICY view_settings ON internal.settings; - -DROP POLICY update_settings ON internal.settings; - -DROP POLICY view_header ON internal.header; - -DROP POLICY update_header ON internal.header; - -DROP POLICY view_home ON internal.home; - -DROP POLICY update_home ON internal.home; - -DROP POLICY view_articles ON internal.article; - -DROP POLICY update_article ON internal.article; - -DROP POLICY delete_article ON internal.article; - -DROP POLICY insert_article ON internal.article; - -DROP POLICY view_categories ON internal.docs_category; - -DROP POLICY update_category ON internal.docs_category; - -DROP POLICY delete_category ON internal.docs_category; - -DROP POLICY insert_category ON internal.docs_category; - -DROP POLICY view_footer ON internal.footer; - -DROP POLICY update_footer ON internal.footer; - -DROP POLICY view_collaborations ON internal.collab; - -DROP POLICY insert_collaborations ON internal.collab; - -DROP POLICY update_collaborations ON internal.collab; - -DROP POLICY delete_collaborations ON internal.collab; - -DROP FUNCTION internal.user_has_website_access; - -ALTER TABLE internal.user DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.website DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.media DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.settings DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.header DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.home DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.article DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.docs_category DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.footer DISABLE ROW LEVEL SECURITY; - -ALTER TABLE internal.collab DISABLE ROW LEVEL SECURITY; - diff --git a/rest-api/db/migrations/20240805132306_last_modified_triggers.sql b/rest-api/db/migrations/20240805132306_last_modified_triggers.sql index 1ee502b..6bb01e7 100644 --- a/rest-api/db/migrations/20240805132306_last_modified_triggers.sql +++ b/rest-api/db/migrations/20240805132306_last_modified_triggers.sql @@ -74,21 +74,3 @@ CREATE TRIGGER update_collab_last_modified EXECUTE FUNCTION internal.update_last_modified (); -- migrate:down -DROP TRIGGER update_website_last_modified ON internal.website; - -DROP TRIGGER update_settings_last_modified ON internal.settings; - -DROP TRIGGER update_header_last_modified ON internal.header; - -DROP TRIGGER update_home_last_modified ON internal.home; - -DROP TRIGGER update_article_last_modified ON internal.article; - -DROP TRIGGER update_docs_category_modified ON internal.docs_category; - -DROP TRIGGER update_footer_last_modified ON internal.footer; - -DROP TRIGGER update_collab_last_modified ON internal.collab; - -DROP FUNCTION internal.update_last_modified; - diff --git a/rest-api/db/migrations/20240808141708_collaborator_not_owner.sql b/rest-api/db/migrations/20240808141708_collaborator_not_owner.sql index 6a0474b..f7b8f38 100644 --- a/rest-api/db/migrations/20240808141708_collaborator_not_owner.sql +++ b/rest-api/db/migrations/20240808141708_collaborator_not_owner.sql @@ -24,7 +24,3 @@ CREATE CONSTRAINT TRIGGER check_user_not_website_owner EXECUTE FUNCTION internal.check_user_not_website_owner (); -- migrate:down -DROP TRIGGER check_user_not_website_owner ON internal.collab; - -DROP FUNCTION internal.check_user_not_website_owner; - diff --git a/rest-api/db/migrations/20240810115846_image_upload_function.sql b/rest-api/db/migrations/20240810115846_image_upload_function.sql index b6668b8..da1f88a 100644 --- a/rest-api/db/migrations/20240810115846_image_upload_function.sql +++ b/rest-api/db/migrations/20240810115846_image_upload_function.sql @@ -95,9 +95,3 @@ GRANT EXECUTE ON FUNCTION api.retrieve_file TO anon; GRANT EXECUTE ON FUNCTION api.retrieve_file TO authenticated_user; -- migrate:down -DROP FUNCTION api.upload_file; - -DROP FUNCTION api.retrieve_file; - -DROP DOMAIN "*/*"; - diff --git a/rest-api/db/migrations/20240911070907_change_log.sql b/rest-api/db/migrations/20240911070907_change_log.sql index 6f17b1a..eae81df 100644 --- a/rest-api/db/migrations/20240911070907_change_log.sql +++ b/rest-api/db/migrations/20240911070907_change_log.sql @@ -133,29 +133,3 @@ CREATE TRIGGER track_changes_collab EXECUTE FUNCTION internal.track_changes (); -- migrate:down -DROP TRIGGER track_changes_website ON internal.website; - -DROP TRIGGER track_changes_media ON internal.media; - -DROP TRIGGER track_changes_settings ON internal.settings; - -DROP TRIGGER track_changes_header ON internal.header; - -DROP TRIGGER track_changes_home ON internal.home; - -DROP TRIGGER track_changes_article ON internal.article; - -DROP TRIGGER track_changes_docs_category ON internal.docs_category; - -DROP TRIGGER track_changes_footer ON internal.footer; - -DROP TRIGGER track_changes_collab ON internal.collab; - -DROP FUNCTION internal.track_changes; - -DROP VIEW api.change_log; - -DROP TABLE internal.change_log; - -DROP EXTENSION hstore; - diff --git a/rest-api/db/migrations/20241006165029_administrator.sql b/rest-api/db/migrations/20241006165029_administrator.sql index 73ab963..2a39df1 100644 --- a/rest-api/db/migrations/20241006165029_administrator.sql +++ b/rest-api/db/migrations/20241006165029_administrator.sql @@ -141,29 +141,3 @@ GRANT UPDATE, DELETE ON internal.user TO administrator; GRANT UPDATE, DELETE ON api.user TO administrator; -- migrate:down -DROP FUNCTION api.user_websites_storage_size; - -DROP TRIGGER _prevent_storage_excess_article ON internal.article; - -DROP TRIGGER _prevent_storage_excess_collab ON internal.collab; - -DROP TRIGGER _prevent_storage_excess_docs_category ON internal.docs_category; - -DROP TRIGGER _prevent_storage_excess_footer ON internal.footer; - -DROP TRIGGER _prevent_storage_excess_header ON internal.header; - -DROP TRIGGER _prevent_storage_excess_home ON internal.home; - -DROP TRIGGER _prevent_storage_excess_media ON internal.media; - -DROP TRIGGER _prevent_storage_excess_settings ON internal.settings; - -DROP FUNCTION internal.prevent_website_storage_size_excess; - -REVOKE UPDATE (max_storage_size) ON internal.website FROM administrator; - -REVOKE UPDATE, DELETE ON internal.user FROM administrator; - -REVOKE UPDATE, DELETE ON api.user FROM administrator; - diff --git a/rest-api/db/migrations/20241011092744_filesystem_triggers.sql b/rest-api/db/migrations/20241011092744_filesystem_triggers.sql index 6c3ff91..1a5d405 100644 --- a/rest-api/db/migrations/20241011092744_filesystem_triggers.sql +++ b/rest-api/db/migrations/20241011092744_filesystem_triggers.sql @@ -56,9 +56,3 @@ CREATE TRIGGER _cleanup_filesystem_article EXECUTE FUNCTION internal.cleanup_filesystem (); -- migrate:down -DROP TRIGGER _cleanup_filesystem_website ON internal.website; - -DROP TRIGGER _cleanup_filesystem_article ON internal.article; - -DROP FUNCTION internal.cleanup_filesystem; - diff --git a/rest-api/db/migrations/20241029160539_export_articles.sql b/rest-api/db/migrations/20241029160539_export_articles.sql index eff2d20..b21617c 100644 --- a/rest-api/db/migrations/20241029160539_export_articles.sql +++ b/rest-api/db/migrations/20241029160539_export_articles.sql @@ -39,5 +39,3 @@ SECURITY DEFINER; GRANT EXECUTE ON FUNCTION api.export_articles_zip TO authenticated_user; -- migrate:down -DROP FUNCTION api.export_articles_zip; - diff --git a/rest-api/db/migrations/20241206191942_username_blocklist.sql b/rest-api/db/migrations/20241206191942_username_blocklist.sql index 476c5b5..8d4f2c6 100644 --- a/rest-api/db/migrations/20241206191942_username_blocklist.sql +++ b/rest-api/db/migrations/20241206191942_username_blocklist.sql @@ -3,6 +3,3 @@ ALTER TABLE internal.user ADD CONSTRAINT username_not_blocked CHECK (LOWER(username) NOT IN ('admin', 'administrator', 'api', 'auth', 'blog', 'cdn', 'docs', 'help', 'login', 'logout', 'profile', 'register', 'settings', 'setup', 'signin', 'signup', 'support', 'test', 'www')); -- migrate:down -ALTER TABLE internal.user - DROP CONSTRAINT username_not_blocked; - diff --git a/rest-api/db/migrations/20250323134405_username_blocklist.sql b/rest-api/db/migrations/20250323134405_username_blocklist.sql index c1cd202..8777dc8 100644 --- a/rest-api/db/migrations/20250323134405_username_blocklist.sql +++ b/rest-api/db/migrations/20250323134405_username_blocklist.sql @@ -6,9 +6,3 @@ ALTER TABLE internal.user ADD CONSTRAINT username_not_blocked CHECK (LOWER(username) NOT IN ('admin', 'administrator', 'api', 'auth', 'blog', 'cdn', 'docs', 'help', 'login', 'logout', 'profile', 'preview', 'previews', 'register', 'settings', 'setup', 'signin', 'signup', 'support', 'test', 'www')); -- migrate:down -ALTER TABLE internal.user - DROP CONSTRAINT username_not_blocked; - -ALTER TABLE internal.user - ADD CONSTRAINT username_not_blocked CHECK (LOWER(username) NOT IN ('admin', 'administrator', 'api', 'auth', 'blog', 'cdn', 'docs', 'help', 'login', 'logout', 'profile', 'register', 'settings', 'setup', 'signin', 'signup', 'support', 'test', 'www')); - diff --git a/rest-api/db/migrations/20250410150518_filesystem_triggers.sql b/rest-api/db/migrations/20250410150518_filesystem_triggers.sql new file mode 100644 index 0000000..7c8d147 --- /dev/null +++ b/rest-api/db/migrations/20250410150518_filesystem_triggers.sql @@ -0,0 +1,88 @@ +-- migrate:up +DROP TRIGGER _cleanup_filesystem_website ON internal.website; + +DROP TRIGGER _cleanup_filesystem_article ON internal.article; + +DROP FUNCTION internal.cleanup_filesystem; + +CREATE FUNCTION internal.cleanup_filesystem () + RETURNS TRIGGER + AS $$ +DECLARE + _website_id UUID; + _website_user_id UUID; + _website_slug TEXT; + _username TEXT; + _base_path CONSTANT TEXT := '/var/www/archtika-websites'; + _preview_path TEXT; + _prod_path TEXT; + _article_slug TEXT; +BEGIN + IF TG_TABLE_NAME = 'website' THEN + _website_id := OLD.id; + _website_user_id = OLD.user_id; + _website_slug := OLD.slug; + ELSE + _website_id := OLD.website_id; + END IF; + SELECT + u.username INTO _username + FROM + internal.user AS u + WHERE + u.id = _website_user_id; + _preview_path := _base_path || '/previews/' || _website_id; + IF TG_TABLE_NAME = 'website' THEN + EXECUTE FORMAT('COPY (SELECT 1) TO PROGRAM ''rm -rf %s''', _preview_path); + IF _username IS NOT NULL THEN + _prod_path := _base_path || '/' || _username || '/' || _website_slug; + EXECUTE FORMAT('COPY (SELECT 1) TO PROGRAM ''rm -rf %s''', _prod_path); + END IF; + ELSIF TG_TABLE_NAME = 'article' THEN + SELECT + a.slug INTO _article_slug + FROM + internal.article AS a + WHERE + a.id = OLD.id; + EXECUTE FORMAT('COPY (SELECT 1) TO PROGRAM ''rm -f %s/articles/%s.html''', _preview_path, _article_slug); + END IF; + RETURN COALESCE(NEW, OLD); +END; +$$ +LANGUAGE plpgsql +SECURITY DEFINER; + +CREATE FUNCTION internal.cleanup_user_directory () + RETURNS TRIGGER + AS $$ +DECLARE + _username TEXT; + _base_path CONSTANT TEXT := '/var/www/archtika-websites'; + _user_path TEXT; +BEGIN + _username := OLD.username; + _user_path := _base_path || '/' || _username; + EXECUTE FORMAT('COPY (SELECT 1) TO PROGRAM ''rm -rf %s''', _user_path); + RETURN OLD; +END; +$$ +LANGUAGE plpgsql +SECURITY DEFINER; + +CREATE TRIGGER _cleanup_filesystem_website + BEFORE UPDATE OF title OR DELETE ON internal.website + FOR EACH ROW + EXECUTE FUNCTION internal.cleanup_filesystem (); + +CREATE TRIGGER _cleanup_filesystem_article + BEFORE UPDATE OF title OR DELETE ON internal.article + FOR EACH ROW + EXECUTE FUNCTION internal.cleanup_filesystem (); + +CREATE TRIGGER _cleanup_user_directory + BEFORE DELETE ON internal.user + FOR EACH ROW + EXECUTE FUNCTION internal.cleanup_user_directory (); + +-- migrate:down From 7dcbd5e9d9f2c4e9d5fd3b68dcf5659e6c2896cd Mon Sep 17 00:00:00 2001 From: thiloho <123883702+thiloho@users.noreply.github.com> Date: Thu, 10 Apr 2025 20:54:58 +0200 Subject: [PATCH 2/4] Use js-diff instead of diff-match-patch for word level diffs --- nix/package.nix | 2 +- web-app/package-lock.json | 25 +++++++++-------- web-app/package.json | 4 +-- .../website/[websiteId]/logs/+page.server.ts | 28 ++++++++++--------- .../website/[websiteId]/logs/+page.svelte | 4 +-- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/nix/package.nix b/nix/package.nix index 8f48ad7..a1e45d1 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -10,7 +10,7 @@ let web = buildNpmPackage { name = "web-app"; src = ../web-app; - npmDepsHash = "sha256-J58LwSEQa0p6J6h/wPhpGY/60n9a7TOV5WfNm4K1NH0="; + npmDepsHash = "sha256-ab7MJ5vl6XNaAHTyzRxj/Zpk1nEKQLzGmPGJdDrdemg="; npmFlags = [ "--legacy-peer-deps" ]; installPhase = '' mkdir -p $out/web-app diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 9a58ec8..3231f8f 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -8,7 +8,7 @@ "name": "web-app", "version": "0.0.1", "dependencies": { - "diff-match-patch": "1.0.5", + "diff": "7.0.0", "highlight.js": "11.11.1", "isomorphic-dompurify": "2.22.0", "marked": "15.0.7", @@ -20,7 +20,7 @@ "@sveltejs/adapter-node": "5.2.12", "@sveltejs/kit": "2.20.2", "@sveltejs/vite-plugin-svelte": "5.0.3", - "@types/diff-match-patch": "1.0.36", + "@types/diff": "7.0.2", "@types/eslint": "9.6.1", "@types/eslint__js": "9.14.0", "@types/eslint-config-prettier": "6.11.3", @@ -1425,10 +1425,10 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/diff-match-patch": { - "version": "1.0.36", - "resolved": "https://registry.npmjs.org/@types/diff-match-patch/-/diff-match-patch-1.0.36.tgz", - "integrity": "sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==", + "node_modules/@types/diff": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-7.0.2.tgz", + "integrity": "sha512-JSWRMozjFKsGlEjiiKajUjIJVKuKdE3oVy2DNtK+fUo8q82nhFZ2CPQwicAIkXrofahDXrWJ7mjelvZphMS98Q==", "dev": true, "license": "MIT" }, @@ -2125,11 +2125,14 @@ "dev": true, "license": "MIT" }, - "node_modules/diff-match-patch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", - "license": "Apache-2.0" + "node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, "node_modules/dompurify": { "version": "3.2.4", diff --git a/web-app/package.json b/web-app/package.json index 2b7d48b..200c167 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -19,7 +19,7 @@ "@sveltejs/adapter-node": "5.2.12", "@sveltejs/kit": "2.20.2", "@sveltejs/vite-plugin-svelte": "5.0.3", - "@types/diff-match-patch": "1.0.36", + "@types/diff": "7.0.2", "@types/eslint": "9.6.1", "@types/eslint__js": "9.14.0", "@types/eslint-config-prettier": "6.11.3", @@ -38,7 +38,7 @@ "vite": "6.2.5" }, "dependencies": { - "diff-match-patch": "1.0.5", + "diff": "7.0.0", "highlight.js": "11.11.1", "isomorphic-dompurify": "2.22.0", "marked": "15.0.7", diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts b/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts index e9ac293..e3cec82 100644 --- a/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts +++ b/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts @@ -3,6 +3,7 @@ import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils"; import type { ChangeLog, User, Collab } from "$lib/db-schema"; import DiffMatchPatch from "diff-match-patch"; import { PAGINATION_MAX_ITEMS } from "$lib/utils"; +import * as Diff from "diff"; export const load: PageServerLoad = async ({ parent, fetch, params, url }) => { const userFilter = url.searchParams.get("user"); @@ -76,22 +77,19 @@ export const actions: Actions = { computeDiff: async ({ request, fetch }) => { const data = await request.formData(); - const dmp = new DiffMatchPatch(); - const htmlDiff = (oldValue: string, newValue: string) => { - const diff = dmp.diff_main(oldValue, newValue); + const diff = Diff.diffWordsWithSpace(oldValue, newValue); return diff - .map(([op, text]) => { - const escapedText = text.replace(//g, ">"); + .map((part) => { + const escapedText = part.value.replace(//g, ">"); - switch (op) { - case 1: - return `${escapedText}`; - case -1: - return `${escapedText}`; - default: - return escapedText; + if (part.added) { + return `${escapedText}`; + } else if (part.removed) { + return `${escapedText}`; + } else { + return escapedText; } }) .join(""); @@ -112,8 +110,12 @@ export const actions: Actions = { return { logId: data.get("id"), currentDiff: htmlDiff( - JSON.stringify(log.old_value, null, 2), + JSON.stringify(log.old_value, null, 2) + .replace(/\\r\\n|\\n|\\r/g, "\n") + .replace(/\\\"/g, '"'), JSON.stringify(log.new_value, null, 2) + .replace(/\\r\\n|\\n|\\r/g, "\n") + .replace(/\\\"/g, '"') ) }; } diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.svelte b/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.svelte index 328db02..48c8c2c 100644 --- a/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.svelte +++ b/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.svelte @@ -141,9 +141,7 @@ {#if form?.logId === id && form?.currentDiff} -
{@html form.currentDiff
-                          .replace(/\\\"/g, '"')
-                          .replace(/\\r\\n|\\n|\\r/g, "\n")}
+
{@html form.currentDiff}
{/if} {/if} From c738bfbd364d50da1f028b318991584b4617489f Mon Sep 17 00:00:00 2001 From: thiloho <123883702+thiloho@users.noreply.github.com> Date: Thu, 10 Apr 2025 20:55:37 +0200 Subject: [PATCH 3/4] Remove old diff-match-patch import --- .../(authenticated)/website/[websiteId]/logs/+page.server.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts b/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts index e3cec82..1a1fe39 100644 --- a/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts +++ b/web-app/src/routes/(authenticated)/website/[websiteId]/logs/+page.server.ts @@ -1,7 +1,6 @@ import type { PageServerLoad, Actions } from "./$types"; import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils"; import type { ChangeLog, User, Collab } from "$lib/db-schema"; -import DiffMatchPatch from "diff-match-patch"; import { PAGINATION_MAX_ITEMS } from "$lib/utils"; import * as Diff from "diff"; From d34a623e39c0980ef9bfe78e0be10393cab6b00f Mon Sep 17 00:00:00 2001 From: thiloho <123883702+thiloho@users.noreply.github.com> Date: Thu, 10 Apr 2025 21:21:43 +0200 Subject: [PATCH 4/4] Trigger actions