Work on CORS again. Chromium now enforces the new "Local Network Access" permission and prompting. This was a problem because pfSense was set to resolve dev-api.oneskyit.com back to 192.168.32.7 instead of the normal external IP. Turned this off. Hopefully it won't break other things.

This commit is contained in:
Scott Idem
2026-02-23 17:57:13 -05:00
parent f518d7a433
commit 719ca5240b

View File

@@ -43,10 +43,10 @@ async def lifespan(app: FastAPI):
# 1. Initialize Logging early but safely # 1. Initialize Logging early but safely
setup_logging(config.settings) setup_logging(config.settings)
log.info('### **** *** ** * Aether API v4 using FastAPI - Startup Lifespan Initiated * ** *** **** ###') log.info('### **** *** ** * Aether API v4 using FastAPI - Startup Lifespan Initiated * ** *** **** ###')
# 2. Bootstrapping Configuration from DB with robust error handling # 2. Bootstrapping Configuration from DB with robust error handling
log.info("Bootstrapping Configuration...") log.info("Bootstrapping Configuration...")
# Save original settings for fallback # Save original settings for fallback
orig_db_server = config.settings.DB_SERVER orig_db_server = config.settings.DB_SERVER
orig_db_user = config.settings.DB_USER orig_db_user = config.settings.DB_USER
@@ -81,11 +81,11 @@ async def lifespan(app: FastAPI):
# 3. Final validation of critical infrastructure # 3. Final validation of critical infrastructure
validate_critical_config(config.settings) validate_critical_config(config.settings)
log.info('### **** *** ** * Aether API v4 using FastAPI - Startup Sequence Complete * ** *** **** ###') log.info('### **** *** ** * Aether API v4 using FastAPI - Startup Sequence Complete * ** *** **** ###')
yield yield
# Shutdown logic # Shutdown logic
log.info('### **** *** ** * Aether API v4 using FastAPI - Shutdown Lifespan Initiated * ** *** **** ###') log.info('### **** *** ** * Aether API v4 using FastAPI - Shutdown Lifespan Initiated * ** *** **** ###')
log.info('The Aether FastAPI API is shutting down...') log.info('The Aether FastAPI API is shutting down...')
@@ -114,6 +114,7 @@ app.mount('/static', StaticFiles(directory='static'), name='static')
setup_routers(app) setup_routers(app)
# Updated 2026-02-23
# BEGIN: CORS # BEGIN: CORS
# NOTE: Eventually this should query the DB for the specific list based on the cfg table and or site_domain table. That way it is dynamic and only allowing those defined in the DB. No wildcards or regex. # NOTE: Eventually this should query the DB for the specific list based on the cfg table and or site_domain table. That way it is dynamic and only allowing those defined in the DB. No wildcards or regex.
# NOTE: Need to include .localhost for less browser restrictions! Mainly for audio and video. # NOTE: Need to include .localhost for less browser restrictions! Mainly for audio and video.
@@ -132,6 +133,44 @@ app.add_middleware(
# END: CORS # END: CORS
# Updated 2026-02-23
# Add middleware to ensure Access-Control-Allow-Private-Network is present
# when the response already includes CORS allow-origin (i.e. origin was allowed).
@app.middleware("http")
async def cors_pna_middleware(request: Request, call_next):
"""Add `Access-Control-Allow-Private-Network: true` to responses
only when CORS has already allowed the request's origin. This avoids
echoing PNA for disallowed origins and leverages the existing
CORSMiddleware origin validation.
"""
response = await call_next(request)
# Rely on existing CORS logic (CORSMiddleware) to validate origin.
# Only add the PNA header if an Allow-Origin header is present.
if response.headers.get('access-control-allow-origin') or response.headers.get('Access-Control-Allow-Origin'):
response.headers['Access-Control-Allow-Private-Network'] = 'true'
return response
# Updated 2026-02-23
# Temporary debug middleware: logs Origin and PNA-related request/response headers
# Activate only when an Origin header is present to limit log noise.
# @app.middleware("http")
# async def debug_pna_logging_middleware(request: Request, call_next):
# origin = request.headers.get('origin')
# if origin:
# acrpn = request.headers.get('access-control-request-private-network')
# acrm = request.headers.get('access-control-request-method')
# log.debug(f"PNA_DEBUG REQ: method={request.method} path={request.url.path} remote={getattr(request.client, 'host', None)} origin={origin} acr_method={acrm} acr_private_network={acrpn}")
# response = await call_next(request)
# if origin:
# # collect CORS/PNA-related response headers for visibility
# interesting = {k: v for k, v in response.headers.items() if k.lower().startswith('access-control-') or k.lower() == 'vary'}
# log.debug(f"PNA_DEBUG RESP: status={response.status_code} headers={interesting}")
# return response
# Register utility middleware from external module # Register utility middleware from external module
app.middleware('http')(process_time_middleware) app.middleware('http')(process_time_middleware)