@@ -475,12 +475,20 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
475475 t .Run ("CORS" , func (t * testing.T ) {
476476 t .Parallel ()
477477
478- t .Run ("AuthenticatedPassthruProtected" , func (t * testing.T ) {
478+ // Set up test headers that should be returned by the app
479+ testHeaders := http.Header {
480+ "Access-Control-Allow-Origin" : []string {"*" },
481+ "Access-Control-Allow-Methods" : []string {"GET, POST, OPTIONS" },
482+ }
483+
484+ t .Run ("UnauthenticatedPassthruRejected" , func (t * testing.T ) {
479485 t .Parallel ()
480486
481487 ctx := testutil .Context (t , testutil .WaitLong )
482488
483- appDetails := setupProxyTest (t , nil )
489+ appDetails := setupProxyTest (t , & DeploymentOptions {
490+ headers : testHeaders ,
491+ })
484492
485493 // Given: an unauthenticated client
486494 client := appDetails .AppClient (t )
@@ -491,7 +499,7 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
491499 require .NoError (t , err )
492500 defer resp .Body .Close ()
493501
494- // Then: the request is redirected to the primary access URL because even though CORS is passthru,
502+ // Then: the request is redirected to login because even though CORS is passthru,
495503 // the request must still be authenticated first
496504 require .Equal (t , http .StatusSeeOther , resp .StatusCode )
497505 gotLocation , err := resp .Location ()
@@ -505,7 +513,9 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
505513
506514 ctx := testutil .Context (t , testutil .WaitLong )
507515
508- appDetails := setupProxyTest (t , nil )
516+ appDetails := setupProxyTest (t , & DeploymentOptions {
517+ headers : testHeaders ,
518+ })
509519
510520 userClient , _ := coderdtest .CreateAnotherUser (t , appDetails .SDKClient , appDetails .FirstUser .OrganizationID , rbac .RoleMember ())
511521 userAppClient := appDetails .AppClient (t )
@@ -516,6 +526,65 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
516526 require .NoError (t , err )
517527 defer resp .Body .Close ()
518528 require .Equal (t , http .StatusOK , resp .StatusCode )
529+
530+ // Check CORS headers are passed through
531+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Origin" ), resp .Header .Get ("Access-Control-Allow-Origin" ))
532+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Credentials" ), resp .Header .Get ("Access-Control-Allow-Credentials" ))
533+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Methods" ), resp .Header .Get ("Access-Control-Allow-Methods" ))
534+ })
535+
536+ t .Run ("UnauthenticatedPublicPassthruOK" , func (t * testing.T ) {
537+ t .Parallel ()
538+
539+ ctx := testutil .Context (t , testutil .WaitLong )
540+
541+ appDetails := setupProxyTest (t , & DeploymentOptions {
542+ headers : testHeaders ,
543+ })
544+
545+ // Given: an unauthenticated client
546+ client := appDetails .AppClient (t )
547+ client .SetSessionToken ("" )
548+
549+ // When: a request is made to a public app with passthru CORS behavior
550+ resp , err := requestWithRetries (ctx , t , client , http .MethodGet , appDetails .SubdomainAppURL (appDetails .Apps .PublicCORSPassthru ).String (), nil )
551+ require .NoError (t , err )
552+ defer resp .Body .Close ()
553+
554+ // Then: the request succeeds because the app is public
555+ require .Equal (t , http .StatusOK , resp .StatusCode )
556+
557+ // Check CORS headers are passed through
558+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Origin" ), resp .Header .Get ("Access-Control-Allow-Origin" ))
559+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Credentials" ), resp .Header .Get ("Access-Control-Allow-Credentials" ))
560+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Methods" ), resp .Header .Get ("Access-Control-Allow-Methods" ))
561+ })
562+
563+ t .Run ("AuthenticatedPublicPassthruOK" , func (t * testing.T ) {
564+ t .Parallel ()
565+
566+ ctx := testutil .Context (t , testutil .WaitLong )
567+
568+ appDetails := setupProxyTest (t , & DeploymentOptions {
569+ headers : testHeaders ,
570+ })
571+
572+ userClient , _ := coderdtest .CreateAnotherUser (t , appDetails .SDKClient , appDetails .FirstUser .OrganizationID , rbac .RoleMember ())
573+ userAppClient := appDetails .AppClient (t )
574+ userAppClient .SetSessionToken (userClient .SessionToken ())
575+
576+ // Given: an authenticated client accessing a public app with passthru CORS behavior
577+ resp , err := requestWithRetries (ctx , t , userAppClient , http .MethodGet , appDetails .SubdomainAppURL (appDetails .Apps .PublicCORSPassthru ).String (), nil )
578+ require .NoError (t , err )
579+ defer resp .Body .Close ()
580+
581+ // Then: the request succeeds because the app is public
582+ require .Equal (t , http .StatusOK , resp .StatusCode )
583+
584+ // Check CORS headers are passed through
585+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Origin" ), resp .Header .Get ("Access-Control-Allow-Origin" ))
586+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Credentials" ), resp .Header .Get ("Access-Control-Allow-Credentials" ))
587+ require .Equal (t , testHeaders .Get ("Access-Control-Allow-Methods" ), resp .Header .Get ("Access-Control-Allow-Methods" ))
519588 })
520589 })
521590
@@ -1842,7 +1911,7 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
18421911 })
18431912
18441913 // See above test for original implementation.
1845- t .Run ("CORSHeadersConditionalStrip " , func (t * testing.T ) {
1914+ t .Run ("CORSHeadersConditionallyStripped " , func (t * testing.T ) {
18461915 t .Parallel ()
18471916
18481917 // Set a bunch of headers which may or may not be stripped, depending on the CORS behavior.
@@ -1854,15 +1923,6 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
18541923 "Access-Control-Allow-Credentials" : []string {"true" },
18551924 "Access-Control-Allow-Methods" : []string {"PUT" },
18561925 "Access-Control-Allow-Headers" : []string {"X-Foobar" },
1857- "Vary" : []string {
1858- "Origin" ,
1859- "origin" ,
1860- "Access-Control-Request-Headers" ,
1861- "access-Control-request-Headers" ,
1862- "Access-Control-Request-Methods" ,
1863- "ACCESS-CONTROL-REQUEST-METHODS" ,
1864- "X-Foobar" ,
1865- },
18661926 }
18671927
18681928 appDetails := setupProxyTest (t , & DeploymentOptions {
0 commit comments