1
0
forked from baron/baron-sso

userfront로 리펙토링 완료

This commit is contained in:
Lectom C Han
2026-01-28 08:28:25 +09:00
parent 6d88c81217
commit 1aaa772907
154 changed files with 339 additions and 314 deletions

View File

@@ -11,7 +11,7 @@ DB_PORT=5432
CLICKHOUSE_PORT_HTTP=8123
CLICKHOUSE_PORT_NATIVE=9000
BACKEND_PORT=3000
FRONTEND_PORT=5000
USERFRONT_PORT=5000
# --- Database Credentials (PostgreSQL) ---
DB_USER=baron
@@ -47,7 +47,7 @@ ADMIN_EMAIL=admin@baron.co.kr
ADMIN_PASSWORD=adminPasswordIsNotSimple
# --- URLs for Proxy/Handoff ---
FRONTEND_URL=https://sso.hmac.kr # 프론트엔드 접속 주소 (이메일/SMS 링크 생성 시 사용)
USERFRONT_URL=https://sso.hmac.kr # 프론트엔드 접속 주소 (이메일/SMS 링크 생성 시 사용)
BACKEND_URL=https://sso.hmac.kr # 프론트엔드에서 참조할 백엔드 API 주소
# IDP_PROVIDER는 우선순위 순으로 콤마 구분 (예: Kratos/Hydra 우선, Descope 백업)

View File

@@ -86,17 +86,17 @@ jobs:
provenance: false
sbom: false
- name: Temporarily update frontend nginx port
- name: Temporarily update userfront nginx port
run: |
sed -i 's/listen 5000;/listen 80;/g' frontend/nginx.conf
sed -i 's/proxy_pass http:\/\/baron_backend:3000;/proxy_pass http:\/\/baron_backend:3010;/g' frontend/nginx.conf
sed -i 's/listen 5000;/listen 80;/g' userfront/nginx.conf
sed -i 's/proxy_pass http:\/\/baron_backend:3000;/proxy_pass http:\/\/baron_backend:3010;/g' userfront/nginx.conf
- name: Build and push frontend RC image
- name: Build and push userfront RC image
uses: docker/build-push-action@v5
with:
context: ./frontend
file: ./frontend/Dockerfile
context: ./userfront
file: ./userfront/Dockerfile
push: true
tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/frontend:${{ steps.rc_calculator.outputs.new_rc_tag }}
tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/userfront:${{ steps.rc_calculator.outputs.new_rc_tag }}
provenance: false
sbom: false

View File

@@ -13,8 +13,8 @@ on:
required: true
type: boolean
default: true
run_frontend_tests:
description: "Run frontend Flutter tests"
run_userfront_tests:
description: "Run userfront Flutter tests"
required: true
type: boolean
default: true
@@ -46,9 +46,9 @@ jobs:
working-directory: backend
args: --enable-only=gofmt,gofumpt
- name: Analyze Flutter frontend
- name: Analyze Flutter userfront
run: |
cd frontend
cd userfront
flutter analyze --no-fatal-warnings --no-fatal-infos
backend-tests:
@@ -85,9 +85,9 @@ jobs:
cd backend
go test -v ./...
frontend-tests:
userfront-tests:
needs: lint
if: ${{ inputs.run_frontend_tests == true }}
if: ${{ inputs.run_userfront_tests == true }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
@@ -99,11 +99,11 @@ jobs:
channel: "stable"
cache: true
- name: Run frontend tests
- name: Run userfront tests
run: |
cd frontend
cd userfront
if [ -d test ]; then
flutter test
else
echo "No frontend tests: skipping (test/ directory not found)."
echo "No userfront tests: skipping (test/ directory not found)."
fi

View File

@@ -49,12 +49,12 @@ jobs:
--src-tls-verify=false --dest-tls-verify=false \
"docker://${HARBOR_HOSTNAME}/baron_sso/backend:${BASE_TAG}" "docker://${HARBOR_HOSTNAME}/baron_sso/backend:${RE_TAG}"
# Re-tag frontend image
echo "Re-tagging frontend image..."
# Re-tag userfront image
echo "Re-tagging userfront image..."
skopeo copy --preserve-digests \
--src-creds "${HARBOR_USER}:${HARBOR_PASSWORD}" --dest-creds "${HARBOR_USER}:${HARBOR_PASSWORD}" \
--src-tls-verify=false --dest-tls-verify=false \
"docker://${HARBOR_HOSTNAME}/baron_sso/frontend:${BASE_TAG}" "docker://${HARBOR_HOSTNAME}/baron_sso/frontend:${RE_TAG}"
"docker://${HARBOR_HOSTNAME}/baron_sso/userfront:${BASE_TAG}" "docker://${HARBOR_HOSTNAME}/baron_sso/userfront:${RE_TAG}"
echo "final_image_tag=${RE_TAG}" >> "$GITHUB_OUTPUT"
@@ -67,7 +67,7 @@ jobs:
env:
IMAGE_TAG: ${{ steps.retag.outputs.final_image_tag }}
BACKEND_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/backend
FRONTEND_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/frontend
USERFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/userfront
DEPLOY_PATH: ${{ vars.PROD_DEPLOY_PATH }}
PROD_HOST: ${{ vars.PROD_HOST }}
PROD_USER: ${{ vars.PROD_USER }}
@@ -102,7 +102,7 @@ jobs:
"CLICKHOUSE_USER=${{ vars.PROD_CLICKHOUSE_USER }}" \
"CLICKHOUSE_PASSWORD=${{ secrets.PROD_CLICKHOUSE_PASSWORD }}" \
"BACKEND_PORT=${{ vars.PROD_BACKEND_PORT }}" \
"FRONTEND_PORT=${{ vars.PROD_FRONTEND_PORT }}" \
"USERFRONT_PORT=${{ vars.PROD_USERFRONT_PORT }}" \
"DB_USER=${{ vars.PROD_DB_USER }}" \
"DB_PASSWORD=${{ secrets.PROD_DB_PASSWORD }}" \
"DB_NAME=${{ vars.PROD_DB_NAME }}" \
@@ -119,7 +119,7 @@ jobs:
"AWS_ACCESS_KEY_ID=${{ vars.AWS_ACCESS_KEY_ID }}" \
"AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" \
"AWS_SES_SENDER=${{ vars.AWS_SES_SENDER }}" \
"FRONTEND_URL=${{ vars.PROD_FRONTEND_URL }}" \
"USERFRONT_URL=${{ vars.PROD_USERFRONT_URL }}" \
"BACKEND_URL=${{ vars.PROD_BACKEND_URL }}" \
> .env
@@ -131,7 +131,7 @@ jobs:
echo "${HARBOR_ROBOT_KEY}" | ssh "${PROD_USER}@${PROD_HOST}" \
"export DEPLOY_PATH='${DEPLOY_PATH}'; \
export BACKEND_IMAGE_NAME='${BACKEND_IMAGE_NAME}'; \
export FRONTEND_IMAGE_NAME='${FRONTEND_IMAGE_NAME}'; \
export USERFRONT_IMAGE_NAME='${USERFRONT_IMAGE_NAME}'; \
export IMAGE_TAG='${IMAGE_TAG}'; \
export HARBOR_ENDPOINT='${HARBOR_ENDPOINT}'; \
export HARBOR_ROBOT_ACCOUNT='${HARBOR_ROBOT_ACCOUNT}'; \

14
.gitignore vendored
View File

@@ -17,10 +17,10 @@ backend/vendor/
backend/tmp/
backend/.env
# Frontend (Flutter)
# Note: Frontend might have its own .gitignore, but adding here just in case
frontend/build/
frontend/.dart_tool/
frontend/.packages
frontend/.pub/
frontend/.env
# userfront (Flutter)
# Note: userfront might have its own .gitignore, but adding here just in case
userfront/build/
userfront/.dart_tool/
userfront/.packages
userfront/.pub/
userfront/.env

View File

@@ -21,22 +21,22 @@
- **Features**:
- 인증용 SMS 발송 등 Ory-Stack으로 구현 어려운 부분 직접 구현
- `POST /api/v1/audit`: 감사 로그 수집 API
- User-Front가 바라보는 backend
- userfront가 바라보는 backend
### 2. User-Front(Flutter Web/App)
### 2. userfront(Flutter Web/App)
- **Framework**: Flutter 3.32+
- **Key Packages**: `flutter_riverpod`, `go_router`
- **Features**:
- 탭 기반 로그인 UI (비밀번호 기반 / 링크 기반 / QR 기반 등)
### 3. Admin-Front(Web)
### 3. adminfront(Web)
- **Framework**: Vite, React 19+, Shadcn/ui 등
- **Features**:
- 사용자 관리, 권한 부여 등 관리자 기능
- 앱 별 사용량(호출량) 등 통계
- 핵심 Audit 대상
### 4. Dev-Front(Web) - 향후 분리 예정
### 4. devfront(Web) - 향후 분리 예정
- **Framework**: Vite, React 19+, Shadcn/ui 등
- **Features**:
- RP 등록 및 관리
@@ -55,9 +55,9 @@
```mermaid
flowchart LR
AF[Admin Front] -->|"OIDC authorize/token (PKCE)"| HY["Hydra (OIDC 엔진)"]
DF[Dev Front] -->|"OIDC authorize/token (PKCE)"| HY
UF["User Front (Login/Consent UI)"] <-->|Hydra login/consent redirect| HY
AF[adminfront] -->|"OIDC authorize/token (PKCE)"| HY["Hydra (OIDC 엔진)"]
DF[devfront] -->|"OIDC authorize/token (PKCE)"| HY
UF["userfront (Login/Consent UI)"] <-->|Hydra login/consent redirect| HY
UF -->|Kratos Browser Flow| KR["Kratos (SoT: identities/traits)"]
KR -->|subject=identity.id| HY
HY -->|ID/Access Token| RP[Relying Party Apps]
@@ -111,14 +111,14 @@ docker compose -f compose.infra.yaml -f compose.ory.yaml up -d
```
#### 3. 애플리케이션 실행
FrontendBackend 서비스를 실행합니다.
userfront와 backend 서비스를 실행합니다.
```bash
docker compose -f docker-compose.yaml up -d
```
(또는 한번에 실행: `docker compose -f compose.infra.yaml -f compose.ory.yaml -f docker-compose.yaml up -d`)
- **Frontend**: http://localhost:5000 접속
- **Backend**: http://localhost:3000 (API)
- **userfront**: http://localhost:5000 접속
- **backend**: http://localhost:3000 (API)
- **ClickHouse**: http://localhost:8123
- **Kratos Public**: http://localhost:4433
- **Hydra Public**: http://localhost:4444
@@ -134,9 +134,9 @@ go mod tidy
go run cmd/server/main.go
```
**Frontend:**
**userfront:**
```bash
cd frontend
cd userfront
flutter pub get
flutter run -d chrome
```
@@ -151,10 +151,10 @@ baron_sso/
│ ├── cmd/server/ # 진입점 (Entry point)
│ ├── internal/ # 도메인, 핸들러, 저장소(Repository)
│ └── Dockerfile
├── user-front/ # Flutter 애플리케이션
├── userfront/ # Flutter 애플리케이션
│ ├── src/ # UI 및 로직
│ └── pubspec.yaml
├── admin-front/ # React 기반 관리
├── adminfront/ # React 기반 관리
│ ├── src/ # UI 및 로직
│ └── pubspec.yaml
├── compose.ory-stack.yaml # DB 서비스 (Postgres, ClickHouse)
@@ -167,6 +167,6 @@ baron_sso/
## 📝 상태 및 로드맵 (Status & Roadmap)
- [x] **Phase 1**: 초기 설정 및 아키텍처 설계 (완료)
- [x] **Phase 2**: Backend Audit API 구현 (일부 완료)
- [x] **Phase 3**: User Front 로그인 UI 인증 로직 (완료)
- [ ] **Phase 4**: Admin Front 기능 추가 (예정)
- [x] **Phase 3**: userfront 로그인 UI 인증 로직 (완료)
- [ ] **Phase 4**: adminfront 기능 추가 (예정)
- [ ] **Phase 5**: 대시보드 및 통합 런처 구현 (예정)

View File

@@ -24,7 +24,7 @@ It leverages **Descope** for secure, passwordless authentication (Enchanted Link
### 3. Infrastructure (Docker)
- **Services**: `postgres`, `clickhouse` (defined in `compose.infra.yaml`)
- **App**: `frontend`, `backend` (defined in `docker-compose.yaml`)
- **App**: `userfront`, `backend` (defined in `docker-compose.yaml`)
---
@@ -60,13 +60,13 @@ docker compose -f compose.infra.yaml up -d
```
#### 2. Start Applications
Start the Frontend and Backend services.
Start the userfront and backend services.
```bash
docker compose up
```
- **Frontend**: Accessible at http://localhost:5000
- **Backend**: API active at http://localhost:3000
- **userfront**: Accessible at http://localhost:5000
- **backend**: API active at http://localhost:3000
- **ClickHouse**: http://localhost:8123
### Local Development (Manual)
@@ -79,9 +79,9 @@ go mod tidy
go run cmd/server/main.go
```
**Frontend:**
**userfront:**
```bash
cd frontend
cd userfront
flutter pub get
flutter run -d chrome
```
@@ -96,7 +96,7 @@ baron_sso/
│ ├── cmd/server/ # Entry point
│ ├── internal/ # Domain, Handlers, Repository
│ └── Dockerfile
├── frontend/ # Flutter Application
├── userfront/ # Flutter Application
│ ├── lib/ # UI & Logic
│ └── pubspec.yaml
├── compose.infra.yaml # DB Services (Postgres, ClickHouse)

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>admin-front</title>
<title>adminfront</title>
</head>
<body>
<div id="root"></div>

View File

@@ -1,11 +1,11 @@
{
"name": "admin-front",
"name": "adminfront",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "admin-front",
"name": "adminfront",
"version": "0.0.0",
"dependencies": {
"@radix-ui/react-avatar": "^1.1.4",

View File

@@ -1,5 +1,5 @@
{
"name": "admin-front",
"name": "adminfront",
"private": true,
"version": "0.0.0",
"type": "module",

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -54,7 +54,7 @@ function DashboardPage() {
<div className="space-y-3 max-w-2xl">
<div className="inline-flex items-center gap-2 rounded-full border border-[var(--color-border)] px-3 py-1 text-xs uppercase tracking-[0.2em] text-[var(--color-muted)]">
<Sparkles size={14} />
admin-front ready
adminfront ready
</div>
<h2 className="text-3xl font-semibold leading-tight">
Build the admin plane with{" "}

View File

@@ -74,8 +74,8 @@ func main() {
"app_env", getEnv("APP_ENV", "dev"),
"db_port", getEnv("DB_PORT", "5532"),
"backend_port", getEnv("BACKEND_PORT", "3000"),
"frontend_port", getEnv("FRONTEND_PORT", "5000"),
"frontend_url", getEnv("FRONTEND_URL", "http://sso.hmac.kr"),
"userfront_port", getEnv("USERFRONT_PORT", "5000"),
"userfront_url", getEnv("USERFRONT_URL", "http://sso.hmac.kr"),
"redis_addr", getEnv("REDIS_ADDR", "redis:6379"),
)

View File

@@ -418,7 +418,7 @@ func (h *AuthHandler) saveSignupState(key string, state *signupState, ttl time.D
return h.RedisService.Set(key, string(data), ttl)
}
// GetPasswordPolicy exposes the current Descope password policy to the frontend for dynamic validation.
// GetPasswordPolicy exposes the current Descope password policy to the userfront for dynamic validation.
func (h *AuthHandler) GetPasswordPolicy(c *fiber.Ctx) error {
if h.DescopeClient == nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Descope client not configured"})
@@ -531,12 +531,12 @@ func (h *AuthHandler) InitEnchantedLink(c *fiber.Ctx) error {
h.RedisService.Set(prefixToken+token, fmt.Sprintf(`{"pendingRef":"%s","loginId":"%s"}`, pendingRef, loginID), defaultExpiration)
// Generate Link
frontendURL := os.Getenv("FRONTEND_URL")
slog.Info("[Enchanted] Read FRONTEND_URL", "url", frontendURL)
if frontendURL == "" {
frontendURL = "http://sso.hmac.kr"
userfrontURL := os.Getenv("USERFRONT_URL")
slog.Info("[Enchanted] Read USERFRONT_URL", "url", userfrontURL)
if userfrontURL == "" {
userfrontURL = "http://sso.hmac.kr"
}
link := fmt.Sprintf("%s/verify/%s", frontendURL, token)
link := fmt.Sprintf("%s/verify/%s", userfrontURL, token)
// Route based on LoginID type
if strings.Contains(loginID, "@") {
@@ -801,16 +801,16 @@ func (h *AuthHandler) InitiatePasswordReset(c *fiber.Ctx) error {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Authentication service not configured"})
}
frontendURL := os.Getenv("FRONTEND_URL")
if frontendURL == "" {
userfrontURL := os.Getenv("USERFRONT_URL")
if userfrontURL == "" {
ale.Status = fiber.StatusInternalServerError
ale.LatencyMs = time.Since(startTime)
ale.DescopeError = "FRONTEND_URL is not set"
ale.Log(slog.LevelError, "FRONTEND_URL is not set")
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "FRONTEND_URL environment variable is not set"})
ale.DescopeError = "USERFRONT_URL is not set"
ale.Log(slog.LevelError, "USERFRONT_URL is not set")
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "USERFRONT_URL environment variable is not set"})
}
// [Changed] Point to Backend API for verification (which then redirects to Frontend)
redirectURL := fmt.Sprintf("%s/api/v1/auth/password/reset/verify", frontendURL)
redirectURL := fmt.Sprintf("%s/api/v1/auth/password/reset/verify", userfrontURL)
ale.RedirectTo = redirectURL
// 내부 토큰 발급 + 우리 채널로 전송
@@ -831,7 +831,7 @@ func (h *AuthHandler) InitiatePasswordReset(c *fiber.Ctx) error {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to store reset token"})
}
resetLink := fmt.Sprintf("%s/reset-password?token=%s", frontendURL, resetToken)
resetLink := fmt.Sprintf("%s/reset-password?token=%s", userfrontURL, resetToken)
ale.RedirectTo = resetLink
ale.Operation = "SendPasswordReset"
ale.Log(slog.LevelInfo, "Initiating password reset via internal token")
@@ -923,7 +923,7 @@ func (h *AuthHandler) VerifyPasswordResetPage(c *fiber.Ctx) error {
}
// ProcessPasswordResetToken - Handles the POST request from the interstitial page.
// Verifies the token, sets the refresh token cookie, and redirects to the frontend.
// Verifies the token, sets the refresh token cookie, and redirects to the userfront.
func (h *AuthHandler) ProcessPasswordResetToken(c *fiber.Ctx) error {
startTime := time.Now()
ale := logger.NewAuditLogEntry(c, "verify")
@@ -960,7 +960,7 @@ func (h *AuthHandler) ProcessPasswordResetToken(c *fiber.Ctx) error {
ale.LoginIDs["loginId_normalized"] = loginID
redirectURL := fmt.Sprintf("%s/reset-password?loginId=%s&token=%s",
os.Getenv("FRONTEND_URL"),
os.Getenv("USERFRONT_URL"),
loginID,
token,
)
@@ -968,7 +968,7 @@ func (h *AuthHandler) ProcessPasswordResetToken(c *fiber.Ctx) error {
ale.RedirectTo = redirectURL
ale.Status = fiber.StatusFound
ale.LatencyMs = time.Since(startTime)
ale.Log(slog.LevelInfo, "Token verified, redirecting to frontend")
ale.Log(slog.LevelInfo, "Token verified, redirecting to userfront")
return c.Redirect(redirectURL)
}
@@ -1127,11 +1127,11 @@ func (h *AuthHandler) InitQRLogin(c *fiber.Ctx) error {
pendingRef := GenerateSecureToken(16)
// QR 코드 페이로드를 실제 접속 가능한 URL로 변경합니다.
frontendURL := os.Getenv("FRONTEND_URL")
if frontendURL == "" {
frontendURL = "https://sso.hmac.kr"
userfrontURL := os.Getenv("USERFRONT_URL")
if userfrontURL == "" {
userfrontURL = "https://sso.hmac.kr"
}
qrPayload := fmt.Sprintf("%s/approve?ref=%s", frontendURL, pendingRef)
qrPayload := fmt.Sprintf("%s/approve?ref=%s", userfrontURL, pendingRef)
slog.Info("[QR] Init", "pendingRef", pendingRef, "url", qrPayload)

View File

@@ -44,7 +44,7 @@ func NewDescopeProvider(projectID, managementKey string) *DescopeProvider {
return &DescopeProvider{
Client: descopeClient,
FrontendURL: os.Getenv("FRONTEND_URL"),
FrontendURL: os.Getenv("USERFRONT_URL"),
fieldMapping: mapping,
}
}

View File

@@ -52,5 +52,6 @@ volumes:
networks:
baron_net:
name: baron_network
name: baron_net
external: true
driver: bridge

View File

@@ -173,7 +173,7 @@ services:
command: >
clients create
--endpoint http://hydra:4445
--id admin-front
--id adminfront
--secret admin-secret
--grant-types authorization_code,refresh_token
--response-types code

View File

@@ -17,7 +17,7 @@ services:
- NAVER_CLOUD_SECRET_KEY=${NAVER_CLOUD_SECRET_KEY}
- NAVER_CLOUD_SERVICE_ID=${NAVER_CLOUD_SERVICE_ID}
- NAVER_SENDER_PHONE_NUMBER=${NAVER_SENDER_PHONE_NUMBER}
- FRONTEND_URL=${FRONTEND_URL}
- USERFRONT_URL=${USERFRONT_URL}
- IDP_PROVIDER=${IDP_PROVIDER:-ory,descope}
- KRATOS_ADMIN_URL=${KRATOS_ADMIN_URL:-http://kratos:4434}
- HYDRA_ADMIN_URL=${HYDRA_ADMIN_URL:-http://hydra:4445}
@@ -44,20 +44,20 @@ services:
retries: 3
start_period: 10s
frontend:
userfront:
build:
context: ./frontend
context: ./userfront
dockerfile: Dockerfile
container_name: baron_frontend
container_name: baron_userfront
env_file:
- .env
environment:
- DESCOPE_PROJECT_ID=${DESCOPE_PROJECT_ID}
- BACKEND_URL=${BACKEND_URL}
- FRONTEND_URL=${FRONTEND_URL}
- USERFRONT_URL=${USERFRONT_URL}
- APP_ENV=${APP_ENV}
ports:
- "${FRONTEND_PORT:-5000}:5000"
- "${USERFRONT_PORT:-5000}:5000"
networks:
- baron_net
depends_on:
@@ -67,7 +67,7 @@ services:
/bin/sh -c "mkdir -p /usr/share/nginx/html/assets &&
echo \"DESCOPE_PROJECT_ID=$${DESCOPE_PROJECT_ID}\" > /usr/share/nginx/html/assets/.env &&
echo \"BACKEND_URL=$${BACKEND_URL}\" >> /usr/share/nginx/html/assets/.env &&
echo \"FRONTEND_URL=$${FRONTEND_URL}\" >> /usr/share/nginx/html/assets/.env &&
echo \"USERFRONT_URL=$${USERFRONT_URL}\" >> /usr/share/nginx/html/assets/.env &&
echo \"APP_ENV=$${APP_ENV}\" >> /usr/share/nginx/html/assets/.env &&
cp /usr/share/nginx/html/assets/.env /usr/share/nginx/html/.env &&
nginx -g 'daemon off;'"
@@ -85,7 +85,7 @@ services:
networks:
baron_net:
external: true
name: baron_network
name: baron_net
ory-net:
external: true
name: ory-net

View File

@@ -13,10 +13,10 @@ Backend와 Frontend 애플리케이션을 각각의 Dockerfile을 사용하여
```bash
# Backend 이미지 빌드
# v1.2601.1-RC1 부분은 실제 배포 버전에 맞게 수정하세요.
docker build -t reg.hmac.kr/baron_sso/backend:v1.2601.1-RC1 -f docker/Dockerfile.backend .
docker build -t reg.hmac.kr/baron_sso/backend:v1.2601.1-RC1 -f backend/Dockerfile .
# Frontend 이미지 빌드
docker build -t reg.hmac.kr/baron_sso/frontend:v1.2601.1-RC1 -f docker/Dockerfile.frontend .
docker build -t reg.hmac.kr/baron_sso/userfront:v1.2601.1-RC1 -f userfront/Dockerfile .
```
---
@@ -42,7 +42,7 @@ docker login reg.hmac.kr
docker push reg.hmac.kr/baron_sso/backend:v1.2601.1-RC1
# Frontend 이미지 푸시
docker push reg.hmac.kr/baron_sso/frontend:v1.2601.1-RC1
docker push reg.hmac.kr/baron_sso/userfront:v1.2601.1-RC1
```
---

View File

@@ -16,7 +16,7 @@ services:
- CLICKHOUSE_PORT=${CLICKHOUSE_PORT_NATIVE:-9000}
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-baron}
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-password}
- FRONTEND_URL=${FRONTEND_URL:-https://sso.hmac.kr}
- USERFRONT_URL=${USERFRONT_URL:-https://sso.hmac.kr}
ports:
- "${BACKEND_PORT:-3010}:3010"
depends_on:
@@ -30,15 +30,15 @@ services:
networks:
- baron_net
frontend:
image: ${FRONTEND_IMAGE_NAME}:${IMAGE_TAG}
container_name: baron_frontend
userfront:
image: ${USERFRONT_IMAGE_NAME}:${IMAGE_TAG}
container_name: baron_userfront
restart: unless-stopped
environment:
- FRONTEND_URL=${FRONTEND_URL:-https://sso.hmac.kr}
- BACKEND_URL=${FRONTEND_URL:-https://sso.hmac.kr}
- USERFRONT_URL=${USERFRONT_URL:-https://sso.hmac.kr}
- BACKEND_URL=${USERFRONT_URL:-https://sso.hmac.kr}
ports:
- "${FRONTEND_PORT:-80}:80"
- "${USERFRONT_PORT:-80}:80"
depends_on:
backend:
condition: service_healthy

View File

@@ -35,7 +35,7 @@
## Workspace Structure
Root: `/home/lectom/.gemini/antigravity/scratch/baron_sso`
- `/backend`: Go Fiber Application
- `/frontend`: Flutter Application
- `/userfront`: Flutter Application
- `/docs`: Documentation (PRD, API Specs)
## Current Status

View File

@@ -1,98 +0,0 @@
name: frontend
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: "none" # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: ^3.10.4
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
flutter_riverpod: ^3.0.3
go_router: ^17.0.1
descope: ^0.9.11
http: ^1.6.0
google_fonts: ^6.3.3
flutter_dotenv: ^5.1.0
url_launcher: ^6.3.2
logging: ^1.2.0
logger: ^2.0.0
qr_flutter: ^4.1.0
mobile_scanner: ^6.0.0
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^6.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - .env
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/to/asset-from-package
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/to/font-from-package

View File

@@ -11,7 +11,7 @@ DB_PORT=5432
CLICKHOUSE_PORT_HTTP=8123
CLICKHOUSE_PORT_NATIVE=9000
BACKEND_PORT=3000
FRONTEND_PORT=5000
USERFRONT_PORT=5000
# --- Database Credentials (PostgreSQL) ---
DB_USER=baron

View File

@@ -6,7 +6,7 @@ plugins {
}
android {
namespace = "kr.co.baroncs.frontend"
namespace = "kr.co.baroncs.userfront"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
@@ -21,7 +21,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "kr.co.baroncs.frontend"
applicationId = "kr.co.baroncs.userfront"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion

View File

@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:label="frontend"
android:label="userfront"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity

View File

@@ -1,4 +1,4 @@
package kr.co.baroncs.frontend
package kr.co.baroncs.userfront
import io.flutter.embedding.android.FlutterActivity

View File

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 544 B

View File

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

View File

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 721 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -368,7 +368,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.frontend;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.userfront;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
@@ -384,7 +384,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.frontend.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.userfront.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -401,7 +401,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.frontend.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.userfront.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@@ -416,7 +416,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.frontend.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.userfront.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@@ -547,7 +547,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.frontend;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.userfront;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -569,7 +569,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.frontend;
PRODUCT_BUNDLE_IDENTIFIER = kr.co.baroncs.userfront;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;

Some files were not shown because too many files have changed in this diff Show More