@@ -65,6 +65,8 @@ public class CrudApiConfiguration
6565{
6666 public string ApiFile { get ; set ; } = "api.json" ;
6767 public string BaseUrl { get ; set ; } = string . Empty ;
68+ [ JsonPropertyName ( "enableCors" ) ]
69+ public bool EnableCORS { get ; set ; } = true ;
6870 public string DataFile { get ; set ; } = string . Empty ;
6971 public IEnumerable < CrudApiAction > Actions { get ; set ; } = [ ] ;
7072 [ System . Text . Json . Serialization . JsonConverter ( typeof ( JsonStringEnumConverter ) ) ]
@@ -165,6 +167,13 @@ protected virtual Task OnRequestAsync(object? sender, ProxyRequestArgs e)
165167 return Task . CompletedTask ;
166168 }
167169
170+ if ( IsCORSPreflightRequest ( request ) && _configuration . EnableCORS )
171+ {
172+ SendEmptyResponse ( HttpStatusCode . NoContent , e . Session ) ;
173+ Logger . LogRequest ( "CORS preflight request" , MessageType . Mocked , new LoggingContext ( e . Session ) ) ;
174+ return Task . CompletedTask ;
175+ }
176+
168177 if ( ! AuthorizeRequest ( e ) )
169178 {
170179 SendUnauthorizedResponse ( e . Session ) ;
@@ -193,6 +202,35 @@ protected virtual Task OnRequestAsync(object? sender, ProxyRequestArgs e)
193202 return Task . CompletedTask ;
194203 }
195204
205+ private static bool IsCORSPreflightRequest ( Request request )
206+ {
207+ return request . Method == "OPTIONS" &&
208+ request . Headers . Any ( h => h . Name . Equals ( "Origin" , StringComparison . OrdinalIgnoreCase ) ) ;
209+ }
210+
211+ private void AddCORSHeaders ( Request request , List < HttpHeader > headers )
212+ {
213+ var origin = request . Headers . FirstOrDefault ( h => h . Name . Equals ( "Origin" , StringComparison . OrdinalIgnoreCase ) ) ? . Value ;
214+ if ( string . IsNullOrEmpty ( origin ) )
215+ {
216+ return ;
217+ }
218+
219+ headers . Add ( new HttpHeader ( "access-control-allow-origin" , origin ) ) ;
220+
221+ if ( _configuration . EntraAuthConfig is not null )
222+ {
223+ headers . Add ( new HttpHeader ( "access-control-allow-headers" , "authorization" ) ) ;
224+ }
225+
226+ var methods = string . Join ( ", " , _configuration . Actions
227+ . Where ( a => a . Method is not null )
228+ . Select ( a => a . Method )
229+ . Distinct ( ) ) ;
230+
231+ headers . Add ( new HttpHeader ( "access-control-allow-methods" , methods ) ) ;
232+ }
233+
196234 private bool AuthorizeRequest ( ProxyRequestArgs e , CrudApiAction ? action = null )
197235 {
198236 var authType = action is null ? _configuration . Auth : action . Auth ;
@@ -304,12 +342,12 @@ private static bool HasPermission(string permission, string permissionString)
304342 return permissions . Contains ( permission , StringComparer . OrdinalIgnoreCase ) ;
305343 }
306344
307- private static void SendUnauthorizedResponse ( SessionEventArgs e )
345+ private void SendUnauthorizedResponse ( SessionEventArgs e )
308346 {
309347 SendJsonResponse ( "{\" error\" :{\" message\" :\" Unauthorized\" }}" , HttpStatusCode . Unauthorized , e ) ;
310348 }
311349
312- private static void SendNotFoundResponse ( SessionEventArgs e )
350+ private void SendNotFoundResponse ( SessionEventArgs e )
313351 {
314352 SendJsonResponse ( "{\" error\" :{\" message\" :\" Not found\" }}" , HttpStatusCode . NotFound , e ) ;
315353 }
@@ -327,25 +365,19 @@ private static string ReplaceParams(string query, IDictionary<string, string> pa
327365 return result ;
328366 }
329367
330- private static void SendEmptyResponse ( HttpStatusCode statusCode , SessionEventArgs e )
368+ private void SendEmptyResponse ( HttpStatusCode statusCode , SessionEventArgs e )
331369 {
332370 var headers = new List < HttpHeader > ( ) ;
333- if ( e . HttpClient . Request . Headers . Any ( h => h . Name == "Origin" ) )
334- {
335- headers . Add ( new HttpHeader ( "access-control-allow-origin" , "*" ) ) ;
336- }
371+ AddCORSHeaders ( e . HttpClient . Request , headers ) ;
337372 e . GenericResponse ( "" , statusCode , headers ) ;
338373 }
339374
340- private static void SendJsonResponse ( string body , HttpStatusCode statusCode , SessionEventArgs e )
375+ private void SendJsonResponse ( string body , HttpStatusCode statusCode , SessionEventArgs e )
341376 {
342377 var headers = new List < HttpHeader > {
343378 new ( "content-type" , "application/json; charset=utf-8" )
344379 } ;
345- if ( e . HttpClient . Request . Headers . Any ( h => h . Name == "Origin" ) )
346- {
347- headers . Add ( new HttpHeader ( "access-control-allow-origin" , "*" ) ) ;
348- }
380+ AddCORSHeaders ( e . HttpClient . Request , headers ) ;
349381 e . GenericResponse ( body , statusCode , headers ) ;
350382 }
351383
0 commit comments