The Site:Audience setting was conflating two distinct concepts: an OAuth
JWT audience (a single resource identifier) and a CORS allow-list (an
array of origins). Collapsing them caused several latent bugs:
- OAuth/JWT validation expected a single string while CORS WithOrigins
accepts an array.
- Password-reset callback URLs and OAuth client RedirectUri/Origin were
being built from what was meant to be an audience identifier, not a
base URL.
- Yavsc.Org's main CORS policy was hardcoded to '*', with no way to
restrict it without code changes.
Changes:
- SiteSettings.Audience (string) replaced with CorsAllowedOrigins
(IList<string>).
- OAuth JWT Authority still reads Site:Authority; Audience now reads
Site:ExternalUrl (Org only; Api/Blogs use ValidateAudience=false).
- MailSender and AccountController build reset-callback URLs from
Site:ExternalUrl.
- ClientController uses Site:ExternalUrl for OAuth RedirectUri/Origin
defaults on newly created clients.
- Yavsc.Api and Yavsc.Blogs now read CORS origins from
Site:CorsAllowedOrigins instead of hardcoded URLs.
Add shared AddYavscCors / AddYavscJwtBearer extension methods in
Yavsc.Server/Helpers/ServiceExtensions.cs to enforce a single
configuration contract across all runtime services (Api, Blogs, Org).
Fails closed when CorsAllowedOrigins is empty; fails fast at startup
when Site:Authority is missing.
Remove obsolete ConfigurationHelpers.GetAudience (no remaining callers).
Local appsettings-*.json files (which carry deployment-specific values
and are gitignored) must be updated to add Site:CorsAllowedOrigins.
The previous code computed the path as
Path.Combine(BaseDir, "../../src/Yavsc.Org")
which from `bin/Debug/net10.0/` resolved to a non-existent
`test/yavscTests/src/Yavsc.Org` (two levels up, not four).
Kestrel logged:
"The WebRootPath was not found: ... /wwwroot. Static files
may be unavailable."
The fix walks up the directory tree from BaseDir until it
finds a directory that contains `src/Yavsc.Org`. This is
robust against the test runner changing the current working
directory (which it does: it runs from
`test/yavscTests/bin/Debug/net10.0`, not the repo root).
After this fix, UseStaticFiles correctly resolves the
wwwroot, so static assets under `wwwroot/` are served.
Note: this does NOT make the in-memory WebServerFixture
fully functional. Two pre-existing issues remain:
1. _Layout.cshtml references `~/css/site.css` but the
actual file is now at `~/css/main/site.css` (moved by
commit 31906a78). The .cshtml was not updated.
2. HomeController.Index() throws NullReferenceException
on an empty EF Core InMemory database (no Activities
seeded). UseDeveloperExceptionPage returns a 500 page
that gets caught and re-rendered as 404 by the test
client.
Both will be addressed in follow-up commits.
Tested: dotnet test 11/11 green (existing tests use
Services DI, not HTTP). UI tests not added yet (blocked by
the issues above).
- Make WebServerFixture properties nullable to match async initialization
- Add null-coalescing assertions where properties are guaranteed non-null
- Fix GetDiscoveryDocumentAsync delegate signature in Remoting to allow nullable parameters
- Build now succeeds with 0 errors, 7/9 tests passing
- Add in-memory database support for test isolation in WebServerFixture
- Implement TestMailSender fake SMTP provider for email test support
- Add thread synchronization to billing service registration to prevent race conditions
- Make RegisterBilling<T> idempotent to safely handle reconfiguration
- Configure test environment via in-memory settings (UseTestEmailSender, UseInMemoryDatabase)
- Add regression tests for billing module idempotency and duplicate registration detection
- Fix tests: EMaillingTests.SendEMailSynchrone, BillingServiceTests (2 tests), HaveConfigurationRoot (3 tests)
All core test infrastructure tests now passing.