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:
49
app/main.py
49
app/main.py
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user