userfront로 리펙토링 완료
@@ -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 백업)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
32
README.md
@@ -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. 애플리케이션 실행
|
||||
Frontend와 Backend 서비스를 실행합니다.
|
||||
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**: 대시보드 및 통합 런처 구현 (예정)
|
||||
|
||||
14
README_en.md
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
@@ -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",
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "admin-front",
|
||||
"name": "adminfront",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -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{" "}
|
||||
@@ -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"),
|
||||
)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,5 +52,6 @@ volumes:
|
||||
|
||||
networks:
|
||||
baron_net:
|
||||
name: baron_network
|
||||
name: baron_net
|
||||
external: true
|
||||
driver: bridge
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,91 +1,91 @@
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: baron_backend
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- GO_ENV=${APP_ENV:-development}
|
||||
- COOKIE_SECRET=${COOKIE_SECRET}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- DESCOPE_PROJECT_ID=${DESCOPE_PROJECT_ID}
|
||||
- DESCOPE_MANAGEMENT_KEY=${DESCOPE_MANAGEMENT_KEY}
|
||||
- NAVER_CLOUD_ACCESS_KEY=${NAVER_CLOUD_ACCESS_KEY}
|
||||
- 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}
|
||||
- IDP_PROVIDER=${IDP_PROVIDER:-ory,descope}
|
||||
- KRATOS_ADMIN_URL=${KRATOS_ADMIN_URL:-http://kratos:4434}
|
||||
- HYDRA_ADMIN_URL=${HYDRA_ADMIN_URL:-http://hydra:4445}
|
||||
- DB_HOST=postgres
|
||||
- CLICKHOUSE_HOST=clickhouse
|
||||
- CLICKHOUSE_PORT=${CLICKHOUSE_PORT_NATIVE:-9000}
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-baron}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-password}
|
||||
ports:
|
||||
- "${BACKEND_PORT:-3000}:3000"
|
||||
depends_on:
|
||||
- infra_check
|
||||
networks:
|
||||
- baron_net
|
||||
- ory-net
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
command: ["go", "run", "./cmd/server/main.go"]
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: baron_backend
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- GO_ENV=${APP_ENV:-development}
|
||||
- COOKIE_SECRET=${COOKIE_SECRET}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- DESCOPE_PROJECT_ID=${DESCOPE_PROJECT_ID}
|
||||
- DESCOPE_MANAGEMENT_KEY=${DESCOPE_MANAGEMENT_KEY}
|
||||
- NAVER_CLOUD_ACCESS_KEY=${NAVER_CLOUD_ACCESS_KEY}
|
||||
- NAVER_CLOUD_SECRET_KEY=${NAVER_CLOUD_SECRET_KEY}
|
||||
- NAVER_CLOUD_SERVICE_ID=${NAVER_CLOUD_SERVICE_ID}
|
||||
- NAVER_SENDER_PHONE_NUMBER=${NAVER_SENDER_PHONE_NUMBER}
|
||||
- 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}
|
||||
- DB_HOST=postgres
|
||||
- CLICKHOUSE_HOST=clickhouse
|
||||
- CLICKHOUSE_PORT=${CLICKHOUSE_PORT_NATIVE:-9000}
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-baron}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-password}
|
||||
ports:
|
||||
- "${BACKEND_PORT:-3000}:3000"
|
||||
depends_on:
|
||||
- infra_check
|
||||
networks:
|
||||
- baron_net
|
||||
- ory-net
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
command: ["go", "run", "./cmd/server/main.go"]
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/health"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/health"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
container_name: baron_frontend
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- DESCOPE_PROJECT_ID=${DESCOPE_PROJECT_ID}
|
||||
- BACKEND_URL=${BACKEND_URL}
|
||||
- FRONTEND_URL=${FRONTEND_URL}
|
||||
- APP_ENV=${APP_ENV}
|
||||
ports:
|
||||
- "${FRONTEND_PORT:-5000}:5000"
|
||||
networks:
|
||||
- baron_net
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
command: >
|
||||
/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 \"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;'"
|
||||
userfront:
|
||||
build:
|
||||
context: ./userfront
|
||||
dockerfile: Dockerfile
|
||||
container_name: baron_userfront
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- DESCOPE_PROJECT_ID=${DESCOPE_PROJECT_ID}
|
||||
- BACKEND_URL=${BACKEND_URL}
|
||||
- USERFRONT_URL=${USERFRONT_URL}
|
||||
- APP_ENV=${APP_ENV}
|
||||
ports:
|
||||
- "${USERFRONT_PORT:-5000}:5000"
|
||||
networks:
|
||||
- baron_net
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
command: >
|
||||
/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 \"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;'"
|
||||
|
||||
# Dummy service to wait for infra network if needed,
|
||||
# but essentially we assume infra is running.
|
||||
# In a real unified stack, we might include infra here or use external links.
|
||||
# Here we attach to the same network.
|
||||
infra_check:
|
||||
image: alpine
|
||||
command: ["echo", "Infrastructure assumed running"]
|
||||
networks:
|
||||
- baron_net
|
||||
# Dummy service to wait for infra network if needed,
|
||||
# but essentially we assume infra is running.
|
||||
# In a real unified stack, we might include infra here or use external links.
|
||||
# Here we attach to the same network.
|
||||
infra_check:
|
||||
image: alpine
|
||||
command: ["echo", "Infrastructure assumed running"]
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
networks:
|
||||
baron_net:
|
||||
external: true
|
||||
name: baron_network
|
||||
ory-net:
|
||||
external: true
|
||||
name: ory-net
|
||||
baron_net:
|
||||
external: true
|
||||
name: baron_net
|
||||
ory-net:
|
||||
external: true
|
||||
name: ory-net
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,4 +1,4 @@
|
||||
package kr.co.baroncs.frontend
|
||||
package kr.co.baroncs.userfront
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 544 B |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -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;
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 295 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 282 B |
|
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 462 B |