Merge pull request 'feat(auth): voice-memo bot 365d access token (PoC v1)' (#19) from feat/voice-memo-bot-token into main

Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
2026-05-13 14:19:41 +09:00
3 changed files with 24 additions and 0 deletions
+6
View File
@@ -16,6 +16,7 @@ from core.auth import (
REFRESH_TOKEN_EXPIRE_DAYS,
create_access_token,
create_refresh_token,
create_voice_memo_bot_token,
decode_token,
get_current_user,
hash_password,
@@ -117,6 +118,11 @@ async def login(
user.last_login_at = datetime.now(timezone.utc)
await session.commit()
# Voice Memo PoC v1 — bot 계정 한정 long-expiry token (env gate). 일반 사용자 흐름 영향 0.
bot_token = create_voice_memo_bot_token(user.username)
if bot_token is not None:
return AccessTokenResponse(access_token=bot_token)
# refresh token → HttpOnly cookie
_set_refresh_cookie(response, create_refresh_token(user.username))
+13
View File
@@ -1,5 +1,6 @@
"""JWT + TOTP 2FA 인증"""
import os
from datetime import datetime, timedelta, timezone
from typing import Annotated
@@ -37,6 +38,18 @@ def create_access_token(subject: str, expires_minutes: int | None = None) -> str
return jwt.encode(payload, settings.jwt_secret, algorithm=ALGORITHM)
def create_voice_memo_bot_token(username: str) -> str | None:
# Voice Memo PoC v1 — bot 계정 한정 long-expiry access token (env gate + username hard-match).
# 일반 사용자 호출 시 None 반환. 정식 service-account/api_keys 는 Phase 2.
if os.getenv("VOICE_MEMO_BOT_TOKEN_ENABLED", "false").lower() != "true":
return None
bot_username = os.getenv("VOICE_MEMO_BOT_USERNAME", "voice-memo-bot")
if username != bot_username:
return None
expire_days = int(os.getenv("VOICE_MEMO_BOT_TOKEN_EXPIRE_DAYS", "365"))
return create_access_token(username, expires_minutes=expire_days * 24 * 60)
def create_refresh_token(subject: str) -> str:
expire = datetime.now(timezone.utc) + timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
payload = {"sub": subject, "exp": expire, "type": "refresh"}
+5
View File
@@ -194,6 +194,11 @@ services:
- STT_ENDPOINT=http://stt-service:3300
# KGS Code 등 외부 학습 자료 추가 스캔 경로 (host .env 에서 주입). 빈 값이면 비활성.
- ADDITIONAL_WATCH_TARGETS=${ADDITIONAL_WATCH_TARGETS:-}
# Voice Memo PoC v1 — bot 계정 한정 long-expiry access token. default false → 일반 운영 영향 0.
# 활성화: host .env 에 VOICE_MEMO_BOT_TOKEN_ENABLED=true. plan: rosy-launching-otter.md
- VOICE_MEMO_BOT_TOKEN_ENABLED=${VOICE_MEMO_BOT_TOKEN_ENABLED:-false}
- VOICE_MEMO_BOT_USERNAME=${VOICE_MEMO_BOT_USERNAME:-voice-memo-bot}
- VOICE_MEMO_BOT_TOKEN_EXPIRE_DAYS=${VOICE_MEMO_BOT_TOKEN_EXPIRE_DAYS:-365}
restart: unless-stopped
frontend: