prepare app for public app store distribution
- rebrand from 습관 트래커 to 해빗랩 across templates, manifest, service worker - add HTTPS redirect middleware for reverse-proxied deployments - add public landing page (/) and privacy policy page with real data handling disclosures - add in-app account deletion (Apple review requirement) - add Android TWA Digital Asset Links support (/.well-known/assetlinks.json) - add SFTP deployment script for the Synology-hosted server Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+18
-2
@@ -2,7 +2,7 @@ import logging
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
from starlette.middleware.sessions import SessionMiddleware
|
||||
@@ -24,12 +24,22 @@ async def lifespan(app: FastAPI):
|
||||
scheduler_service.shutdown_scheduler()
|
||||
|
||||
|
||||
app = FastAPI(title="습관 트래커", lifespan=lifespan)
|
||||
app = FastAPI(title="해빗랩", lifespan=lifespan)
|
||||
|
||||
# 구글 OAuth 핸드셰이크 중 state/nonce를 임시로 저장하는 데만 쓰는 세션이다.
|
||||
# 로그인 유지용 쿠키(habit_session)와는 별개.
|
||||
app.add_middleware(SessionMiddleware, secret_key=settings.secret_key, session_cookie="oauth_session", max_age=600)
|
||||
|
||||
|
||||
@app.middleware("http")
|
||||
async def redirect_http_to_https(request: Request, call_next):
|
||||
# 리버스 프록시가 X-Forwarded-Proto로 원래 스킴을 알려줄 때만 동작한다
|
||||
# (로컬 uvicorn 직접 실행 시에는 이 헤더가 없어 그냥 통과).
|
||||
if request.headers.get("x-forwarded-proto") == "http":
|
||||
return RedirectResponse(str(request.url.replace(scheme="https")), status_code=301)
|
||||
return await call_next(request)
|
||||
|
||||
|
||||
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
||||
|
||||
app.include_router(auth.router)
|
||||
@@ -75,3 +85,9 @@ async def unhandled_exception_handler(request: Request, exc: Exception):
|
||||
def service_worker():
|
||||
# 서비스워커 scope가 앱 전체를 커버하려면 /static/ 하위가 아닌 루트 경로로 서빙해야 한다.
|
||||
return FileResponse("app/static/service-worker.js", media_type="application/javascript")
|
||||
|
||||
|
||||
@app.get("/.well-known/assetlinks.json")
|
||||
def assetlinks():
|
||||
# Android TWA(kr.co.alphalok.habit.twa)의 도메인 소유권 증명용 — 반드시 /.well-known/ 루트 경로여야 한다.
|
||||
return FileResponse("app/static/.well-known/assetlinks.json", media_type="application/json")
|
||||
|
||||
Reference in New Issue
Block a user