Skip to content

Commit d33803b

Browse files
authored
Merge pull request #458 from Resgrid/develop
RG-T117 API CORS fix
2 parents 93a86a0 + ab5355d commit d33803b

31 files changed

Lines changed: 729 additions & 80 deletions

File tree

Core/Resgrid.Config/ApiConfig.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public static class ApiConfig
2020
/// to the API and eventing hubs, on top of the configured base urls, their subdomains and
2121
/// their shared parent domain (see Resgrid.Config.CorsHelper). Entries with a scheme match
2222
/// the exact origin ("http://localhost:8081"); bare hosts match that host on any scheme and
23-
/// port ("dispatch.example.com"). A single "*" allows every origin — intended only for
23+
/// port ("dispatch.example.com"); wildcard hosts match the apex and every subdomain on any
24+
/// scheme and port ("*.resgrid.com"). A single "*" allows every origin — intended only for
2425
/// isolated on-prem or development installs.
2526
/// </summary>
2627
public static string CorsAllowedOrigins = "";

Core/Resgrid.Config/CorsHelper.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ namespace Resgrid.Config
88
/// An origin is allowed when it matches any of:
99
/// 1. An entry in <see cref="ApiConfig.CorsAllowedOrigins"/>. Entries with a scheme
1010
/// ("http://localhost:8081") must match the origin's scheme, host and port exactly; bare
11-
/// hosts ("dispatch.example.com") match that host on any scheme/port. A single "*" entry
12-
/// allows every origin and is intended only for isolated on-prem or development installs.
11+
/// hosts ("dispatch.example.com") match that host on any scheme/port; wildcard hosts
12+
/// ("*.resgrid.com") match the apex and every subdomain on any scheme/port. An entry equal
13+
/// to the raw Origin header value also matches verbatim, which covers desktop-app origins
14+
/// like Electron's "app://." that are not standard URIs. A single "*" entry allows every
15+
/// origin and is intended only for isolated on-prem or development installs.
1316
/// 2. The host of one of the configured base urls (ResgridBaseUrl, ResgridApiBaseUrl,
1417
/// ResgridEventingBaseUrl), or any subdomain of one of those hosts.
1518
/// 3. The widest safe parent domain of a base-url host, or any subdomain of it. This is what
@@ -82,7 +85,16 @@ public static class CorsHelper
8285
/// </summary>
8386
public static bool IsAllowedOrigin(string origin)
8487
{
85-
if (String.IsNullOrWhiteSpace(origin) || !Uri.TryCreate(origin, UriKind.Absolute, out var originUri) || String.IsNullOrWhiteSpace(originUri.Host))
88+
if (String.IsNullOrWhiteSpace(origin))
89+
return false;
90+
91+
// Verbatim config match before URI parsing: desktop-app origins such as
92+
// Electron's custom-scheme "app://." are not reliably parseable as absolute
93+
// URIs, so an exact entry must be honored without going through Uri.
94+
if (MatchesConfiguredOriginVerbatim(origin))
95+
return true;
96+
97+
if (!Uri.TryCreate(origin, UriKind.Absolute, out var originUri) || String.IsNullOrWhiteSpace(originUri.Host))
8698
return false;
8799

88100
if (MatchesConfiguredOrigin(originUri))
@@ -109,6 +121,25 @@ public static bool IsAllowedOrigin(string origin)
109121
return false;
110122
}
111123

124+
private static bool MatchesConfiguredOriginVerbatim(string origin)
125+
{
126+
var configured = ApiConfig.CorsAllowedOrigins;
127+
if (String.IsNullOrWhiteSpace(configured))
128+
return false;
129+
130+
foreach (var rawEntry in configured.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
131+
{
132+
var entry = rawEntry.Trim();
133+
if (entry.Length == 0)
134+
continue;
135+
136+
if (entry == "*" || String.Equals(entry, origin, StringComparison.OrdinalIgnoreCase))
137+
return true;
138+
}
139+
140+
return false;
141+
}
142+
112143
private static bool MatchesConfiguredOrigin(Uri originUri)
113144
{
114145
var configured = ApiConfig.CorsAllowedOrigins;
@@ -124,6 +155,17 @@ private static bool MatchesConfiguredOrigin(Uri originUri)
124155
if (entry == "*")
125156
return true;
126157

158+
if (entry.StartsWith("*.", StringComparison.Ordinal))
159+
{
160+
// Wildcard host: "*.resgrid.com" allows the apex and every subdomain,
161+
// on any scheme and port.
162+
var suffix = entry.Substring(2);
163+
if (suffix.Length > 0 && HostMatchesOrIsSubdomainOf(originUri.Host, suffix))
164+
return true;
165+
166+
continue;
167+
}
168+
127169
if (entry.Contains("://"))
128170
{
129171
if (Uri.TryCreate(entry, UriKind.Absolute, out var entryUri) &&

Core/Resgrid.Framework/Logging.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ public static void LogError(string message)
108108

109109
}
110110

111+
public static void LogWarning(string message)
112+
{
113+
Initialize(null);
114+
115+
116+
if (_logger != null)
117+
_logger.Warning(message);
118+
119+
}
120+
111121
public static void LogDebug(string message)
112122
{
113123
Initialize(null);

Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.ar.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@
135135
<data name="DeleteAreYouSure3" xml:space="preserve">
136136
<value>يُرجى ملاحظة أن البيانات المقدمة إلى Resgrid لقسم ما تخص ذلك القسم وقد تخضع لسياسات الاحتفاظ بالبيانات والقوانين السارية في نطاق القسم. سيؤدي حذف حسابك إلى مسح معلوماتك الشخصية (PII) وحذف بيانات تسجيل الدخول، لكنه لن يمسح جميع البيانات. ستحتاج إلى تقديم طلب إلى القسم الذي كنت منتمياً إليه إذا كنت تريد مسح جميع البيانات.</value>
137137
</data>
138+
<data name="DeleteAreYouSure4" xml:space="preserve">
139+
<value>سيؤدي حذف حسابك إلى إلغاء تنشيطه في جميع الأقسام التي أنت عضو فيها، وليس فقط القسم الحالي. ستتم إزالة جميع الأتمتة المجدولة الخاصة بك (تسليم التقارير، وتغييرات الحالة المجدولة، وتغييرات التوظيف المجدولة)، وستتوقف عن تلقي الإشعارات والمراسلات من جميع الأقسام.</value>
140+
</data>
138141
<data name="DepartmentOwnerError" xml:space="preserve">
139142
<value>لا يمكنك حذف حسابك لأنك مالك قسم. إذا كنت ترغب في حذف القسم، ستحتاج إلى الوصول إليه عبر صفحة إعدادات القسم. إذا كنت تريد الاحتفاظ بالقسم، فاختر شخصاً آخر ليكون مالكاً للقسم ثم حاول حذف حسابك مرة أخرى.</value>
140143
</data>

Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.de.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
<data name="DeleteAreYouSure3" xml:space="preserve">
8787
<value>Please note, data supplied to Resgrid for a department is owned by that department and could be subject to data retention policies and laws governing the jurisdiction of the department. Deleting your account here will clear your PII (Personally Identifiable Information) and delete your login but won’t clear all data. You will need to make a request to the department you were apart of for additional if you want all data cleared.</value>
8888
</data>
89+
<data name="DeleteAreYouSure4" xml:space="preserve">
90+
<value>Wenn Sie Ihr Konto löschen, wird es in JEDER Abteilung deaktiviert, in der Sie Mitglied sind - nicht nur in Ihrer aktuellen. Alle Ihre geplanten Automatisierungen (Berichtszustellungen, geplante Statusänderungen und geplante Besetzungsänderungen) werden entfernt, und Sie erhalten keine Benachrichtigungen und Mitteilungen mehr von allen Abteilungen.</value>
91+
</data>
8992
<data name="DepartmentOwnerError" xml:space="preserve">
9093
<value>You are unable to delete your account because you are a Department Owner in a department. If you wish to delete the department you will need to access that though the Department Settings page. If you want to retain the department please choose another person as the Department Owner and then try and delete your account again.</value>
9194
</data>

Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.en.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@
135135
<data name="DeleteAreYouSure3" xml:space="preserve">
136136
<value>Please note, data supplied to Resgrid for a department is owned by that department and could be subject to data retention policies and laws governing the jurisdiction of the department. Deleting your account here will clear your PII (Personally Identifiable Information) and delete your login but won’t clear all data. You will need to make a request to the department you were apart of for additional if you want all data cleared.</value>
137137
</data>
138+
<data name="DeleteAreYouSure4" xml:space="preserve">
139+
<value>Deleting your account will deactivate it in EVERY department you are a member of, not just your current one. All of your scheduled automations (report deliveries, scheduled status changes and scheduled staffing changes) will be removed, and you will stop receiving notifications and communications from all departments.</value>
140+
</data>
138141
<data name="DepartmentOwnerError" xml:space="preserve">
139142
<value>You are unable to delete your account because you are a Department Owner in a department. If you wish to delete the department you will need to access that though the Department Settings page. If you want to retain the department please choose another person as the Department Owner and then try and delete your account again.</value>
140143
</data>

Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.es.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
<data name="DeleteAreYouSure3" xml:space="preserve">
8787
<value>Ten en cuenta que los datos suministrados a Resgrid para un departamento son propiedad de ese departamento y pueden estar sujetos a políticas de retención de datos. Eliminar tu cuenta aquí borrará tu información personal (PII) y tu acceso, pero no todos los datos.</value>
8888
</data>
89+
<data name="DeleteAreYouSure4" xml:space="preserve">
90+
<value>Eliminar su cuenta la desactivará en TODOS los departamentos de los que sea miembro, no solo en el actual. Todas sus automatizaciones programadas (entregas de informes, cambios de estado programados y cambios de personal programados) serán eliminadas, y dejará de recibir notificaciones y comunicaciones de todos los departamentos.</value>
91+
</data>
8992
<data name="DepartmentOwnerError" xml:space="preserve">
9093
<value>No puedes eliminar tu cuenta porque eres propietario de un departamento. Si deseas eliminar el departamento, debes acceder a eso a través de la página de configuración del departamento. Si deseas conservar el departamento, elige a otra persona como propietario del departamento y luego intenta eliminar tu cuenta.</value>
9194
</data>

Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.fr.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
<data name="DeleteAreYouSure3" xml:space="preserve">
8787
<value>Please note, data supplied to Resgrid for a department is owned by that department and could be subject to data retention policies and laws governing the jurisdiction of the department. Deleting your account here will clear your PII (Personally Identifiable Information) and delete your login but won’t clear all data. You will need to make a request to the department you were apart of for additional if you want all data cleared.</value>
8888
</data>
89+
<data name="DeleteAreYouSure4" xml:space="preserve">
90+
<value>La suppression de votre compte le désactivera dans TOUS les départements dont vous êtes membre, pas seulement dans votre département actuel. Toutes vos automatisations planifiées (envois de rapports, changements de statut planifiés et changements d'effectifs planifiés) seront supprimées, et vous ne recevrez plus de notifications ni de communications d'aucun département.</value>
91+
</data>
8992
<data name="DepartmentOwnerError" xml:space="preserve">
9093
<value>You are unable to delete your account because you are a Department Owner in a department. If you wish to delete the department you will need to access that though the Department Settings page. If you want to retain the department please choose another person as the Department Owner and then try and delete your account again.</value>
9194
</data>

Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.it.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
<data name="DeleteAreYouSure3" xml:space="preserve">
8787
<value>Please note, data supplied to Resgrid for a department is owned by that department and could be subject to data retention policies and laws governing the jurisdiction of the department. Deleting your account here will clear your PII (Personally Identifiable Information) and delete your login but won’t clear all data. You will need to make a request to the department you were apart of for additional if you want all data cleared.</value>
8888
</data>
89+
<data name="DeleteAreYouSure4" xml:space="preserve">
90+
<value>L'eliminazione del tuo account lo disattiverà in TUTTI i dipartimenti di cui sei membro, non solo in quello corrente. Tutte le tue automazioni pianificate (invii di report, cambi di stato pianificati e modifiche pianificate del personale) verranno rimosse e smetterai di ricevere notifiche e comunicazioni da tutti i dipartimenti.</value>
91+
</data>
8992
<data name="DepartmentOwnerError" xml:space="preserve">
9093
<value>You are unable to delete your account because you are a Department Owner in a department. If you wish to delete the department you will need to access that though the Department Settings page. If you want to retain the department please choose another person as the Department Owner and then try and delete your account again.</value>
9194
</data>

Core/Resgrid.Localization/Areas/User/Account/DeleteAccount.pl.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
<data name="DeleteAreYouSure3" xml:space="preserve">
8787
<value>Please note, data supplied to Resgrid for a department is owned by that department and could be subject to data retention policies and laws governing the jurisdiction of the department. Deleting your account here will clear your PII (Personally Identifiable Information) and delete your login but won’t clear all data. You will need to make a request to the department you were apart of for additional if you want all data cleared.</value>
8888
</data>
89+
<data name="DeleteAreYouSure4" xml:space="preserve">
90+
<value>Usunięcie konta spowoduje jego dezaktywację w KAŻDYM dziale, którego jesteś członkiem, nie tylko w bieżącym. Wszystkie zaplanowane automatyzacje (dostarczanie raportów, zaplanowane zmiany statusu i zaplanowane zmiany obsady) zostaną usunięte, a Ty przestaniesz otrzymywać powiadomienia i komunikaty ze wszystkich działów.</value>
91+
</data>
8992
<data name="DepartmentOwnerError" xml:space="preserve">
9093
<value>You are unable to delete your account because you are a Department Owner in a department. If you wish to delete the department you will need to access that though the Department Settings page. If you want to retain the department please choose another person as the Department Owner and then try and delete your account again.</value>
9194
</data>

0 commit comments

Comments
 (0)