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:
+48
-4
@@ -8,12 +8,13 @@ from fastapi.templating import Jinja2Templates
|
||||
from pydantic import ValidationError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.config import settings
|
||||
from app.database import get_db
|
||||
from app.models.habit import HabitDifficulty, HabitStatus, HabitType
|
||||
from app.models.user import User
|
||||
from app.schemas.habit import HabitCreate, HabitUpdate
|
||||
from app.security import get_current_user_optional
|
||||
from app.services import habit_service, log_service
|
||||
from app.services import habit_service, log_service, user_service
|
||||
from app.template_utils import (
|
||||
difficulty_label,
|
||||
goal_progress,
|
||||
@@ -46,14 +47,57 @@ def _current_user_or_redirect(request: Request, db: Session) -> User | RedirectR
|
||||
def index(request: Request, db: Session = Depends(get_db)):
|
||||
if get_current_user_optional(request, db) is not None:
|
||||
return RedirectResponse(url="/today", status_code=303)
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
# 로그인 없이도 앱 목적을 설명하는 페이지가 있어야 한다(구글 OAuth 동의 화면 "홈페이지" 요건).
|
||||
return templates.TemplateResponse(request, "home.html", {"logged_in": False, "current_user": None})
|
||||
|
||||
|
||||
@router.get("/login")
|
||||
def login_page(request: Request, db: Session = Depends(get_db)):
|
||||
def login_page(request: Request, deleted: bool = False, db: Session = Depends(get_db)):
|
||||
if get_current_user_optional(request, db) is not None:
|
||||
return RedirectResponse(url="/today", status_code=303)
|
||||
return templates.TemplateResponse(request, "login.html", {"logged_in": False, "current_user": None})
|
||||
return templates.TemplateResponse(
|
||||
request, "login.html", {"logged_in": False, "current_user": None, "deleted": deleted}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/privacy")
|
||||
def privacy_page(request: Request, db: Session = Depends(get_db)):
|
||||
user = get_current_user_optional(request, db)
|
||||
return templates.TemplateResponse(
|
||||
request, "privacy.html", {"logged_in": user is not None, "current_user": user}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account")
|
||||
def account_page(request: Request, db: Session = Depends(get_db)):
|
||||
current = _current_user_or_redirect(request, db)
|
||||
if isinstance(current, RedirectResponse):
|
||||
return current
|
||||
return templates.TemplateResponse(request, "account.html", {"logged_in": True, "current_user": current})
|
||||
|
||||
|
||||
@router.post("/account/delete")
|
||||
def delete_account_page(request: Request, confirm_email: str = Form(""), db: Session = Depends(get_db)):
|
||||
current = _current_user_or_redirect(request, db)
|
||||
if isinstance(current, RedirectResponse):
|
||||
return current
|
||||
|
||||
if confirm_email.strip().lower() != current.email.lower():
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"account.html",
|
||||
{
|
||||
"logged_in": True,
|
||||
"current_user": current,
|
||||
"delete_error": "입력한 이메일이 계정 이메일과 일치하지 않습니다.",
|
||||
},
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
user_service.delete_account(db, current)
|
||||
response = RedirectResponse(url="/login?deleted=1", status_code=303)
|
||||
response.delete_cookie(settings.session_cookie_name)
|
||||
return response
|
||||
|
||||
|
||||
def _today_context(db: Session, user_id: int, **extra) -> dict:
|
||||
|
||||
+1
-1
@@ -42,5 +42,5 @@ def unsubscribe(
|
||||
|
||||
@router.post("/test")
|
||||
def send_test(db: Session = Depends(get_db), current_user: User = Depends(require_login)):
|
||||
sent = push_service.send_to_user(db, current_user.id, title="습관 트래커", body="테스트 알림입니다.")
|
||||
sent = push_service.send_to_user(db, current_user.id, title="해빗랩", body="테스트 알림입니다.")
|
||||
return {"sent": sent}
|
||||
|
||||
Reference in New Issue
Block a user