Skip to content

Develop#284

Merged
ucswift merged 5 commits intomasterfrom
develop
Mar 3, 2026
Merged

Develop#284
ucswift merged 5 commits intomasterfrom
develop

Conversation

@ucswift
Copy link
Member

@ucswift ucswift commented Mar 2, 2026

Summary by CodeRabbit

  • New Features

    • Added calendar synchronization capabilities with subscription and download options
    • Expanded multi-language support across all major UI areas (German, French, Italian, Polish, Swedish, Ukrainian)
  • Configuration

    • Added configuration settings for calendar feed management and SSO/SCIM/OIDC features

@request-info
Copy link

request-info bot commented Mar 2, 2026

Thanks for opening this, but we'd appreciate a little more information. Could you update it with more details?

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

Important

Review skipped

Too many files!

This PR contains 274 files, which is 124 over the limit of 150.

📥 Commits

Reviewing files that changed from the base of the PR and between 9a67d37 and 8825496.

⛔ Files ignored due to path filters (26)
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/fullcalendar.css is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/fullcalendar.d.ts is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/fullcalendar.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/fullcalendar.min.css is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/fullcalendar.min.js is excluded by !**/dist/**, !**/*.min.js
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/fullcalendar.print.css is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/fullcalendar.print.min.css is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/gcal.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/gcal.min.js is excluded by !**/dist/**, !**/*.min.js
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale-all.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/af.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ar-dz.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ar-kw.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ar-ly.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ar-ma.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ar-sa.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ar-tn.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ar.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/be.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/bg.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/bs.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/ca.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/cs.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/da.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/de-at.js is excluded by !**/dist/**
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/dist/locale/de-ch.js is excluded by !**/dist/**
📒 Files selected for processing (274)
  • .github/workflows/dotnet.yml
  • Core/Resgrid.Config/CalendarConfig.cs
  • Core/Resgrid.Config/SsoConfig.cs
  • Core/Resgrid.Config/WorkflowConfig.cs
  • Core/Resgrid.Localization/Account/Login.de.resx
  • Core/Resgrid.Localization/Account/Login.fr.resx
  • Core/Resgrid.Localization/Account/Login.it.resx
  • Core/Resgrid.Localization/Account/Login.pl.resx
  • Core/Resgrid.Localization/Account/Login.sv.resx
  • Core/Resgrid.Localization/Account/Login.uk.resx
  • Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.de.resx
  • Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.es.resx
  • Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.fr.resx
  • Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.it.resx
  • Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.pl.resx
  • Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.sv.resx
  • Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.uk.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.de.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.en.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.es.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.fr.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.it.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.pl.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.sv.resx
  • Core/Resgrid.Localization/Areas/User/Calendar/Calendar.uk.resx
  • Core/Resgrid.Localization/Areas/User/Contacts/Contacts.de.resx
  • Core/Resgrid.Localization/Areas/User/Contacts/Contacts.es.resx
  • Core/Resgrid.Localization/Areas/User/Contacts/Contacts.fr.resx
  • Core/Resgrid.Localization/Areas/User/Contacts/Contacts.it.resx
  • Core/Resgrid.Localization/Areas/User/Contacts/Contacts.pl.resx
  • Core/Resgrid.Localization/Areas/User/Contacts/Contacts.sv.resx
  • Core/Resgrid.Localization/Areas/User/Contacts/Contacts.uk.resx
  • Core/Resgrid.Localization/Areas/User/CustomStatuses/CustomStatuses.de.resx
  • Core/Resgrid.Localization/Areas/User/CustomStatuses/CustomStatuses.fr.resx
  • Core/Resgrid.Localization/Areas/User/CustomStatuses/CustomStatuses.it.resx
  • Core/Resgrid.Localization/Areas/User/CustomStatuses/CustomStatuses.pl.resx
  • Core/Resgrid.Localization/Areas/User/CustomStatuses/CustomStatuses.sv.resx
  • Core/Resgrid.Localization/Areas/User/CustomStatuses/CustomStatuses.uk.resx
  • Core/Resgrid.Localization/Areas/User/Department/Department.de.resx
  • Core/Resgrid.Localization/Areas/User/Department/Department.fr.resx
  • Core/Resgrid.Localization/Areas/User/Department/Department.it.resx
  • Core/Resgrid.Localization/Areas/User/Department/Department.pl.resx
  • Core/Resgrid.Localization/Areas/User/Department/Department.sv.resx
  • Core/Resgrid.Localization/Areas/User/Department/Department.uk.resx
  • Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.de.resx
  • Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.fr.resx
  • Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.it.resx
  • Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.pl.resx
  • Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.sv.resx
  • Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.uk.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Call.de.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Call.fr.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Call.it.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Call.pl.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Call.sv.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Call.uk.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Dashboard.de.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Dashboard.fr.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Dashboard.it.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Dashboard.pl.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Dashboard.sv.resx
  • Core/Resgrid.Localization/Areas/User/Dispatch/Dashboard.uk.resx
  • Core/Resgrid.Localization/Areas/User/Documents/Documents.de.resx
  • Core/Resgrid.Localization/Areas/User/Documents/Documents.fr.resx
  • Core/Resgrid.Localization/Areas/User/Documents/Documents.it.resx
  • Core/Resgrid.Localization/Areas/User/Documents/Documents.pl.resx
  • Core/Resgrid.Localization/Areas/User/Documents/Documents.sv.resx
  • Core/Resgrid.Localization/Areas/User/Documents/Documents.uk.resx
  • Core/Resgrid.Localization/Areas/User/Home/EditProfile.de.resx
  • Core/Resgrid.Localization/Areas/User/Home/EditProfile.fr.resx
  • Core/Resgrid.Localization/Areas/User/Home/EditProfile.it.resx
  • Core/Resgrid.Localization/Areas/User/Home/EditProfile.pl.resx
  • Core/Resgrid.Localization/Areas/User/Home/EditProfile.sv.resx
  • Core/Resgrid.Localization/Areas/User/Home/EditProfile.uk.resx
  • Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.de.resx
  • Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.fr.resx
  • Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.it.resx
  • Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.pl.resx
  • Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.sv.resx
  • Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.uk.resx
  • Core/Resgrid.Localization/Areas/User/Logs/Logs.de.resx
  • Core/Resgrid.Localization/Areas/User/Logs/Logs.fr.resx
  • Core/Resgrid.Localization/Areas/User/Logs/Logs.it.resx
  • Core/Resgrid.Localization/Areas/User/Logs/Logs.pl.resx
  • Core/Resgrid.Localization/Areas/User/Logs/Logs.sv.resx
  • Core/Resgrid.Localization/Areas/User/Logs/Logs.uk.resx
  • Core/Resgrid.Localization/Areas/User/Messages/Messages.de.resx
  • Core/Resgrid.Localization/Areas/User/Messages/Messages.fr.resx
  • Core/Resgrid.Localization/Areas/User/Messages/Messages.it.resx
  • Core/Resgrid.Localization/Areas/User/Messages/Messages.pl.resx
  • Core/Resgrid.Localization/Areas/User/Messages/Messages.sv.resx
  • Core/Resgrid.Localization/Areas/User/Messages/Messages.uk.resx
  • Core/Resgrid.Localization/Areas/User/Notes/Note.de.resx
  • Core/Resgrid.Localization/Areas/User/Notes/Note.fr.resx
  • Core/Resgrid.Localization/Areas/User/Notes/Note.it.resx
  • Core/Resgrid.Localization/Areas/User/Notes/Note.pl.resx
  • Core/Resgrid.Localization/Areas/User/Notes/Note.sv.resx
  • Core/Resgrid.Localization/Areas/User/Notes/Note.uk.resx
  • Core/Resgrid.Localization/Areas/User/Personnel/Person.de.resx
  • Core/Resgrid.Localization/Areas/User/Personnel/Person.fr.resx
  • Core/Resgrid.Localization/Areas/User/Personnel/Person.it.resx
  • Core/Resgrid.Localization/Areas/User/Personnel/Person.pl.resx
  • Core/Resgrid.Localization/Areas/User/Personnel/Person.sv.resx
  • Core/Resgrid.Localization/Areas/User/Personnel/Person.uk.resx
  • Core/Resgrid.Localization/Areas/User/Profile/Profile.de.resx
  • Core/Resgrid.Localization/Areas/User/Profile/Profile.fr.resx
  • Core/Resgrid.Localization/Areas/User/Profile/Profile.it.resx
  • Core/Resgrid.Localization/Areas/User/Profile/Profile.pl.resx
  • Core/Resgrid.Localization/Areas/User/Profile/Profile.sv.resx
  • Core/Resgrid.Localization/Areas/User/Profile/Profile.uk.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.de.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.en.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.es.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.fr.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.it.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.pl.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.sv.resx
  • Core/Resgrid.Localization/Areas/User/Security/Security.uk.resx
  • Core/Resgrid.Localization/Areas/User/Shifts/Shifts.de.resx
  • Core/Resgrid.Localization/Areas/User/Shifts/Shifts.fr.resx
  • Core/Resgrid.Localization/Areas/User/Shifts/Shifts.it.resx
  • Core/Resgrid.Localization/Areas/User/Shifts/Shifts.pl.resx
  • Core/Resgrid.Localization/Areas/User/Shifts/Shifts.sv.resx
  • Core/Resgrid.Localization/Areas/User/Shifts/Shifts.uk.resx
  • Core/Resgrid.Localization/Areas/User/Subscription/Subscription.de.resx
  • Core/Resgrid.Localization/Areas/User/Subscription/Subscription.fr.resx
  • Core/Resgrid.Localization/Areas/User/Subscription/Subscription.it.resx
  • Core/Resgrid.Localization/Areas/User/Subscription/Subscription.pl.resx
  • Core/Resgrid.Localization/Areas/User/Subscription/Subscription.sv.resx
  • Core/Resgrid.Localization/Areas/User/Subscription/Subscription.uk.resx
  • Core/Resgrid.Localization/Areas/User/Templates/Templates.de.resx
  • Core/Resgrid.Localization/Areas/User/Templates/Templates.fr.resx
  • Core/Resgrid.Localization/Areas/User/Templates/Templates.it.resx
  • Core/Resgrid.Localization/Areas/User/Templates/Templates.pl.resx
  • Core/Resgrid.Localization/Areas/User/Templates/Templates.sv.resx
  • Core/Resgrid.Localization/Areas/User/Templates/Templates.uk.resx
  • Core/Resgrid.Localization/Areas/User/TwoFactor/TwoFactor.de.resx
  • Core/Resgrid.Localization/Areas/User/TwoFactor/TwoFactor.fr.resx
  • Core/Resgrid.Localization/Areas/User/TwoFactor/TwoFactor.it.resx
  • Core/Resgrid.Localization/Areas/User/TwoFactor/TwoFactor.pl.resx
  • Core/Resgrid.Localization/Areas/User/TwoFactor/TwoFactor.sv.resx
  • Core/Resgrid.Localization/Areas/User/TwoFactor/TwoFactor.uk.resx
  • Core/Resgrid.Localization/Areas/User/Units/Units.de.resx
  • Core/Resgrid.Localization/Areas/User/Units/Units.fr.resx
  • Core/Resgrid.Localization/Areas/User/Units/Units.it.resx
  • Core/Resgrid.Localization/Areas/User/Units/Units.pl.resx
  • Core/Resgrid.Localization/Areas/User/Units/Units.sv.resx
  • Core/Resgrid.Localization/Areas/User/Units/Units.uk.resx
  • Core/Resgrid.Localization/Areas/User/Voice/Voice.de.resx
  • Core/Resgrid.Localization/Areas/User/Voice/Voice.fr.resx
  • Core/Resgrid.Localization/Areas/User/Voice/Voice.it.resx
  • Core/Resgrid.Localization/Areas/User/Voice/Voice.pl.resx
  • Core/Resgrid.Localization/Areas/User/Voice/Voice.sv.resx
  • Core/Resgrid.Localization/Areas/User/Voice/Voice.uk.resx
  • Core/Resgrid.Localization/Areas/User/Workflows/Workflows.de.resx
  • Core/Resgrid.Localization/Areas/User/Workflows/Workflows.fr.resx
  • Core/Resgrid.Localization/Areas/User/Workflows/Workflows.it.resx
  • Core/Resgrid.Localization/Areas/User/Workflows/Workflows.pl.resx
  • Core/Resgrid.Localization/Areas/User/Workflows/Workflows.sv.resx
  • Core/Resgrid.Localization/Areas/User/Workflows/Workflows.uk.resx
  • Core/Resgrid.Localization/Common.de.resx
  • Core/Resgrid.Localization/Common.fr.resx
  • Core/Resgrid.Localization/Common.it.resx
  • Core/Resgrid.Localization/Common.pl.resx
  • Core/Resgrid.Localization/Common.sv.resx
  • Core/Resgrid.Localization/Common.uk.resx
  • Core/Resgrid.Localization/SupportedLocales.cs
  • Core/Resgrid.Model/AuditLogTypes.cs
  • Core/Resgrid.Model/CalendarItem.cs
  • Core/Resgrid.Model/DataClassificationLevel.cs
  • Core/Resgrid.Model/DepartmentMember.cs
  • Core/Resgrid.Model/DepartmentSecurityPolicy.cs
  • Core/Resgrid.Model/DepartmentSsoConfig.cs
  • Core/Resgrid.Model/Repositories/IDepartmentSecurityPolicyRepository.cs
  • Core/Resgrid.Model/Repositories/IDepartmentSsoConfigRepository.cs
  • Core/Resgrid.Model/Services/ICalendarExportService.cs
  • Core/Resgrid.Model/Services/ICalendarService.cs
  • Core/Resgrid.Model/Services/IDepartmentSsoService.cs
  • Core/Resgrid.Model/SsoProviderType.cs
  • Core/Resgrid.Model/SystemAuditTypes.cs
  • Core/Resgrid.Model/UserProfile.cs
  • Core/Resgrid.Model/WorkflowRunStatus.cs
  • Core/Resgrid.Model/WorkflowStep.cs
  • Core/Resgrid.Services/CalendarExportService.cs
  • Core/Resgrid.Services/CalendarService.cs
  • Core/Resgrid.Services/DepartmentSsoService.cs
  • Core/Resgrid.Services/Resgrid.Services.csproj
  • Core/Resgrid.Services/ServicesModule.cs
  • Core/Resgrid.Services/WorkflowService.cs
  • Providers/Resgrid.Providers.Claims/ResgridClaimTypes.cs
  • Providers/Resgrid.Providers.Claims/ResgridResources.cs
  • Providers/Resgrid.Providers.Migrations/Migrations/M0045_AddConditionExpressionToWorkflowSteps.cs
  • Providers/Resgrid.Providers.Migrations/Migrations/M0046_AddingSsoAndSecurityPolicy.cs
  • Providers/Resgrid.Providers.Migrations/Migrations/M0047_AddingCalendarSyncToken.cs
  • Providers/Resgrid.Providers.MigrationsPg/Migrations/M0045_AddConditionExpressionToWorkflowStepsPg.cs
  • Providers/Resgrid.Providers.MigrationsPg/Migrations/M0046_AddingSsoAndSecurityPolicyPg.cs
  • Providers/Resgrid.Providers.MigrationsPg/Migrations/M0047_AddingCalendarSyncTokenPg.cs
  • Providers/Resgrid.Providers.Number/PhoneNumberProcesserProvider.cs
  • Providers/Resgrid.Providers.Workflow/Executors/SmtpEmailExecutor.cs
  • Providers/Resgrid.Providers.Workflow/Executors/TeamsMessageExecutor.cs
  • Providers/Resgrid.Providers.Workflow/Resgrid.Providers.Workflow.csproj
  • Repositories/Resgrid.Repositories.DataRepository/DepartmentSecurityPolicyRepository.cs
  • Repositories/Resgrid.Repositories.DataRepository/DepartmentSsoConfigRepository.cs
  • Repositories/Resgrid.Repositories.DataRepository/Modules/ApiDataModule.cs
  • Repositories/Resgrid.Repositories.DataRepository/Modules/DataModule.cs
  • Repositories/Resgrid.Repositories.DataRepository/Modules/NonWebDataModule.cs
  • Repositories/Resgrid.Repositories.DataRepository/Modules/TestingDataModule.cs
  • Repositories/Resgrid.Repositories.DataRepository/Queries/Sso/SelectSecurityPolicyByDepartmentIdQuery.cs
  • Repositories/Resgrid.Repositories.DataRepository/Queries/Sso/SelectSsoConfigByDepartmentIdAndTypeQuery.cs
  • Repositories/Resgrid.Repositories.DataRepository/Queries/Sso/SelectSsoConfigByEntityIdQuery.cs
  • Repositories/Resgrid.Repositories.DataRepository/Queries/Sso/SelectSsoConfigsByDepartmentIdQuery.cs
  • Tests/Resgrid.Tests/Bootstrapper.cs
  • Tests/Resgrid.Tests/Config/ConfigProcessorTests.cs
  • Tests/Resgrid.Tests/Providers/PhoneNumberValidatorProviderTests.cs
  • Tests/Resgrid.Tests/Resgrid.Tests.csproj
  • Tests/Resgrid.Tests/Services/ActionLogsServiceTests.cs
  • Tests/Resgrid.Tests/Services/AuthorizationServiceTests.cs
  • Tests/Resgrid.Tests/Services/CalendarExportServiceTests.cs
  • Tests/Resgrid.Tests/Services/CalendarServiceTests.cs
  • Tests/Resgrid.Tests/Services/CallEmailFactoryTests.cs
  • Tests/Resgrid.Tests/Services/CallsServiceTests.cs
  • Tests/Resgrid.Tests/Services/ScheduledTasksServiceTests.cs
  • Tests/Resgrid.Tests/Services/WorkflowTemplateRenderingTests.cs
  • Tests/Resgrid.Tests/Web/Mcp/SensitiveDataRedactorTests.cs
  • Web/Resgrid.Web.Services/Controllers/v4/CalendarController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/CalendarExportController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/ScimController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/WorkflowsController.cs
  • Web/Resgrid.Web.Services/Models/v4/Calendar/GetAllCalendarItemResult.cs
  • Web/Resgrid.Web.Services/Models/v4/Calendar/GetCalendarSubscriptionUrlResult.cs
  • Web/Resgrid.Web.Services/Models/v4/Sso/GetDepartmentSsoConfigResult.cs
  • Web/Resgrid.Web.Services/Models/v4/Sso/SsoAdminModels.cs
  • Web/Resgrid.Web.Services/Models/v4/Workflows/WorkflowModels.cs
  • Web/Resgrid.Web.Services/Resgrid.Web.Services.xml
  • Web/Resgrid.Web.Services/Startup.cs
  • Web/Resgrid.Web/Areas/User/Controllers/CalendarController.cs
  • Web/Resgrid.Web/Areas/User/Controllers/SecurityController.cs
  • Web/Resgrid.Web/Areas/User/Controllers/WorkflowsController.cs
  • Web/Resgrid.Web/Areas/User/Models/Calendar/CalendarItemV2Json.cs
  • Web/Resgrid.Web/Areas/User/Models/Calendar/CalendarItemView.cs
  • Web/Resgrid.Web/Areas/User/Models/Calendar/EditCalendarEntry.cs
  • Web/Resgrid.Web/Areas/User/Models/Calendar/IndexView.cs
  • Web/Resgrid.Web/Areas/User/Models/Security/SsoViews.cs
  • Web/Resgrid.Web/Areas/User/Views/Calendar/Edit.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Calendar/Index.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Calendar/New.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Calendar/View.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Security/Index.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Security/ScimSetup.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Security/SecurityPolicy.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Security/Sso.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Security/SsoEdit.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Shared/_Navigation.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Shared/_TopNavbar.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Shared/_UserLayout.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Workflows/Edit.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Workflows/RunDetail.cshtml
  • Web/Resgrid.Web/Areas/User/Views/Workflows/Runs.cshtml
  • Web/Resgrid.Web/Models/SaveStepRequest.cs
  • Web/Resgrid.Web/Models/ValidateConditionWebRequest.cs
  • Web/Resgrid.Web/Startup.cs
  • Web/Resgrid.Web/Views/Account/LogOn.cshtml
  • Web/Resgrid.Web/libman.json
  • Web/Resgrid.Web/wwwroot/css/fullcalendar-inspinia.css
  • Web/Resgrid.Web/wwwroot/js/app/internal/calendar/resgrid.calendar.editEntry.js
  • Web/Resgrid.Web/wwwroot/js/app/internal/calendar/resgrid.calendar.index.js
  • Web/Resgrid.Web/wwwroot/js/app/internal/calendar/resgrid.calendar.newEntry.js
  • Web/Resgrid.Web/wwwroot/js/app/internal/resgrid.user.js
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/CHANGELOG.md
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/CONTRIBUTING.md
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/LICENSE.txt
  • Web/Resgrid.Web/wwwroot/lib/fullcalendar/README.md

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

🟠 Major comments (41)
Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.it.resx-71-91 (1)

71-91: ⚠️ Potential issue | 🟠 Major

Incomplete Italian translations: most strings remain in English.

Only DeleteAccountHeader (line 78) is translated to Italian. The remaining user-facing strings (CheckToDelete, ConfirmDelete, DeleteAreYouSure1-3, DepartmentOwnerError) are still in English.

The typo "delete you account" → "delete your account" is also present on line 72.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.it.resx` around
lines 71 - 91, The resource file contains English strings and a typo that need
proper Italian translations and correction: update the values for keys
CheckToDelete, ConfirmDelete, DeleteAreYouSure1, DeleteAreYouSure2,
DeleteAreYouSure3, and DepartmentOwnerError with accurate Italian translations,
and fix the typo in CheckToDelete ("delete you account" → "delete your account")
before translating; keep DeleteAccountHeader as-is but verify consistency;
ensure punctuation and italics/apostrophes are localized correctly for all
updated resource entries.
Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.sv.resx-71-91 (1)

71-91: ⚠️ Potential issue | 🟠 Major

Incomplete Swedish translations: most strings remain in English.

Only DeleteAccountHeader (line 78) is translated to Swedish. The remaining user-facing strings (CheckToDelete, ConfirmDelete, DeleteAreYouSure1-3, DepartmentOwnerError) are still in English.

The typo "delete you account" → "delete your account" is also present on line 72.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.sv.resx` around
lines 71 - 91, The Swedish resource file has mostly English strings and a typo;
update the values for the resource keys CheckToDelete, ConfirmDelete,
DeleteAreYouSure1, DeleteAreYouSure2, DeleteAreYouSure3, and
DepartmentOwnerError to proper Swedish translations and fix the typo in
CheckToDelete ("delete you account" → "delete your account") so all user-facing
strings are localized consistently (refer to the resource keys named above and
preserve xml:space and element structure).
Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.uk.resx-71-91 (1)

71-91: ⚠️ Potential issue | 🟠 Major

Incomplete Ukrainian translations: most strings remain in English.

Only DeleteAccountHeader (line 78) is translated to Ukrainian. The remaining user-facing strings (CheckToDelete, ConfirmDelete, DeleteAreYouSure1-3, DepartmentOwnerError) are still in English.

The typo "delete you account" → "delete your account" is also present on line 72.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.uk.resx` around
lines 71 - 91, Several resource entries are still in English and one contains a
typo; update the values for resource keys CheckToDelete, ConfirmDelete,
DeleteAreYouSure1, DeleteAreYouSure2, DeleteAreYouSure3, and
DepartmentOwnerError to proper Ukrainian translations (and fix "delete you
account" → "delete your account" if you keep English for reference), ensuring
you only replace the inner <value> text for each key (leave the element
names/attributes intact) and keep encoding/escaping consistent; verify
DeleteAccountHeader remains unchanged.
Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.de.resx-71-91 (1)

71-91: ⚠️ Potential issue | 🟠 Major

Incomplete German translations: most strings remain in English.

Only DeleteAccountHeader (line 78) is translated to German. The remaining user-facing strings (CheckToDelete, ConfirmDelete, DeleteAreYouSure1-3, DepartmentOwnerError) are still in English.

The typo "delete you account" → "delete your account" is also present on line 72.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.de.resx` around
lines 71 - 91, The resource file contains mostly English strings and a typo;
update the values for the keys CheckToDelete, ConfirmDelete, DeleteAreYouSure1,
DeleteAreYouSure2, DeleteAreYouSure3 and DepartmentOwnerError to proper German
translations and fix the typo "delete you account" → "delete your account" (or
its German equivalent) so all user-facing strings are localized consistently
while keeping DeleteAccountHeader as-is; ensure each <data name="..."> value is
replaced with correct German text and preserve xml:space and element structure.
Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.fr.resx-71-91 (1)

71-91: ⚠️ Potential issue | 🟠 Major

Incomplete French translations: most strings remain in English.

Only DeleteAccountHeader (line 78) is translated to French. The remaining user-facing strings (CheckToDelete, ConfirmDelete, DeleteAreYouSure1-3, DepartmentOwnerError) are still in English.

The typo "delete you account" → "delete your account" is also present on line 72.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.fr.resx` around
lines 71 - 91, The resource file contains mostly English strings and a typo;
replace the English values for CheckToDelete, ConfirmDelete, DeleteAreYouSure1,
DeleteAreYouSure2, DeleteAreYouSure3, and DepartmentOwnerError with correct
French translations (keeping DeleteAccountHeader as-is), and fix the typo in
CheckToDelete ("delete you account" → "delete your account") before translating
so the French text is accurate and user-facing copy is fully localized.
Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.pl.resx-71-91 (1)

71-91: ⚠️ Potential issue | 🟠 Major

Incomplete Polish translations: most strings remain in English.

Only DeleteAccountHeader (line 78) is translated to Polish. The remaining user-facing strings (CheckToDelete, ConfirmDelete, DeleteAreYouSure1-3, DepartmentOwnerError) are still in English, resulting in a mixed-language UI for Polish users.

Additionally, line 72 contains a typo: "delete you account" should be "delete your account".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.pl.resx` around
lines 71 - 91, The resource file has incomplete Polish translations and a typo;
update the values for keys CheckToDelete, ConfirmDelete, DeleteAreYouSure1,
DeleteAreYouSure2, DeleteAreYouSure3, and DepartmentOwnerError to proper Polish
translations so the UI is consistently localized (leave DeleteAccountHeader
as-is), and fix the typo in CheckToDelete ("delete you account" → "delete your
account") before translating; locate these strings by their resource names
(CheckToDelete, ConfirmDelete, DeleteAreYouSure1, DeleteAreYouSure2,
DeleteAreYouSure3, DepartmentOwnerError) and replace the English text with
correct Polish equivalents.
Core/Resgrid.Localization/Areas/User/Logs/Logs.fr.resx-71-220 (1)

71-220: ⚠️ Potential issue | 🟠 Major

French locale file still contains substantial English UI text.

Many values are untranslated (for example at Line 72, Line 78, Line 111, Line 126, Line 168), which will produce a mixed-language UX. Also, Line 168 includes a typo ("Logs an be used").

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Logs/Logs.fr.resx` around lines 71 -
220, Several resource values remain in English and one contains a typo; update
the untranslated entries (e.g. data keys AddUnitsToLog, BodyLocation,
BodyLocationReq, CallName, CallPriority, CaseNumber, Investigator, Meeting,
NewCall, NewLog, NewLogHeader, NewLogInfo, OthersHavingContact,
PersonnelRequired, PresidingPeople, PronouncedDeceasedBy,
PronouncedDeceasedByReq, PronouncedDeceasedDateReq, SelectCall, SeniorOIC,
TrainingEndError, TrainingStartError, UnitPersonnel, Units, UnitsAndPersonnel,
WorkLogEndRequired, WorkLogStartRequired) with their correct French translations
and fix the typo in NewLogInfo ("Logs an be used" -> proper French equivalent
and/or correct English if intentionally English), ensuring the NewLogInfo value
is fully translated to French and consistent with existing phrasing; keep the
XML element names intact and only change the <value> text for each key.
Core/Resgrid.Localization/Areas/User/Logs/Logs.de.resx-71-220 (1)

71-220: ⚠️ Potential issue | 🟠 Major

German locale file is only partially translated.

A large number of entries remain English (e.g., Line 72, Line 78, Line 111, Line 126, Line 168), resulting in mixed-language UI. Line 168 also has a typo ("Logs an be used").

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Logs/Logs.de.resx` around lines 71 -
220, The resource file contains many untranslated English strings and a typo in
the NewLogInfo value; update the values for the untranslated resource keys
(e.g., AddUnitsToLog, BodyLocation, BodyLocationReq, CallName, CallPriority,
Cause, Condition, Investigator, LogInfo, LogsForYear, Meeting, MeetingType,
Narrative, NewCall, NewLog, NewLogHeader, NewLogInfo, OtherAttendees,
OthersHavingContact, Personnel, PersonnelRequired, PresidingPeople,
PronouncedDeceasedBy, SelectCall, SeniorOIC, TrainingEndError,
TrainingStartError, UnitPersonnel, UnitsAndPersonnel, WorkLogEndRequired,
WorkLogStartRequired, etc.) with correct German translations and correct the
typo in NewLogInfo ("Logs an be used" → "Logs can be used" or German
equivalent); review the entire file for any remaining English values and ensure
consistent German phrasing and punctuation across all <data name="..."> entries.
Core/Resgrid.Localization/Areas/User/Documents/Documents.sv.resx-71-115 (1)

71-115: ⚠️ Potential issue | 🟠 Major

Complete Swedish translation coverage for document strings.

Many values are still English (for example Line 71 AdminsOnlyLabel, Line 83 EditDocumentHeader, Line 95 NewDocumentNamePlaceholder, Line 113 ViewDocumentHeader). This results in mixed-language UI in the sv locale.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Documents/Documents.sv.resx` around
lines 71 - 115, Several resource entries in Documents.sv.resx remain in English;
update the value text for AdminsOnlyLabel, EditDocumentHeader,
NewDocumentNamePlaceholder, ViewDocumentHeader (and any other remaining English
strings such as Category/EveryoneLabel/Presentations/Spreadsheets if you find
them) to their Swedish equivalents, preserving the existing XML structure and
xml:space attributes; for example replace "Admins Only" -> "Endast
administratörer", "Edit Document" -> "Redigera dokument", "Name of the Document"
-> "Dokumentets namn", and "View Document" -> "Visa dokument", then save the
.resx with UTF-8 encoding.
Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.uk.resx-71-124 (1)

71-124: ⚠️ Potential issue | 🟠 Major

Ukrainian HomeDashboard localization is incomplete.

Only a small subset is localized (e.g., Line 75 Actions), while many keys remain English (for example Line 77 AreYouSureResetAll, Line 86 ConfirmStatusReset, Line 110 SetStaffingLevel, Line 122 ToggleCollapseGroupsOnce). This will show mixed-language UI for Ukrainian users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.uk.resx` around lines
71 - 124, The Ukrainian HomeDashboard resource file contains many entries still
in English (e.g., AreYouSureResetAll, ConfirmSetStandByGroup,
ConfirmStatusReset, DepartmentCode, DepartmentId, DepartmentInfo, ResetAll,
ResetGroupStandingBy, ResetStatusButton, SetCurrentAction, SetStaffingLevel,
StaffingLevel, StaffingLevelSubmit, TextNumber, ToggleCollapseGroupsOnce)
causing mixed-language UI; update each value to proper Ukrainian translations
for those keys (and verify the already-translated Actions remains correct) so
every <data name="..."> entry in HomeDashboard.uk.resx is localized
consistently, ensuring grammar and context match the original English strings.
Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.pl.resx-71-124 (1)

71-124: ⚠️ Potential issue | 🟠 Major

Polish HomeDashboard strings are largely untranslated.

Most keys still use English values (for example Line 71 ActionNote, Line 77 AreYouSureResetAll, Line 98 ResetAll, Line 122 ToggleCollapseGroupsOnce). This creates inconsistent language experience in the Polish locale.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Home/HomeDashboard.pl.resx` around lines
71 - 124, The Polish resource file has many untranslated strings—replace English
values with proper Polish translations for the keys ActionNote, Actions,
AreYouSureResetAll, CollapseGroups, ConfirmSetStandByGroup, ConfirmStatusReset,
DepartmentCode, DepartmentId, DepartmentInfo, ResetAll, ResetGroupStandingBy,
ResetStatusButton, SetCurrentAction, SetStaffingLevel, StaffingLevel,
StaffingLevelSubmit, TextNumber, and ToggleCollapseGroupsOnce; update each
<value> content to correct Polish text, ensure proper accents/grammar and
consistent phrasing across related keys (e.g., ResetAll vs ResetStatusButton vs
ResetGroupStandingBy), and run the app/localization tests to confirm no missing
resources or encoding issues.
Core/Resgrid.Localization/Areas/User/Documents/Documents.pl.resx-71-115 (1)

71-115: ⚠️ Potential issue | 🟠 Major

Localize the remaining English values for the Polish locale.

Several entries are still English (for example Line 71 AdminsOnlyLabel, Line 80 DeleteDocumentWarning, Line 92 NewDocumentHeader, Line 110 ViewableByLabel). This will surface mixed-language UI for Polish users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Documents/Documents.pl.resx` around
lines 71 - 115, Several resource values in the Polish .resx are still in
English—update the values for the keys AdminsOnlyLabel, DeleteDocumentWarning,
EditDocumentHeader, NewDocumentHeader, Presentations, Spreadsheets,
ViewableByLabel (and any other English-valued <data name="..."> entries) to
their Polish translations; locate each <data name="..."> entry (e.g.,
AdminsOnlyLabel, DeleteDocumentWarning, NewDocumentHeader, ViewableByLabel) and
replace the <value> text with the correct Polish phrase, preserving punctuation
and any placeholders and keeping xml:space="preserve" intact so the UI no longer
mixes languages.
Core/Resgrid.Localization/Areas/User/Documents/Documents.it.resx-71-115 (1)

71-115: ⚠️ Potential issue | 🟠 Major

Finish localization for Italian resource values.

Multiple values remain English (for example Line 71 AdminsOnlyLabel, Line 80 DeleteDocumentWarning, Line 98 Presentations, Line 110 ViewableByLabel). Users on the Italian locale will see mixed-language text.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Documents/Documents.it.resx` around
lines 71 - 115, Translate the remaining English resource values into Italian by
updating the value elements for the listed resource keys (e.g., AdminsOnlyLabel,
DeleteDocumentWarning, EditDocumentHeader, NewDocumentHeader,
NewDocumentNamePlaceholder, Presentations, Spreadsheets, UploadWarning,
ViewableByLabel, ViewDocumentHeader) so the Italian locale contains
all-localized strings; for example replace AdminsOnlyLabel -> "Solo
amministratori", DeleteDocumentWarning -> "ATTENZIONE: Questo eliminerà
permanentemente questo documento. Sei sicuro di voler eliminare il documento?",
EditDocumentHeader -> "Modifica documento", NewDocumentHeader -> "Nuovo
documento", NewDocumentNamePlaceholder -> "Nome del documento", Presentations ->
"Presentazioni", Spreadsheets -> "Fogli di calcolo", UploadWarning -> "Non tutti
i tipi di file sono consentiti! Il file deve essere inferiore a 10 MB e avere
una delle seguenti estensioni (.png, .jpg, .jpeg, .gif, .pdf, .doc, .docx, .txt,
.ppt, .pptx, .pps, .ppsx, .odt, .xls, .xlsx, .mp4, .mp3)", ViewableByLabel ->
"Visibile a", ViewDocumentHeader -> "Visualizza documento"; ensure consistent
punctuation and accents in the updated value elements.
Core/Resgrid.Localization/Areas/User/Contacts/Contacts.pl.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Localize remaining English values in the Polish resource file.

Contacts.pl.resx still has many English values (for example Line 72, Line 81, Line 123, Line 153, Line 366, Line 435). This causes inconsistent language rendering.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Contacts/Contacts.pl.resx` around lines
71 - 436, The Polish resource file Contacts.pl.resx contains many entries whose
<value> text is still in English (e.g., AddCategoryHeader, AddressPlaceholder,
CategoryDescriptionPlaceholder, EmailAddressHelper, ContactsInCategory,
LocationDetails, SaveNote, LoadingNotes, etc.); update each resource entry so
its <value> is the correct Polish translation for the key (review every data
name in the diff such as AddContact, AddressPlaceholder, BlueskyPlaceholder,
CategoryDescriptionPlaceholder, Company, EmailAddressHelper, ContactsInCategory,
EntranceGpsLatitudePlaceholderHelp, LocationGpsLatitudePlaceholderHelp,
TwitterPlaceholder, SaveNote, LoadingNotes, etc.), replacing the English strings
with proper Polish equivalents and keeping xml:space attributes intact so the UI
renders consistently in Polish.
Core/Resgrid.Localization/Areas/User/Contacts/Contacts.sv.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Finish Swedish translations for remaining English strings.

Contacts.sv.resx still includes many English values (for example Line 72, Line 81, Line 123, Line 153, Line 366, Line 435), which will produce mixed-language UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Contacts/Contacts.sv.resx` around lines
71 - 436, The resource file contains many English values that need Swedish
translations; update the remaining keys so the UI is consistently Swedish by
translating the English values for resource names such as AddCategoryHeader,
AddressPlaceholder, CategoryDescriptionPlaceholder, CategoryNamePlaceholder,
CellPhoneLabel/Placeholder, EmailAddressHelper, EmailAddressPlaceholder,
Location/Entrance/Exit GPS placeholder/help texts, FacebookPlaceholder,
Company/CompanyNamePlaceholder, ContactDetails/ContactInformation,
ContactsInCategory, ContactTypeLabel, DisplayOnMap, DataHeader,
DeleteUnitWarning, DescriptionLabel, Contact-related placeholders like
FirstNamePlaceholder/LastNamePlaceholder, Office/Home/Fax phone placeholders,
Social placeholders (FacebookPlaceholder, InstagramPlaceholder,
LinkedInPlaceholder, MastodonPlaceholder, TwitterPlaceholder,
ThreadsPlaceholder, WebsitePlaceholder), Note-related keys (NoNotesFound,
AddNewNote, NoteTitle, NoteContent, NoteType, ExpiresOn,
LeaveBlankForNoExpiration, ShouldAlert, ShouldAlertInfo, SaveNote),
Loading/Search labels and any other values still in English—replace each value
with an accurate Swedish translation, keeping the resource key names (e.g.,
AddCategoryHeader, AddressPlaceholder, EmailAddressHelper, TwitterPlaceholder,
CreatedBy) unchanged and preserving xml:space="preserve" formatting.
Core/Resgrid.Localization/Areas/User/Contacts/Contacts.de.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Finish German localization to avoid mixed UI language.

In Contacts.de.resx, many values are still English (for example Line 72, Line 81, Line 123, Line 153, Line 366, Line 435). Users selecting German will still see English text.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Contacts/Contacts.de.resx` around lines
71 - 436, The German resource file Contacts.de.resx contains many values still
in English which causes mixed UI language; update the English strings to proper
German translations for the resource keys shown in the diff (e.g.
AddressPlaceholder, BlueskyPlaceholder, CategoryDescriptionPlaceholder,
CellPhoneLabel, ContactsInCategory, ContactTypeLabel, DisplayOnMap,
EmailAddressHelper, ExitGpsLatitudePlaceholderHelp, TwitterPlaceholder,
WebsitePlaceholder, NoContactsInDepartment, NoContactsInThisCategory,
LoadingNotes, SearchNotes, EditContact, etc.), ensuring each <data name="...">
value is translated into German and retains any placeholders or formatting;
review the entire file for remaining English entries and replace them with
correct German text so the UI is fully localized.
Core/Resgrid.Localization/Areas/User/Contacts/Contacts.it.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Complete Italian translations for remaining keys.

Contacts.it.resx still includes many English values (for example Line 72, Line 81, Line 123, Line 183, Line 366, Line 435). This will show mixed-language UI for Italian users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Contacts/Contacts.it.resx` around lines
71 - 436, The Italian resource file contains many untranslated English values;
update all remaining keys that are still in English (e.g., AddressPlaceholder,
BlueskyPlaceholder, CategoryDescriptionPlaceholder, CellPhoneLabel/Placeholder,
ContactTypeLabel, CurrentPasswordHelp, DataHeader, DisplayOnMap,
EmailAddressHelper, EntranceGps*/ExitGps*/LocationGps* placeholders and helps,
FacebookPlaceholder, FaxPhonePlaceholder, FirstNamePlaceholder,
HomePhonePlaceholder, InstagramPlaceholder, LastNamePlaceholder, LastUpdated,
LinkedInPlaceholder, Mailing* placeholders, MapIcon, MastodonPlaceholder,
MiddleNamePlaceholder, NewContact,
NoContactsInDepartment/NoContactsInThisCategory, OfficePhonePlaceholder,
OtherNamePlaceholder, PostalCodePlaceholder, RoleCategoryWarning,
SameAsPhysical, StatePlaceholder, ThreadsPlaceholder, TwitterPlaceholder,
ViewCategoryHeader, ViewContact/ ViewContactHeader,
WebsiteNameLabel/WebsitePlaceholder, AdditionalInfo, CreatedBy, ContactType,
MailingAddressHeader, LocationDetails, SocialsInfo, NoNotesFound, AddNewNote,
NoteTitle, NoteContent, NoteType, ExpiresOn, LeaveBlankForNoExpiration,
ShouldAlert/ShouldAlertInfo, SaveNote, LoadingNotes, SearchNotes, EditContact)
by providing proper Italian translations for each value so the file is fully
localized; ensure translations keep any placeholders or punctuation intact and
follow the existing style used in other keys (e.g., capitalize labels
consistently).
Core/Resgrid.Localization/Areas/User/Contacts/Contacts.uk.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Complete Ukrainian translations for untranslated keys.

Contacts.uk.resx includes many English values (for example Line 72, Line 81, Line 123, Line 153, Line 366, Line 435). This results in mixed Ukrainian/English UI text.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Contacts/Contacts.uk.resx` around lines
71 - 436, The resource file Contacts.uk.resx contains many entries still in
English; update the untranslated values to complete Ukrainian translations for
keys such as AddCategoryHeader, AddressPlaceholder, BlueskyPlaceholder,
CategoryDescriptionPlaceholder, CellPhoneLabel, CityPlaceholder, Company,
CompanyNameLabel, CompanyNamePlaceholder, ContactsInCategory, ContactTypeLabel,
CurrentPasswordHelp, DataHeader, DescriptionLabel, DisplayOnMap,
EmailAddressHelper, EmailAddressPlaceholder, EntranceGps* and ExitGps*
placeholders, FacebookPlaceholder, FaxPhoneLabel, FirstNamePlaceholder,
HomePhonePlaceholder, InstagramPlaceholder, LastNamePlaceholder, LastUpdated,
LinkedInPlaceholder, LocationGps* placeholders, MailingAddressPlaceholder,
MailingCityPlaceholder, MailingPostalCodePlaceholder, MapIcon,
MastodonPlaceholder, MiddleNamePlaceholder, NewContact, NoContactsInDepartment,
NoContactsInThisCategory, OfficePhonePlaceholder, OtherContactHeader,
OtherInfoLabel, OtherNamePlaceholder, PhysicalAddressHeader,
PostalCodePlaceholder, RoleCategoryWarning, SameAsPhysical, StatePlaceholder,
ThreadsPlaceholder, TwitterPlaceholder, ViewCategoryHeader, ViewContactHeader,
WebsiteNameLabel, WebsitePlaceholder, AdditionalInfo, CreatedBy, ContactType,
MailingAddressHeader, LocationDetails, SocialsInfo, NoNotesFound, AddNewNote,
NoteTitle, NoteContent, NoteType, ExpiresOn, LeaveBlankForNoExpiration,
ShouldAlert, ShouldAlertInfo, SaveNote, LoadingNotes, SearchNotes and
EditContact — replace each English <value> with the correct Ukrainian
translation while preserving the xml keys (data name attributes) and xml
structure so the resource file remains valid.
Core/Resgrid.Localization/Areas/User/Contacts/Contacts.fr.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Complete the French localization set before merge.

This file is Contacts.fr.resx, but many values are still English (for example Line 72, Line 81, Line 129, Line 144, Line 366, Line 435). Shipping this will produce a mixed French/English UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Contacts/Contacts.fr.resx` around lines
71 - 436, The Contacts.fr.resx still contains many English values; update all
remaining English strings to French (and fix typos) before merging — e.g.,
translate keys like AddCategoryHeader, AddressPlaceholder,
CategoryDescriptionPlaceholder, CellPhoneLabel, CellPhonePlaceholder, Company,
CompanyNameLabel, CompanyNamePlaceholder, EmailAddressHelper,
EmailAddressPlaceholder, EntranceGpsLabel (and its Placeholder/Help entries),
ExitGpsLabel (and placeholders/helps), LocationGpsLabel (and
placeholders/helps), MapIcon, MastodonPlaceholder, MiddleNameLabel/Placeholder,
NewContact, NoContactsInDepartment, NoContactsInThisCategory,
OfficePhoneLabel/Placeholder, OtherContactHeader, PostalCodePlaceholder,
ThreadsPlaceholder, TwitterPlaceholder, ViewCategoryHeader, ViewContactHeader,
WebsiteNameLabel/Placeholder, AdditionalInfo, CreatedBy, ContactType,
LocationDetails, SocialsInfo, NoNotesFound, AddNewNote,
NoteTitle/NoteContent/NoteType, ExpiresOn, LeaveBlankForNoExpiration,
ShouldAlert/ShouldAlertInfo, SaveNote, LoadingNotes, SearchNotes, EditContact,
etc.; ensure each value is proper French phrasing, correct spelling (e.g.,
"Category Discription" → "Description de la catégorie"), and keep placeholders
meaningful and consistent with other French resources.
Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.pl.resx-71-262 (1)

71-262: ⚠️ Potential issue | 🟠 Major

Locale resource is largely untranslated.

This Polish resource still contains mostly English UI text (for example Line 72, Line 75, Line 141, Line 213). The locale experience will be inconsistent and partially untranslated.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.pl.resx`
around lines 71 - 262, The resource file contains many untranslated English
strings (e.g., values for keys CallPrioritiesHeader,
CallPriorityUsingDefaultText, CertificationTypesName, DepartmentTypesHeader,
DeleteContactNoteTypesWarning and many others); update each resource value to
the correct Polish translation for the corresponding UI text (translate the
entries for CallPrioritiesHeader, CallPriorityAlertSound,
CallPriorityUsingCustomText, CallPriorityUsingDefaultText,
CertificationTypesName, DepartmentTypesHeader, DeleteContactNoteTypesWarning,
DeleteDocumentTypesWarning, DeleteCallTypeWarning, DeleteUnitTypeWarning,
DeleteContactNoteTypesWarning, and any remaining English values), ensure wording
is consistent and grammatically correct in Polish, and run a quick pass to
confirm no remaining English strings exist in the DepartmentTypes.pl.resx
resource keys listed above.
Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.fr.resx-71-262 (1)

71-262: ⚠️ Potential issue | 🟠 Major

Locale resource is largely untranslated.

This French DepartmentTypes resource still contains mostly English text (for example Line 72, Line 75, Line 141, Line 213), leading to mixed-language UX in fr.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.fr.resx`
around lines 71 - 262, The fr resource file contains many English values that
must be translated to French to avoid mixed-language UX; update the values for
keys such as CallPrioritiesHeader, CallPriorityAlertSound,
CallPriorityUsingDefaultText, CallTypeMapIconHeader, CallTypeNameHeader,
CertificationTypesName, DocumentTypeNameLabel, DeleteCallTypeWarning,
DeleteDocumentTypesWarning, DeleteNoteTypesWarning, DeleteUnitTypeWarning,
NewDocumentTypeHeader, NoteTypesName, PriorityNameLabel, UnitTypeNameLabel,
ContactNoteTypesHeader, NewContactNoteTypesHeader,
DeleteContactNoteTypesWarning, ContactNoteTypeNameLabel and any other
English-valued <data name="..."> entries by replacing the English strings with
correct French translations (ensure grammar and accents are correct and keep
contextual meaning), and run a gettext/l10n review or native speaker
verification after updating to confirm accuracy.
Core/Resgrid.Localization/Areas/User/Department/Department.sv.resx-71-461 (1)

71-461: ⚠️ Potential issue | 🟠 Major

Swedish locale file is only partially localized.

A large portion of values remain English (for example Line 75, Line 84, Line 186, Line 336). This will present mixed-language UI in sv.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/Department.sv.resx` around
lines 71 - 461, The Swedish resource file contains many entries still in English
(e.g. resource keys DeleteDepartmentSettingsInfo,
DeleteDepartmentCurrentlyPendingInfo, MappingSettingsHeader,
SavedMappingSettings, PersonnelAllowOverwriteHelp, UnitAllowOverwriteHelp,
Address, ApiRssSettings, CallSettingsHeader, DefaultMapCenterLabel,
DeleteDepartmentInfo, RssActiveCallFeedInfo, RssActiveCallNoFeedInfo,
SavedDispatchSettings, DepartmentModuleSettingsInfo, SavedModuleSettings, etc.);
update each of these resource values to proper Swedish translations (or mark
them as untranslated only if a translator will supply them), ensuring consistent
Swedish phrasing/terminology and preserving any punctuation or placeholders, and
verify no English strings remain so the sv locale presents a fully localized UI.
Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.de.resx-71-262 (1)

71-262: ⚠️ Potential issue | 🟠 Major

Locale resource is largely untranslated.

This German resource still contains mostly English UI text (for example Line 72, Line 75, Line 141, Line 213). That creates mixed-language UI and breaks expected localization quality for de.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/DepartmentTypes.de.resx`
around lines 71 - 262, The German resource file contains many untranslated
entries (e.g., CallPrioritiesHeader, CallPriorityUsingDefaultText,
CertificationTypesName, DocumentTypeNameLabel, DeleteContactNoteTypesWarning)
causing mixed-language UI; translate the English <value> strings for those keys
(and any other English values in this diff such as CallPriorityAlertSound,
CallTypeNameLabel, NewDocumentTypesHeader, ContactNoteTypesHeader, etc.) into
proper German, preserving XML structure and xml:space attributes, and ensure
wording matches existing German style (e.g., "Abteilungstypen") and
grammar/terminology consistency across keys like CallTypesHeader,
DocumentTypesHeader, NoteTypesHeader, PriorityNameLabel, UnitTypesHeader,
ContactNoteTypeNameLabel.
Core/Resgrid.Localization/Areas/User/Department/Department.fr.resx-71-461 (1)

71-461: ⚠️ Potential issue | 🟠 Major

French locale file is only partially localized.

Many values remain English (for example Line 75, Line 84, Line 186, Line 336), so users selecting fr will still see mixed-language UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/Department.fr.resx` around
lines 71 - 461, The fr resource file contains many entries still in English
(e.g., keys like DeleteDepartmentSettingsInfo, RequestDepartmentDeletion,
SavedMappingSettings, AddressError, EmailAddressesHelp, RssActiveCallFeedInfo,
ProvisionFailureBody, RegenerateWarning, SavedDispatchSettings and others)
causing a mixed-language UI; update every value that is still English by
providing a proper French translation for each resource key, ensure
consistency/grammar across entries (including punctuation and accented
characters), and run a pass to verify keys such as MappingSettingsHeader,
PersonnelAllowOverwriteHelp, UnitAllowOverwriteHelp, DeleteDepartmentInfo,
SupressStaffingsInfo, and Disabled* labels are fully translated and tested in
the UI so no English strings remain.
Core/Resgrid.Localization/Areas/User/Department/Department.pl.resx-71-461 (1)

71-461: ⚠️ Potential issue | 🟠 Major

Polish locale file is only partially localized.

Many values remain English (for example Line 75, Line 84, Line 186, Line 336), which results in mixed-language UI for pl.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/Department.pl.resx` around
lines 71 - 461, The Polish resource file contains many entries still in English;
update Department.pl.resx so every <data> value is translated into Polish
(examples to check/translate include DeleteDepartmentSettingsInfo,
RequestDepartmentDeletion, DeleteDepartmentCurrentlyPendingInfo,
MappingSettingsHeader/SavedMappingSettings/MappingSettingsPersonnelHeader/MappingSettingsUnitsHeader,
CallSettingsHeader, CallSorting, CompletedOn, DefaultMapCenterLabel,
DeleteInviteWarning, DispatchImportEmailHelp, EmailAddressesHelp,
ProvisionFailureBody, RssActiveCallFeedInfo, RssActiveCallNoFeedInfo,
DeleteDepartmentInfo and similar keys), preserving any placeholders, escaped
characters (e.g. \', \", \\) and XML structure; review the file for any
remaining English strings and replace them with correct Polish translations with
proper diacritics.
Core/Resgrid.Localization/Areas/User/Department/Department.de.resx-71-461 (1)

71-461: ⚠️ Potential issue | 🟠 Major

German locale file is only partially localized.

A substantial number of values are still English (for example Line 75, Line 84, Line 186, Line 336), causing mixed-language UI for de.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/Department.de.resx` around
lines 71 - 461, The German resource file contains many entries still in English
(e.g., keys RequestDepartmentDeletion, DeleteDepartmentCurrentlyPendingInfo,
MappingSettingsHeader, SavedMappingSettings, ApiSettingsHeader,
CallSettingsHeader, DeleteDepartmentInfo, RssActiveCallFeedInfo,
DispatchSettingsHeader); update the value strings for these and any other
English values to proper German translations so the de locale is fully
localized, preserving punctuation, escape sequences (like &amp; or backslashes),
and any interpolation/placeholders, and ensure consistency/terminology across
keys such as DeleteDepartmentSettingsInfo, PersonnelAllowOverwriteHelp,
UnitAllowOverwriteHelp, and SupressStaffingsInfo.
Core/Resgrid.Localization/Areas/User/Department/Department.uk.resx-71-461 (1)

71-461: ⚠️ Potential issue | 🟠 Major

Ukrainian locale file is only partially localized.

Many values are still English (for example Line 75, Line 84, Line 186, Line 336), so users in uk will see mixed-language UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Department/Department.uk.resx` around
lines 71 - 461, The Ukrainian resource file contains many entries still in
English (e.g., resource keys DeleteDepartmentSettingsInfo,
DeleteDepartmentCurrentlyPendingInfo, MappingSettingsHeader,
SavedMappingSettings, SavedDispatchSettings, DeleteDepartmentInfo,
RegenerateWarning, ProvisionFailureBody and others) resulting in a
mixed-language UI; please replace the English value strings for all keys that
remain untranslated with proper Ukrainian translations (ensure grammatical
consistency and appropriate terminology), review entries such as AddressError,
ApiRssSettings, DispatchSettingsHeader, EmailAddressesHelp,
RssActiveCallFeedInfo, SupressStaffingsInfo and any other values visible in the
diff that are English, and run a follow-up QA pass to confirm no remaining
English strings remain in the uk resource file.
Core/Resgrid.Localization/Areas/User/Dispatch/Call.pl.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Polish locale file is only partially localized.

Many values remain English (for example Line 72, Line 129, Line 204, Line 303), which will present mixed-language strings to Polish users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Dispatch/Call.pl.resx` around lines 71 -
436, The Polish .resx file contains many strings still in English (partial
localization) which causes mixed-language UI; update the untranslated resource
values (e.g., ActiveCallsHelp, AddFilePlaceholder, CallNumberLabel,
LocationLabel, NameLabel, NewCallFormHeader, Note, NotesLabel,
PersonnelDispatchLabel, PrioirtyLabel, ProtocolsLabel, RedispatchCallHelp,
LocationPlaceholder, etc.) with correct Polish translations ensuring grammar and
context match existing localized entries; verify all <data name="..."> entries
across the file so none remain in English and run a resource compile/preview to
confirm no mixed-language texts remain.
Core/Resgrid.Localization/Areas/User/Dispatch/Call.sv.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Swedish localization is incomplete across many keys.

Numerous entries are still English (e.g., Line 72, Line 129, Line 204, Line 303), causing mixed-language UI in the Swedish locale.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Dispatch/Call.sv.resx` around lines 71 -
436, Many Swedish resource values are still in English causing mixed-language
UI; update the <value> text for the affected resource keys (for example
ActiveCallsHelp, CallNumberLabel, Contacts, LocationLabel, NameLabel,
NewCallFormHeader, PrioirtyLabel, PersonnelDispatchLabel, UnitsDispatchLabel,
and any other <data name="..."> entries still in English) to their proper
Swedish translations, ensuring grammar and consistency across the file, and scan
the entire Call.sv.resx for other English strings to translate so all <value>
elements are localized.
Core/Resgrid.Localization/Areas/User/Dispatch/Call.it.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Italian locale is still mostly English.

Many keys remain untranslated (for example Line 72, Line 129, Line 204, Line 303), so users in it will see mixed-language content.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Dispatch/Call.it.resx` around lines 71 -
436, Several resource entries in the Italian .resx are still in English (e.g.,
ActiveCallsHelp, CallNumberLabel, NameLabel, NewCallFormHeader and many others
noted in the diff); update all untranslated values to Italian so the it locale
is fully localized, leaving existing Italian translations intact (e.g., change
"Add a active call" -> proper Italian, "Numero" already present for
CallNumberLabel but ensure consistency where duplicates exist), review keys like
ActiveCalls, ActiveCallsHelp, CallNumberLabel, NameLabel, NewCallFormHeader,
PersonnelDispatchLabel, PrioirtyLabel, LocationLabel, UnitsDispatchLabel and all
other values in this file and replace English strings with correct Italian
translations, and run a quick pass to ensure no English strings remain in the
file.
Core/Resgrid.Localization/Areas/User/Dispatch/Call.uk.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

Ukrainian resource contains extensive untranslated English strings.

A large set of entries are still English (e.g., Line 72, Line 129, Line 204, Line 303), resulting in mixed-language UX for uk users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Dispatch/Call.uk.resx` around lines 71 -
436, The Ukrainian .resx contains many values left in English (e.g., resource
keys ActiveCalls, ActiveCallsHelp, AddArchivedCall, CreateCall,
CallIdentifierPlaceholder, CallNaturePlaceholder, CallNumberLabel, Contacts,
LocationLabel, NameLabel, NewCallFormHeader, PrioirtyLabel,
PersonnelDispatchLabel, ProtocolsLabel, UnitsDispatchLabel, and many others)
causing mixed-language UX; go through the listed keys and the file content and
replace the English <value> text with accurate Ukrainian translations (maintain
placeholders and punctuation), ensure keys like CallForm, CallNotesHeader,
DispatchLabel, LocationPlaceholder, NotesPlaceholder, and RegenerateCallWarning
are fully localized, and run a quick review to confirm no remaining English
strings remain in the uk resource file.
Core/Resgrid.Localization/Areas/User/Dispatch/Call.fr.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

French file has substantial untranslated English content.

A large number of strings are still English (e.g., Line 72, Line 129, Line 204, Line 303), which undermines locale completeness and leads to mixed-language UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Dispatch/Call.fr.resx` around lines 71 -
436, The French resource file contains many untranslated English values; update
all <data name="..."> entries left in English (examples: ActiveCalls,
CallNumberLabel, CallNumber, LocationLabel, NameLabel, NewCallFormHeader,
PrioirtyLabel, UnitsDispatchLabel, ArchivedCallsHeader, NewCallHeader,
PriorityLabel equivalents such as PrioirtyLabel) with proper French
translations, correct the misspelled key if needed (PrioirtyLabel →
PriorityLabel) or ensure its value is translated, and scan the entire file for
any remaining English strings to provide consistent French localization for keys
like ActiveCallsHelp, CallIdentifierPlaceholder, CallNaturePlaceholder,
LocationPlaceholder, NotesPlaceholder, and others before committing.
Core/Resgrid.Localization/Areas/User/Dispatch/Call.de.resx-71-436 (1)

71-436: ⚠️ Potential issue | 🟠 Major

German locale is still largely English.

Many values remain untranslated (for example Line 72, Line 129, Line 204, Line 303), so German users will see mixed-language UI. Please translate these entries or remove untranslated keys to fall back consistently.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Dispatch/Call.de.resx` around lines 71 -
436, The resource file contains many English values in the German locale (e.g.,
keys like ActiveCalls, ActiveCallsHelp, CallIdentifierPlaceholder, CallForm,
CallTemplatesLabel, CallExportHeader, RedispatchCallHelp, etc.); update each
value for the listed resource keys to proper German translations (or remove the
keys so the app falls back consistently) by editing the corresponding <data
name="..."> entries (use the key names such as ActiveCallsHelp,
CallIdentifierPlaceholder, CallForm, CallTemplatesLabel, RedispatchCallHelp to
locate them) and replace the English <value> text with correct German strings,
ensuring all entries in this .resx are translated or removed for consistent
German UI.
Core/Resgrid.Config/CalendarConfig.cs-10-13 (1)

10-13: ⚠️ Potential issue | 🟠 Major

Defaulting the public unauthenticated iCal feed to enabled is risky.

Line 13 enables a public feed by default, which can expose scheduling data on fresh deployments before admins explicitly opt in. Please make this secure-by-default (false).

🔐 Suggested change
-		public static bool ICalFeedEnabled = true;
+		public static bool ICalFeedEnabled = false;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Config/CalendarConfig.cs` around lines 10 - 13, The
CalendarConfig public flag ICalFeedEnabled is currently defaulted to true;
change its default to false to make the unauthenticated public iCal feed
secure-by-default by updating the static field ICalFeedEnabled to false in
CalendarConfig (and adjust any XML docs/comments to reflect the new default and
note that admins must enable it explicitly).
Core/Resgrid.Localization/Areas/User/Calendar/Calendar.fr.resx-62-70 (1)

62-70: ⚠️ Potential issue | 🟠 Major

French locale file is not fully localized and includes template keys.

Name1/Bitmap1/Icon1 should not ship, and several strings are still English (e.g., delete confirmations and calendar sync help/status text). Please remove template artifacts and complete French translations for user-facing keys.

Also applies to: 77-250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Calendar/Calendar.fr.resx` around lines
62 - 70, The .resx contains template artifact entries (Name1, Bitmap1, Icon1)
and untranslated English user-facing strings (e.g., delete confirmations and
calendar sync help/status text) that must be removed/translated; remove the
placeholder data nodes for Name1, Bitmap1, and Icon1 and replace any remaining
English values in the calendar resource (all user-facing keys between lines
~77-250) with proper French translations for confirmations and calendar sync
help/status text so the French locale is complete and contains only localized
resources.
Core/Resgrid.Localization/Areas/User/Calendar/Calendar.pl.resx-62-70 (1)

62-70: ⚠️ Potential issue | 🟠 Major

Polish locale file includes template entries and untranslated English content.

Please remove template artifacts (Name1, Bitmap1, Icon1) and localize remaining English values (notably confirmations, recurrence warnings, and calendar sync explanatory/status strings).

Also applies to: 77-250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Calendar/Calendar.pl.resx` around lines
62 - 70, Remove the leftover template entries Name1, Bitmap1 and Icon1 from the
Polish .resx and replace all remaining untranslated English strings in this
resource (notably confirmation texts, recurrence warning messages, and calendar
sync explanatory/status strings) with their correct Polish translations; scan
the rest of the file (lines after the shown diff, ~77–250) for other English
template artifacts and untranslated values and localize or remove them as
appropriate so the .resx contains only valid Polish resource entries.
Core/Resgrid.Localization/Areas/User/Calendar/Calendar.it.resx-62-70 (1)

62-70: ⚠️ Potential issue | 🟠 Major

Italian locale file still contains template artifacts and untranslated English strings.

This includes placeholder keys (Name1, Bitmap1, Icon1) and many English values (for example CalendarItemHeader, DeleteEventConfirm, CalendarSyncDescription). In a locale-specific RESX this produces mixed-language UI. Remove template keys and fully localize these values (or omit untranslated keys to allow fallback behavior).

Also applies to: 77-250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Calendar/Calendar.it.resx` around lines
62 - 70, The Italian RESX contains leftover template keys (Name1, Bitmap1,
Icon1) and multiple untranslated English entries (e.g., CalendarItemHeader,
DeleteEventConfirm, CalendarSyncDescription) that cause mixed-language UI;
remove the placeholder keys (Name1, Bitmap1, Icon1) and either provide proper
Italian translations for every English-valued resource in Calendar.it.resx
(including CalendarItemHeader, DeleteEventConfirm, CalendarSyncDescription and
the other entries between lines ~77-250) or delete those keys so the system
falls back to the default locale—ensure all resources kept are correctly
localized and that binary/template placeholders are not present.
Core/Resgrid.Localization/Areas/User/Calendar/Calendar.de.resx-62-70 (1)

62-70: ⚠️ Potential issue | 🟠 Major

German locale file is partially untranslated and still contains template keys.

Template entries should be removed, and English strings (confirmations, recurrence/help text, and sync status/help) should be translated to avoid mixed-language rendering.

Also applies to: 77-250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Calendar/Calendar.de.resx` around lines
62 - 70, The German resource file contains leftover template keys and English
strings; remove placeholder/template entries like data elements Name1, Bitmap1,
Icon1 and any other base64/template placeholders (lines ~62 and similar up to
250), and replace all remaining English UI strings (confirmation messages,
recurrence/help text, sync status/help, etc.) with proper German translations so
the file is fully localized; ensure you update the resource value elements for
the affected data names (e.g., any "Confirmation", "RecurrenceHelp",
"SyncStatusHelp" keys) with German text and delete unused template/base64
entries to prevent mixed-language rendering.
Core/Resgrid.Localization/Areas/User/Calendar/Calendar.sv.resx-62-70 (1)

62-70: ⚠️ Potential issue | 🟠 Major

Swedish locale file is not fully localized and includes template resource keys.

Name1/Bitmap1/Icon1 should be removed, and remaining English text should be translated to Swedish to prevent mixed-language UI in this locale.

Also applies to: 77-250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Calendar/Calendar.sv.resx` around lines
62 - 70, Remove the placeholder/template resource entries Name1, Bitmap1, and
Icon1 and any other template keys (they are unused and cause mixed-language UI);
then review every remaining <data> value in this Swedish locale resource and
replace the English strings with proper Swedish translations so all UI text is
localized (apply the same cleanup/translation for the remaining entries
referenced in the comment range). Ensure you only remove the template keys and
update the <value> text for the existing resource keys rather than renaming
keys.
Core/Resgrid.Localization/Areas/User/Calendar/Calendar.uk.resx-62-70 (1)

62-70: ⚠️ Potential issue | 🟠 Major

Ukrainian locale file still has template artifacts and English fallback text embedded.

Please remove placeholder keys and translate remaining English entries so the Ukrainian locale is consistently localized.

Also applies to: 77-250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Localization/Areas/User/Calendar/Calendar.uk.resx` around lines
62 - 70, The Ukrainian resource file contains template artifacts and English
fallback text: remove placeholder resource entries like "Name1", "Bitmap1", and
"Icon1" and any "[base64...]" placeholder values, then replace all remaining
English strings with proper Ukrainian translations so the Calendar.uk.resx
entries are fully localized; apply the same cleanup and translation to the other
affected entries (lines 77-250) ensuring no template placeholders or English
fallbacks remain.
Core/Resgrid.Config/SsoConfig.cs-2-4 (1)

2-4: ⚠️ Potential issue | 🟠 Major

Harden config surface: avoid writable public static globals for security-sensitive settings.

SsoFeatureEnabled, ScimFeatureEnabled, and IpRangeEnforcementEnabled are globally writable at runtime. That makes behavior non-deterministic and allows accidental disabling of controls. Prefer immutable values where possible, and restrict mutability for runtime flags.

🔧 Suggested hardening
- public static string ScimBasePath = "/scim/v2";
+ public static readonly string ScimBasePath = "/scim/v2";

- public static int ScimBearerTokenByteLength = 48;
+ public const int ScimBearerTokenByteLength = 48;

- public static string SsoDiscoveryPath = "/api/v4/connect/sso-config";
+ public static readonly string SsoDiscoveryPath = "/api/v4/connect/sso-config";

- public static string SamlAcsPath = "/api/v4/connect/saml-mobile-callback";
+ public static readonly string SamlAcsPath = "/api/v4/connect/saml-mobile-callback";

- public static string SamlEntityIdBasePath = "/saml/";
+ public static readonly string SamlEntityIdBasePath = "/saml/";

- public static bool SsoFeatureEnabled = true;
+ public static bool SsoFeatureEnabled { get; private set; } = true;

- public static bool ScimFeatureEnabled = true;
+ public static bool ScimFeatureEnabled { get; private set; } = true;

- public static bool IpRangeEnforcementEnabled = true;
+ public static bool IpRangeEnforcementEnabled { get; private set; } = true;

As per coding guidelines, "Prefer functional patterns and immutable data where appropriate in C#" and "Design for testability; avoid hidden dependencies inside methods and prefer explicit, pure functions".

Also applies to: 22-89

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Core/Resgrid.Config/SsoConfig.cs` around lines 2 - 4, SsoFeatureEnabled,
ScimFeatureEnabled, and IpRangeEnforcementEnabled are public writable static
fields making runtime behavior mutable; change them to immutable or at least
non-writable from outside: convert each to a public static read-only property
(e.g., public static bool SsoFeatureEnabled { get; } = <default>), or make the
backing field private and expose a public getter (private static bool
_ssoFeatureEnabled; public static bool SsoFeatureEnabled => _ssoFeatureEnabled),
and if runtime toggling is required provide controlled internal methods or an
explicit configuration object passed into consumers instead of public setters;
update usages referencing the fields to use the new properties/accessors
(SsoFeatureEnabled, ScimFeatureEnabled, IpRangeEnforcementEnabled).

// Convert back to local time first, then take just the date for the date-only picker.
if (model.Item.IsAllDay)
{
model.StartTime = model.Item.Start.TimeConverter(department).Date;

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'Edit' handles a POST request without performing CSRF token validation.
[HttpPost("ValidateCondition")]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = ResgridResources.Workflow_Create)]
public async Task<ActionResult<ValidateConditionResult>> ValidateCondition(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'ValidateCondition' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 2 days ago

In general, the fix is to ensure that every POST action that can be called from a browser and that uses cookie-based authentication validates an anti-forgery token. In ASP.NET Core MVC this is typically done by applying [ValidateAntiForgeryToken] (or by enabling [AutoValidateAntiforgeryToken] globally and optionally decorating APIs with [IgnoreAntiforgeryToken] where appropriate).

For this specific method, the minimal, non-functional-change fix is to add the [ValidateAntiForgeryToken] attribute to ValidateCondition. This action already uses [HttpPost] and [Authorize], so we simply add the CSRF attribute alongside them. The relevant file is Web/Resgrid.Web.Services/Controllers/v4/WorkflowsController.cs, around the existing ValidateCondition method declaration. No new methods or logic are required; ASP.NET Core already provides the antiforgery attribute in Microsoft.AspNetCore.Mvc, which is already imported at the top of the file. Thus, we only need to modify the attribute list above the method.

Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/WorkflowsController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/WorkflowsController.cs b/Web/Resgrid.Web.Services/Controllers/v4/WorkflowsController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/WorkflowsController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/WorkflowsController.cs
@@ -381,6 +381,7 @@
 		/// Validates a condition expression syntax and optionally evaluates it against a sample payload.
 		/// </summary>
 		[HttpPost("ValidateCondition")]
+		[ValidateAntiForgeryToken]
 		[ProducesResponseType(StatusCodes.Status200OK)]
 		[Authorize(Policy = ResgridResources.Workflow_Create)]
 		public async Task<ActionResult<ValidateConditionResult>> ValidateCondition(
EOF
@@ -381,6 +381,7 @@
/// Validates a condition expression syntax and optionally evaluates it against a sample payload.
/// </summary>
[HttpPost("ValidateCondition")]
[ValidateAntiForgeryToken]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = ResgridResources.Workflow_Create)]
public async Task<ActionResult<ValidateConditionResult>> ValidateCondition(
Copilot is powered by AI and may make mistakes. Always verify output.
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<SaveSecurityPolicyResult>> SaveSecurityPolicy(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'SaveSecurityPolicy' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 3 days ago

In general, to fix missing CSRF validation on ASP.NET Core MVC/Web API actions, you add the framework’s anti‑forgery validation attribute (e.g., [ValidateAntiForgeryToken] or [AutoValidateAntiforgeryToken]) to POST actions and ensure that clients send the corresponding token (usually in a header or form field). This causes the framework to reject cross‑site requests that lack a valid token, mitigating CSRF.

For this specific method, the minimal change that adds CSRF protection without altering existing business logic is to apply ASP.NET Core’s anti‑forgery validation attribute to SaveSecurityPolicy. Since this is a POST action that modifies sensitive security settings, we should decorate it with [ValidateAntiForgeryToken] in addition to the existing [HttpPost("SaveSecurityPolicy")] and [Authorize] attributes. ASP.NET Core’s anti‑forgery attribute lives in Microsoft.AspNetCore.Mvc, which is already imported at line 7, so no new using statements are needed. No internal logic changes are required; the framework will now enforce that valid anti‑forgery tokens accompany POST requests to this action.

Concretely:

  • In Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs, locate the SaveSecurityPolicy action (starting at line 341).
  • Add the [ValidateAntiForgeryToken] attribute above the method (typically just under [HttpPost("SaveSecurityPolicy")] or alongside the other attributes).
  • No additional methods or helpers are required in this file because anti‑forgery support comes from the existing MVC framework reference.
Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs b/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
@@ -344,6 +344,7 @@
 		/// a password — ensure at least one working SSO configuration exists first.
 		/// </summary>
 		[HttpPost("SaveSecurityPolicy")]
+		[ValidateAntiForgeryToken]
 		[Authorize(Policy = ResgridResources.Sso_Update)]
 		[ProducesResponseType(StatusCodes.Status200OK)]
 		[ProducesResponseType(StatusCodes.Status400BadRequest)]
EOF
@@ -344,6 +344,7 @@
/// a password — ensure at least one working SSO configuration exists first.
/// </summary>
[HttpPost("SaveSecurityPolicy")]
[ValidateAntiForgeryToken]
[Authorize(Policy = ResgridResources.Sso_Update)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
Copilot is powered by AI and may make mistakes. Always verify output.
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<RotateScimTokenResult>> RotateScimToken(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'RotateScimToken' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 3 days ago

In general, to fix “missing CSRF token validation” on an ASP.NET Core MVC or API controller action that uses cookie-based authentication, you add the framework’s anti-forgery validation attribute (e.g., [ValidateAntiForgeryToken] or [AutoValidateAntiforgeryToken]) to POST (and other state-changing) actions, and ensure that clients send a valid antiforgery token with those requests.

For this specific method, the minimal and most compatible fix is to decorate RotateScimToken with [ValidateAntiForgeryToken]. ASP.NET Core makes ValidateAntiForgeryTokenAttribute available via Microsoft.AspNetCore.Mvc, which is already imported at the top of this file, so no new using statements are required. We only need to add the attribute above the existing attributes on the RotateScimToken action in Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs. This preserves all existing behavior while adding CSRF protection. Any clients calling this endpoint via browser and cookie auth will then need to include the antiforgery token in their POST requests (typically via header or form field), which is the expected pattern in ASP.NET Core.

Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs b/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
@@ -263,6 +263,7 @@
 		/// </summary>
 		[HttpPost("RotateScimToken/{providerType}")]
 		[Authorize(Policy = ResgridResources.Sso_Update)]
+		[ValidateAntiForgeryToken]
 		[ProducesResponseType(StatusCodes.Status200OK)]
 		[ProducesResponseType(StatusCodes.Status403Forbidden)]
 		[ProducesResponseType(StatusCodes.Status404NotFound)]
EOF
@@ -263,6 +263,7 @@
/// </summary>
[HttpPost("RotateScimToken/{providerType}")]
[Authorize(Policy = ResgridResources.Sso_Update)]
[ValidateAntiForgeryToken]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
Copilot is powered by AI and may make mistakes. Always verify output.
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<SaveSsoConfigResult>> CreateSsoConfig(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'CreateSsoConfig' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 3 days ago

To fix missing CSRF token validation in ASP.NET Core MVC/API when using cookie-based authentication, the standard approach is to enable antiforgery tokens and ensure that state-changing actions validate them. For actions that perform important modifications (like creating SSO configs), you typically decorate them with [ValidateAntiForgeryToken] (or rely on [AutoValidateAntiforgeryToken] globally) and ensure the client sends the token in form data or headers.

In this specific case, the minimal and most targeted fix that does not alter existing functionality is to add the [ValidateAntiForgeryToken] attribute to the CreateSsoConfig action. This makes ASP.NET Core’s antiforgery system validate the token whenever this POST endpoint is called, mitigating CSRF while preserving the method’s logic, route, and authorization behavior. Since the file already imports Microsoft.AspNetCore.Mvc, which defines ValidateAntiForgeryTokenAttribute, no additional using directives are needed. The change should be applied at line 116–122 region, adding the attribute above the CreateSsoConfig method declaration.

If other POST actions in this controller also modify state and should be CSRF-protected, they would similarly need [ValidateAntiForgeryToken] or a shared/global antiforgery policy, but per the constraint, this fix is limited to the shown method.


Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs b/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/SsoAdminController.cs
@@ -114,6 +114,7 @@
 		/// encrypted using the department-specific key before storage.
 		/// </summary>
 		[HttpPost("CreateSsoConfig")]
+		[ValidateAntiForgeryToken]
 		[Authorize(Policy = ResgridResources.Sso_Create)]
 		[ProducesResponseType(StatusCodes.Status200OK)]
 		[ProducesResponseType(StatusCodes.Status400BadRequest)]
EOF
@@ -114,6 +114,7 @@
/// encrypted using the department-specific key before storage.
/// </summary>
[HttpPost("CreateSsoConfig")]
[ValidateAntiForgeryToken]
[Authorize(Policy = ResgridResources.Sso_Create)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
Copilot is powered by AI and may make mistakes. Always verify output.
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> CreateUser(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'CreateUser' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 3 days ago

In general, to fix missing CSRF protection for ASP.NET Core MVC actions, you either (a) enable global antiforgery validation for unsafe HTTP methods, or (b) apply [ValidateAntiForgeryToken] or [AutoValidateAntiforgeryToken] to specific controllers/actions, and ensure clients send a valid antiforgery token with each modifying request.

For this specific issue, the minimal, targeted fix is to require antiforgery validation on the CreateUser POST action. Since we can’t change the rest of the app, the safest change that doesn’t alter existing business logic is to add a CSRF-related attribute on CreateUser and, ideally, mark the controller as an MVC controller (not [ApiController] is shown, so [ValidateAntiForgeryToken] works in the standard way). The best single change within the provided snippet is to add [ValidateAntiForgeryToken] above CreateUser. The Microsoft.AspNetCore.Mvc namespace, already imported, contains this attribute, so no new imports are needed. No other behavioral changes are required; the antiforgery system will now reject POSTs lacking a valid token, mitigating CSRF.

Concretely:

  • In Web/Resgrid.Web.Services/Controllers/v4/ScimController.cs, just above the CreateUser action (line 115), add [ValidateAntiForgeryToken] on its own line under the existing [HttpPost("Users")] attribute.
  • No additional helper methods or services are required for this change.

Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/ScimController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/ScimController.cs b/Web/Resgrid.Web.Services/Controllers/v4/ScimController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/ScimController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/ScimController.cs
@@ -109,6 +109,7 @@
 
 		/// <summary>Creates a new user via SCIM provisioning.</summary>
 		[HttpPost("Users")]
+		[ValidateAntiForgeryToken]
 		[ProducesResponseType(StatusCodes.Status201Created)]
 		[ProducesResponseType(StatusCodes.Status400BadRequest)]
 		[ProducesResponseType(StatusCodes.Status401Unauthorized)]
EOF
@@ -109,6 +109,7 @@

/// <summary>Creates a new user via SCIM provisioning.</summary>
[HttpPost("Users")]
[ValidateAntiForgeryToken]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
[AllowAnonymous]
[ProducesResponseType(StatusCodes.Status302Found)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> SamlMobileCallback(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'SamlMobileCallback' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 3 days ago

In general, POST endpoints that accept state-changing or security-sensitive data should validate an anti-forgery (CSRF) token using the framework’s mechanism, typically by applying [ValidateAntiForgeryToken] (or [AutoValidateAntiforgeryToken] globally). This requires that clients include the token in the request, usually via a hidden form field or header.

For this specific method, the minimal and most compatible fix without changing its functional semantics is to require CSRF token validation for the POST variant while keeping the GET route as-is for flows that cannot send anti-forgery tokens. We can do this by adding [ValidateAntiForgeryToken] to the action and explicitly allowing anonymous access (which is already there). ASP.NET Core’s ValidateAntiForgeryTokenAttribute is in Microsoft.AspNetCore.Mvc, which is already imported at the top of the file, so no new using is necessary. The change is localized to the attribute list above SamlMobileCallback in Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs, adding [ValidateAntiForgeryToken] between the HTTP method attributes and [AllowAnonymous]. No further code changes are needed in this snippet.

Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs b/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs
@@ -489,6 +489,7 @@
 		/// </summary>
 		[HttpPost("saml-mobile-callback")]
 		[HttpGet("saml-mobile-callback")]
+		[ValidateAntiForgeryToken]
 		[AllowAnonymous]
 		[ProducesResponseType(StatusCodes.Status302Found)]
 		[ProducesResponseType(StatusCodes.Status400BadRequest)]
EOF
@@ -489,6 +489,7 @@
/// </summary>
[HttpPost("saml-mobile-callback")]
[HttpGet("saml-mobile-callback")]
[ValidateAntiForgeryToken]
[AllowAnonymous]
[ProducesResponseType(StatusCodes.Status302Found)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[Produces("application/json")]
public async Task<IActionResult> ExternalToken(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'ExternalToken' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 3 days ago

Generally, the fix is to ensure that any MVC action handling a POST that can affect authentication or user state validates an anti-forgery token when invoked from a browser. In ASP.NET Core, this is done by decorating the action with [ValidateAntiForgeryToken] (and generating a corresponding token in the form/view using the built-in helpers). For API-style endpoints that are truly CSRF-agnostic, they are usually marked with [IgnoreAntiforgeryToken] or kept on a different pipeline, but here we’ll follow the recommendation to add validation.

Concretely, in Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs, on the ExternalToken action at line 322, we should add the [ValidateAntiForgeryToken] attribute above the method (or among its existing attributes). Since Microsoft.AspNetCore.Mvc is already imported, no new using is necessary. This change preserves existing logic and only enforces that callers provide a valid anti-forgery token, assuming the frontend is updated accordingly.

Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs b/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/ConnectController.cs
@@ -315,6 +315,7 @@
 		/// </summary>
 		[HttpPost("external-token")]
 		[AllowAnonymous]
+		[ValidateAntiForgeryToken]
 		[ProducesResponseType(StatusCodes.Status200OK)]
 		[ProducesResponseType(StatusCodes.Status400BadRequest)]
 		[ProducesResponseType(StatusCodes.Status401Unauthorized)]
EOF
@@ -315,6 +315,7 @@
/// </summary>
[HttpPost("external-token")]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
[HttpPost("RegenerateCalendarSubscriptionUrl")]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = ResgridResources.Schedule_View)]
public async Task<ActionResult<GetCalendarSubscriptionUrlResult>> RegenerateCalendarSubscriptionUrl(

Check failure

Code scanning / CodeQL

Missing cross-site request forgery token validation High

Method 'RegenerateCalendarSubscriptionUrl' handles a POST request without performing CSRF token validation.

Copilot Autofix

AI 3 days ago

In general, to fix missing CSRF protection on ASP.NET Core MVC actions that mutate state, you add antiforgery validation to those actions (e.g., [ValidateAntiForgeryToken] or [AutoValidateAntiforgeryToken]) and ensure clients send the antiforgery token with their POST requests. This ensures that only requests originating from pages that obtained a valid token from your site can successfully invoke the action.

For this specific case, the best minimally invasive fix that preserves existing behavior is to decorate RegenerateCalendarSubscriptionUrl with ASP.NET Core’s [ValidateAntiForgeryToken] attribute. This will require ensuring the Microsoft.AspNetCore.Mvc namespace is available (it already is in this file via using Microsoft.AspNetCore.Mvc;). No changes to the method body are needed. The attribute should be added directly above the method definition (or just under the existing [HttpPost("RegenerateCalendarSubscriptionUrl")] attribute) in Web/Resgrid.Web.Services/Controllers/v4/CalendarExportController.cs at line 99.


Suggested changeset 1
Web/Resgrid.Web.Services/Controllers/v4/CalendarExportController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/CalendarExportController.cs b/Web/Resgrid.Web.Services/Controllers/v4/CalendarExportController.cs
--- a/Web/Resgrid.Web.Services/Controllers/v4/CalendarExportController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/CalendarExportController.cs
@@ -94,6 +94,7 @@
 		/// subscription URLs for the authenticated user.
 		/// </summary>
 		[HttpPost("RegenerateCalendarSubscriptionUrl")]
+		[ValidateAntiForgeryToken]
 		[ProducesResponseType(StatusCodes.Status200OK)]
 		[Authorize(Policy = ResgridResources.Schedule_View)]
 		public async Task<ActionResult<GetCalendarSubscriptionUrlResult>> RegenerateCalendarSubscriptionUrl(
EOF
@@ -94,6 +94,7 @@
/// subscription URLs for the authenticated user.
/// </summary>
[HttpPost("RegenerateCalendarSubscriptionUrl")]
[ValidateAntiForgeryToken]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = ResgridResources.Schedule_View)]
public async Task<ActionResult<GetCalendarSubscriptionUrlResult>> RegenerateCalendarSubscriptionUrl(
Copilot is powered by AI and may make mistakes. Always verify output.

<div class="wrapper wrapper-content animated fadeInRight">
<form asp-action="@(Model.IsNew ? "SsoNew" : "SsoEdit")"
asp-route-id="@Model.DepartmentSsoConfigId"

Check warning

Code scanning / CodeQL

Cross-site scripting Medium

User-provided value
flows to here and is written to HTML or JavaScript: Microsoft.AspNetCore.Mvc.Razor.RazorPageBase.WriteLiteral() method.
User-provided value
flows to here and is written to HTML or JavaScript: Microsoft.AspNetCore.Mvc.Razor.RazorPageBase.WriteLiteral() method.

Copilot Autofix

AI 2 days ago

General approach: Ensure that the user-provided identifier (DepartmentSsoConfigId) is validated/normalized on POST before the model is passed back to the view, and avoid reflecting arbitrary untrusted strings. Since Razor already HTML-encodes output, the main remaining risk is allowing unexpected or malicious characters into identifiers that may later be used in less-safe contexts. The least-invasive fix is to normalize model.DepartmentSsoConfigId server-side (e.g., restrict to a known-safe pattern like an alphanumeric GUID-style token, or fall back to null/empty when invalid) before returning View("SsoEdit", model).

Concretely, in SecurityController.cs, in both SsoNew (POST) and SsoEdit (POST) actions, where we return the "SsoEdit" view when ModelState is invalid, we should sanitize model.DepartmentSsoConfigId just before returning the view. For example, we can add a small helper method SanitizeDepartmentSsoConfigId inside the controller that trims input and ensures it only contains allowed characters (e.g., letters, digits, hyphen, underscore). If the value fails validation, we null it out or set it to an empty string. This does not change existing functional behavior for valid IDs, but prevents unexpected strings from being reflected. No changes are needed in the Razor view, since it is already encoding output; we only make the identifier safe and predictable.

Implementation details:

  • File: Web/Resgrid.Web/Areas/User/Controllers/SecurityController.cs.
  • Add a private helper method SanitizeDepartmentSsoConfigId(string id) to the SecurityController class.
  • In SsoNew(SsoConfigEditView model, CancellationToken cancellationToken), right before each return View("SsoEdit", model); (there are three such returns in the snippet: for invalid ModelState, invalid ProviderType, and when a config already exists), set model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);.
  • In SsoEdit(SsoConfigEditView model, CancellationToken cancellationToken), before the return View("SsoEdit", model); inside the if (!ModelState.IsValid) block, also sanitize model.DepartmentSsoConfigId.
  • The helper can use System.Text.RegularExpressions.Regex to enforce an allowed pattern; we add using System.Text.RegularExpressions; at the top of the controller file.

This keeps behavior for valid identifiers unchanged, ensures that any reflected value is constrained to a safe character set, and addresses all CodeQL variants pointing to this flow.


Suggested changeset 1
Web/Resgrid.Web/Areas/User/Controllers/SecurityController.cs
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Web/Resgrid.Web/Areas/User/Controllers/SecurityController.cs b/Web/Resgrid.Web/Areas/User/Controllers/SecurityController.cs
--- a/Web/Resgrid.Web/Areas/User/Controllers/SecurityController.cs
+++ b/Web/Resgrid.Web/Areas/User/Controllers/SecurityController.cs
@@ -20,6 +20,7 @@
 using Resgrid.Web.Attributes;
 using IdentityUser = Resgrid.Model.Identity.IdentityUser;
 using Microsoft.Extensions.Localization;
+using System.Text.RegularExpressions;
 
 namespace Resgrid.Web.Areas.User.Controllers
 {
@@ -655,6 +656,20 @@
 			return View(model);
 		}
 
+		private string SanitizeDepartmentSsoConfigId(string id)
+		{
+			if (string.IsNullOrWhiteSpace(id))
+				return null;
+
+			id = id.Trim();
+
+			// Allow only alphanumerics, dash and underscore in the identifier
+			if (!Regex.IsMatch(id, "^[A-Za-z0-9_-]+$"))
+				return null;
+
+			return id;
+		}
+
 		// ── Create SSO config ────────────────────────────────────────────────
 
 		[HttpGet]
@@ -692,6 +707,7 @@
 			{
 				model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
 				model.RankList = await BuildRankListAsync(model.DefaultRankId);
+				model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
 				return View("SsoEdit", model);
 			}
 
@@ -700,6 +716,7 @@
 				ModelState.AddModelError("ProviderType", "Invalid provider type.");
 				model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
 				model.RankList = await BuildRankListAsync(model.DefaultRankId);
+				model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
 				return View("SsoEdit", model);
 			}
 
@@ -709,9 +726,11 @@
 				ModelState.AddModelError("", $"An SSO configuration for {model.ProviderType.ToUpperInvariant()} already exists. Use Edit to modify it.");
 				model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
 				model.RankList = await BuildRankListAsync(model.DefaultRankId);
+				model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
 				return View("SsoEdit", model);
 			}
 
+			// additional logic...
 			var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId);
 			var config = new DepartmentSsoConfig
 			{
@@ -796,6 +812,7 @@
 			{
 				model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
 				model.RankList = await BuildRankListAsync(model.DefaultRankId);
+				model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
 				return View("SsoEdit", model);
 			}
 
EOF
@@ -20,6 +20,7 @@
using Resgrid.Web.Attributes;
using IdentityUser = Resgrid.Model.Identity.IdentityUser;
using Microsoft.Extensions.Localization;
using System.Text.RegularExpressions;

namespace Resgrid.Web.Areas.User.Controllers
{
@@ -655,6 +656,20 @@
return View(model);
}

private string SanitizeDepartmentSsoConfigId(string id)
{
if (string.IsNullOrWhiteSpace(id))
return null;

id = id.Trim();

// Allow only alphanumerics, dash and underscore in the identifier
if (!Regex.IsMatch(id, "^[A-Za-z0-9_-]+$"))
return null;

return id;
}

// ── Create SSO config ────────────────────────────────────────────────

[HttpGet]
@@ -692,6 +707,7 @@
{
model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
model.RankList = await BuildRankListAsync(model.DefaultRankId);
model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
return View("SsoEdit", model);
}

@@ -700,6 +716,7 @@
ModelState.AddModelError("ProviderType", "Invalid provider type.");
model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
model.RankList = await BuildRankListAsync(model.DefaultRankId);
model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
return View("SsoEdit", model);
}

@@ -709,9 +726,11 @@
ModelState.AddModelError("", $"An SSO configuration for {model.ProviderType.ToUpperInvariant()} already exists. Use Edit to modify it.");
model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
model.RankList = await BuildRankListAsync(model.DefaultRankId);
model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
return View("SsoEdit", model);
}

// additional logic...
var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId);
var config = new DepartmentSsoConfig
{
@@ -796,6 +812,7 @@
{
model.ProviderTypes = BuildProviderTypeList(model.ProviderType);
model.RankList = await BuildRankListAsync(model.DefaultRankId);
model.DepartmentSsoConfigId = SanitizeDepartmentSsoConfigId(model.DepartmentSsoConfigId);
return View("SsoEdit", model);
}

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
@ucswift
Copy link
Member Author

ucswift commented Mar 3, 2026

Approve

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is approved.

@ucswift ucswift merged commit f7ffd8b into master Mar 3, 2026
15 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant