From 26a3f6dad01cfd1c65db929dc6f6fc74450bb859 Mon Sep 17 00:00:00 2001 From: Herman Snevajs Date: Tue, 10 Feb 2026 15:11:14 +0100 Subject: [PATCH 1/3] shadow for invalid input --- web-app/packages/lib/src/assets/sass/theme-base/_mixins.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-app/packages/lib/src/assets/sass/theme-base/_mixins.scss b/web-app/packages/lib/src/assets/sass/theme-base/_mixins.scss index 7db81588..076d5c2b 100644 --- a/web-app/packages/lib/src/assets/sass/theme-base/_mixins.scss +++ b/web-app/packages/lib/src/assets/sass/theme-base/_mixins.scss @@ -30,7 +30,7 @@ @mixin invalid-input() { border-color: $inputErrorBorderColor; background-color: $inputErrorBackgroundColor; - box-shadow: inset 0 0 0 1px $inputErrorBorderColor; + box-shadow: inset 0 0 0 2px $inputErrorBorderColor; } @mixin menuitem { From 8385e149a50d6004b53c1ed9fd6b19f2cf9a0a61 Mon Sep 17 00:00:00 2001 From: Herman Snevajs Date: Tue, 10 Feb 2026 15:19:04 +0100 Subject: [PATCH 2/3] Small tweaks - improve logging - save heavy DB query - prefer dataclasses over strings --- server/mergin/sync/public_api_controller.py | 5 +++-- server/mergin/sync/public_api_v2_controller.py | 4 ++-- server/mergin/utils.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/server/mergin/sync/public_api_controller.py b/server/mergin/sync/public_api_controller.py index f8b88cd1..22a4ef5a 100644 --- a/server/mergin/sync/public_api_controller.py +++ b/server/mergin/sync/public_api_controller.py @@ -608,8 +608,9 @@ def get_paginated_projects( public, only_public, ) - result = projects.paginate(page, per_page).items - total = projects.paginate().total + pagination = projects.paginate(page, per_page) + result = pagination.items + total = pagination.total # create user map id:username passed to project schema to minimize queries to db projects_ids = [p.id for p in result] diff --git a/server/mergin/sync/public_api_v2_controller.py b/server/mergin/sync/public_api_v2_controller.py index 1070c830..21f199f1 100644 --- a/server/mergin/sync/public_api_v2_controller.py +++ b/server/mergin/sync/public_api_v2_controller.py @@ -428,12 +428,12 @@ def list_workspace_projects(workspace_id, page, per_page, order_params=None, q=N if not (ws and ws.is_active): abort(404, "Workspace not found") - if ws.user_has_permissions(current_user, "read"): + if ws.user_has_permissions(current_user, WorkspaceRole.READER.value): # regular members can list all projects projects = Project.query.filter_by(workspace_id=ws.id).filter( Project.removed_at.is_(None) ) - elif ws.user_has_permissions(current_user, "guest"): + elif ws.user_has_permissions(current_user, WorkspaceRole.GUEST.value): # guest can list only explicitly shared projects projects = projects_query( ProjectPermissions.Read, as_admin=False, public=False diff --git a/server/mergin/utils.py b/server/mergin/utils.py index 7b062770..d61b06d8 100644 --- a/server/mergin/utils.py +++ b/server/mergin/utils.py @@ -60,7 +60,7 @@ def get_order_param( attr = None order_attr = cls.__table__.c.get(col, None) if not isinstance(order_attr, Column): - logging.warning("Ignoring invalid order parameter.") + logging.warning(f"Ignoring invalid order parameter: {order_param}.") return # sort by key in JSON field if attr: From 585e82abeb0f29e9fdc4efcce559472d7756936f Mon Sep 17 00:00:00 2001 From: Herman Snevajs Date: Tue, 10 Feb 2026 15:43:03 +0100 Subject: [PATCH 3/3] revert - permission is not role --- server/mergin/sync/public_api_v2_controller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/mergin/sync/public_api_v2_controller.py b/server/mergin/sync/public_api_v2_controller.py index 21f199f1..1070c830 100644 --- a/server/mergin/sync/public_api_v2_controller.py +++ b/server/mergin/sync/public_api_v2_controller.py @@ -428,12 +428,12 @@ def list_workspace_projects(workspace_id, page, per_page, order_params=None, q=N if not (ws and ws.is_active): abort(404, "Workspace not found") - if ws.user_has_permissions(current_user, WorkspaceRole.READER.value): + if ws.user_has_permissions(current_user, "read"): # regular members can list all projects projects = Project.query.filter_by(workspace_id=ws.id).filter( Project.removed_at.is_(None) ) - elif ws.user_has_permissions(current_user, WorkspaceRole.GUEST.value): + elif ws.user_has_permissions(current_user, "guest"): # guest can list only explicitly shared projects projects = projects_query( ProjectPermissions.Read, as_admin=False, public=False