From 1aaa772907fefe71a37f8ef7821b76d829964096 Mon Sep 17 00:00:00 2001 From: Lectom C Han Date: Wed, 28 Jan 2026 08:28:25 +0900 Subject: [PATCH] =?UTF-8?q?userfront=EB=A1=9C=20=EB=A6=AC=ED=8E=99?= =?UTF-8?q?=ED=86=A0=EB=A7=81=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.sample | 4 +- .gitea/workflows/build_RC.yml | 14 +- .gitea/workflows/code_check.yml | 18 +- .gitea/workflows/production_release.yml | 14 +- .gitignore | 14 +- README.md | 32 ++-- README_en.md | 14 +- {admin-front => adminfront}/.gitignore | 0 {admin-front => adminfront}/README.md | 0 {admin-front => adminfront}/biome.json | 0 {admin-front => adminfront}/index.html | 2 +- {admin-front => adminfront}/package-lock.json | 4 +- {admin-front => adminfront}/package.json | 2 +- {admin-front => adminfront}/postcss.config.js | 0 {admin-front => adminfront}/public/vite.svg | 0 .../src/app/queryClient.ts | 0 .../src/app/routes.tsx | 0 .../src/assets/react.svg | 0 .../src/components/layout/AppLayout.tsx | 0 .../src/components/ui/avatar.tsx | 0 .../src/components/ui/badge.tsx | 0 .../src/components/ui/button.tsx | 0 .../src/components/ui/card.tsx | 0 .../src/components/ui/input.tsx | 0 .../src/components/ui/label.tsx | 0 .../src/components/ui/scroll-area.tsx | 0 .../src/components/ui/separator.tsx | 0 .../src/components/ui/switch.tsx | 0 .../src/components/ui/table.tsx | 0 .../src/components/ui/textarea.tsx | 0 .../src/features/audit/AuditLogsPage.tsx | 0 .../src/features/auth/AuthPage.tsx | 0 .../features/clients/ClientConsentsPage.tsx | 0 .../features/clients/ClientDetailsPage.tsx | 0 .../features/clients/ClientGeneralPage.tsx | 0 .../src/features/clients/ClientsPage.tsx | 0 .../src/features/dashboard/DashboardPage.tsx | 2 +- {admin-front => adminfront}/src/index.css | 0 .../src/lib/apiClient.ts | 0 {admin-front => adminfront}/src/lib/utils.ts | 0 {admin-front => adminfront}/src/main.tsx | 0 .../tailwind.config.ts | 0 {admin-front => adminfront}/tsconfig.app.json | 0 {admin-front => adminfront}/tsconfig.json | 0 .../tsconfig.node.json | 0 {admin-front => adminfront}/vite.config.ts | 0 backend/cmd/server/main.go | 4 +- backend/internal/handler/auth_handler.go | 40 ++--- backend/internal/service/descope_service.go | 2 +- compose.infra.yaml | 3 +- compose.ory.yaml | 2 +- docker-compose.yaml | 170 +++++++++--------- docker/README.md | 6 +- docker/docker-compose.template.yaml | 14 +- docs/Gemini.md | 2 +- frontend/pubspec.yaml | 98 ---------- {frontend => userfront}/.env.sample | 2 +- {frontend => userfront}/.gitignore | 0 {frontend => userfront}/.metadata | 0 {frontend => userfront}/Dockerfile | 0 {frontend => userfront}/analysis_options.yaml | 0 {frontend => userfront}/android/.gitignore | 0 .../android/app/build.gradle.kts | 4 +- .../android/app/src/debug/AndroidManifest.xml | 0 .../android/app/src/main/AndroidManifest.xml | 2 +- .../kr/co/baroncs/frontend/MainActivity.kt | 2 +- .../res/drawable-v21/launch_background.xml | 0 .../main/res/drawable/launch_background.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../app/src/main/res/values-night/styles.xml | 0 .../app/src/main/res/values/styles.xml | 0 .../app/src/profile/AndroidManifest.xml | 0 .../android/build.gradle.kts | 0 .../android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../android/settings.gradle.kts | 0 {frontend => userfront}/ios/.gitignore | 0 .../ios/Flutter/AppFrameworkInfo.plist | 0 .../ios/Flutter/Debug.xcconfig | 0 .../ios/Flutter/Release.xcconfig | 0 .../ios/Runner.xcodeproj/project.pbxproj | 12 +- .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../ios/Runner/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../Icon-App-1024x1024@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../Icon-App-83.5x83.5@2x.png | Bin .../LaunchImage.imageset/Contents.json | 0 .../LaunchImage.imageset/LaunchImage.png | Bin .../LaunchImage.imageset/LaunchImage@2x.png | Bin .../LaunchImage.imageset/LaunchImage@3x.png | Bin .../LaunchImage.imageset/README.md | 0 .../Runner/Base.lproj/LaunchScreen.storyboard | 0 .../ios/Runner/Base.lproj/Main.storyboard | 0 {frontend => userfront}/ios/Runner/Info.plist | 2 +- .../ios/Runner/Runner-Bridging-Header.h | 0 .../ios/RunnerTests/RunnerTests.swift | 0 .../lib/core/notifiers/auth_notifier.dart | 0 .../lib/core/services/audit_service.dart | 9 +- .../lib/core/services/auth_proxy_service.dart | 13 +- .../lib/core/services/logger_service.dart | 2 +- .../core/services/web_auth_integration.dart | 0 .../services/web_auth_integration_stub.dart | 0 .../services/web_auth_integration_web.dart | 0 .../presentation/create_user_screen.dart | 0 .../presentation/user_management_screen.dart | 0 .../auth/presentation/approve_qr_screen.dart | 0 .../presentation/forgot_password_screen.dart | 0 .../auth/presentation/login_screen.dart | 0 .../presentation/login_success_screen.dart | 0 .../auth/presentation/qr_scan_screen.dart | 0 .../presentation/reset_password_screen.dart | 0 .../auth/presentation/signup_screen.dart | 0 .../presentation/dashboard_screen.dart | 0 .../data/models/user_profile_model.dart | 0 .../data/repositories/profile_repository.dart | 9 +- .../domain/notifiers/profile_notifier.dart | 0 .../presentation/pages/edit_profile_page.dart | 0 .../presentation/pages/profile_page.dart | 0 .../widgets/profile_info_row.dart | 0 {frontend => userfront}/lib/main.dart | 21 ++- {frontend => userfront}/nginx.conf | 2 +- {frontend => userfront}/pubspec.lock | 4 +- userfront/pubspec.yaml | 98 ++++++++++ {frontend => userfront}/test/widget_test.dart | 2 +- {frontend => userfront}/web/favicon.png | Bin .../web/icons/Icon-192.png | Bin .../web/icons/Icon-512.png | Bin .../web/icons/Icon-maskable-192.png | Bin .../web/icons/Icon-maskable-512.png | Bin {frontend => userfront}/web/index.html | 4 +- {frontend => userfront}/web/manifest.json | 4 +- 154 files changed, 339 insertions(+), 314 deletions(-) rename {admin-front => adminfront}/.gitignore (100%) rename {admin-front => adminfront}/README.md (100%) rename {admin-front => adminfront}/biome.json (100%) rename {admin-front => adminfront}/index.html (91%) rename {admin-front => adminfront}/package-lock.json (99%) rename {admin-front => adminfront}/package.json (97%) rename {admin-front => adminfront}/postcss.config.js (100%) rename {admin-front => adminfront}/public/vite.svg (100%) rename {admin-front => adminfront}/src/app/queryClient.ts (100%) rename {admin-front => adminfront}/src/app/routes.tsx (100%) rename {admin-front => adminfront}/src/assets/react.svg (100%) rename {admin-front => adminfront}/src/components/layout/AppLayout.tsx (100%) rename {admin-front => adminfront}/src/components/ui/avatar.tsx (100%) rename {admin-front => adminfront}/src/components/ui/badge.tsx (100%) rename {admin-front => adminfront}/src/components/ui/button.tsx (100%) rename {admin-front => adminfront}/src/components/ui/card.tsx (100%) rename {admin-front => adminfront}/src/components/ui/input.tsx (100%) rename {admin-front => adminfront}/src/components/ui/label.tsx (100%) rename {admin-front => adminfront}/src/components/ui/scroll-area.tsx (100%) rename {admin-front => adminfront}/src/components/ui/separator.tsx (100%) rename {admin-front => adminfront}/src/components/ui/switch.tsx (100%) rename {admin-front => adminfront}/src/components/ui/table.tsx (100%) rename {admin-front => adminfront}/src/components/ui/textarea.tsx (100%) rename {admin-front => adminfront}/src/features/audit/AuditLogsPage.tsx (100%) rename {admin-front => adminfront}/src/features/auth/AuthPage.tsx (100%) rename {admin-front => adminfront}/src/features/clients/ClientConsentsPage.tsx (100%) rename {admin-front => adminfront}/src/features/clients/ClientDetailsPage.tsx (100%) rename {admin-front => adminfront}/src/features/clients/ClientGeneralPage.tsx (100%) rename {admin-front => adminfront}/src/features/clients/ClientsPage.tsx (100%) rename {admin-front => adminfront}/src/features/dashboard/DashboardPage.tsx (99%) rename {admin-front => adminfront}/src/index.css (100%) rename {admin-front => adminfront}/src/lib/apiClient.ts (100%) rename {admin-front => adminfront}/src/lib/utils.ts (100%) rename {admin-front => adminfront}/src/main.tsx (100%) rename {admin-front => adminfront}/tailwind.config.ts (100%) rename {admin-front => adminfront}/tsconfig.app.json (100%) rename {admin-front => adminfront}/tsconfig.json (100%) rename {admin-front => adminfront}/tsconfig.node.json (100%) rename {admin-front => adminfront}/vite.config.ts (100%) delete mode 100644 frontend/pubspec.yaml rename {frontend => userfront}/.env.sample (97%) rename {frontend => userfront}/.gitignore (100%) rename {frontend => userfront}/.metadata (100%) rename {frontend => userfront}/Dockerfile (100%) rename {frontend => userfront}/analysis_options.yaml (100%) rename {frontend => userfront}/android/.gitignore (100%) rename {frontend => userfront}/android/app/build.gradle.kts (93%) rename {frontend => userfront}/android/app/src/debug/AndroidManifest.xml (100%) rename {frontend => userfront}/android/app/src/main/AndroidManifest.xml (98%) rename {frontend => userfront}/android/app/src/main/kotlin/kr/co/baroncs/frontend/MainActivity.kt (74%) rename {frontend => userfront}/android/app/src/main/res/drawable-v21/launch_background.xml (100%) rename {frontend => userfront}/android/app/src/main/res/drawable/launch_background.xml (100%) rename {frontend => userfront}/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {frontend => userfront}/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {frontend => userfront}/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {frontend => userfront}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {frontend => userfront}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {frontend => userfront}/android/app/src/main/res/values-night/styles.xml (100%) rename {frontend => userfront}/android/app/src/main/res/values/styles.xml (100%) rename {frontend => userfront}/android/app/src/profile/AndroidManifest.xml (100%) rename {frontend => userfront}/android/build.gradle.kts (100%) rename {frontend => userfront}/android/gradle.properties (100%) rename {frontend => userfront}/android/gradle/wrapper/gradle-wrapper.properties (100%) rename {frontend => userfront}/android/settings.gradle.kts (100%) rename {frontend => userfront}/ios/.gitignore (100%) rename {frontend => userfront}/ios/Flutter/AppFrameworkInfo.plist (100%) rename {frontend => userfront}/ios/Flutter/Debug.xcconfig (100%) rename {frontend => userfront}/ios/Flutter/Release.xcconfig (100%) rename {frontend => userfront}/ios/Runner.xcodeproj/project.pbxproj (98%) rename {frontend => userfront}/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename {frontend => userfront}/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {frontend => userfront}/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename {frontend => userfront}/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename {frontend => userfront}/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename {frontend => userfront}/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {frontend => userfront}/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename {frontend => userfront}/ios/Runner/AppDelegate.swift (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png (100%) rename {frontend => userfront}/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md (100%) rename {frontend => userfront}/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename {frontend => userfront}/ios/Runner/Base.lproj/Main.storyboard (100%) rename {frontend => userfront}/ios/Runner/Info.plist (98%) rename {frontend => userfront}/ios/Runner/Runner-Bridging-Header.h (100%) rename {frontend => userfront}/ios/RunnerTests/RunnerTests.swift (100%) rename {frontend => userfront}/lib/core/notifiers/auth_notifier.dart (100%) rename {frontend => userfront}/lib/core/services/audit_service.dart (79%) rename {frontend => userfront}/lib/core/services/auth_proxy_service.dart (97%) rename {frontend => userfront}/lib/core/services/logger_service.dart (98%) rename {frontend => userfront}/lib/core/services/web_auth_integration.dart (100%) rename {frontend => userfront}/lib/core/services/web_auth_integration_stub.dart (100%) rename {frontend => userfront}/lib/core/services/web_auth_integration_web.dart (100%) rename {frontend => userfront}/lib/features/admin/presentation/create_user_screen.dart (100%) rename {frontend => userfront}/lib/features/admin/presentation/user_management_screen.dart (100%) rename {frontend => userfront}/lib/features/auth/presentation/approve_qr_screen.dart (100%) rename {frontend => userfront}/lib/features/auth/presentation/forgot_password_screen.dart (100%) rename {frontend => userfront}/lib/features/auth/presentation/login_screen.dart (100%) rename {frontend => userfront}/lib/features/auth/presentation/login_success_screen.dart (100%) rename {frontend => userfront}/lib/features/auth/presentation/qr_scan_screen.dart (100%) rename {frontend => userfront}/lib/features/auth/presentation/reset_password_screen.dart (100%) rename {frontend => userfront}/lib/features/auth/presentation/signup_screen.dart (100%) rename {frontend => userfront}/lib/features/dashboard/presentation/dashboard_screen.dart (100%) rename {frontend => userfront}/lib/features/profile/data/models/user_profile_model.dart (100%) rename {frontend => userfront}/lib/features/profile/data/repositories/profile_repository.dart (91%) rename {frontend => userfront}/lib/features/profile/domain/notifiers/profile_notifier.dart (100%) rename {frontend => userfront}/lib/features/profile/presentation/pages/edit_profile_page.dart (100%) rename {frontend => userfront}/lib/features/profile/presentation/pages/profile_page.dart (100%) rename {frontend => userfront}/lib/features/profile/presentation/widgets/profile_info_row.dart (100%) rename {frontend => userfront}/lib/main.dart (92%) rename {frontend => userfront}/nginx.conf (97%) rename {frontend => userfront}/pubspec.lock (99%) create mode 100644 userfront/pubspec.yaml rename {frontend => userfront}/test/widget_test.dart (93%) rename {frontend => userfront}/web/favicon.png (100%) rename {frontend => userfront}/web/icons/Icon-192.png (100%) rename {frontend => userfront}/web/icons/Icon-512.png (100%) rename {frontend => userfront}/web/icons/Icon-maskable-192.png (100%) rename {frontend => userfront}/web/icons/Icon-maskable-512.png (100%) rename {frontend => userfront}/web/index.html (93%) rename {frontend => userfront}/web/manifest.json (93%) diff --git a/.env.sample b/.env.sample index 35fad84e..2e393b60 100644 --- a/.env.sample +++ b/.env.sample @@ -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 백업) diff --git a/.gitea/workflows/build_RC.yml b/.gitea/workflows/build_RC.yml index 43d2b51c..cae77ad0 100644 --- a/.gitea/workflows/build_RC.yml +++ b/.gitea/workflows/build_RC.yml @@ -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 diff --git a/.gitea/workflows/code_check.yml b/.gitea/workflows/code_check.yml index 8204562b..3640da92 100644 --- a/.gitea/workflows/code_check.yml +++ b/.gitea/workflows/code_check.yml @@ -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 diff --git a/.gitea/workflows/production_release.yml b/.gitea/workflows/production_release.yml index e7ae54fc..1fdeaea6 100644 --- a/.gitea/workflows/production_release.yml +++ b/.gitea/workflows/production_release.yml @@ -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}'; \ diff --git a/.gitignore b/.gitignore index 2fe66cc5..276b51e6 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/README.md b/README.md index 9d2e2836..15ff9e62 100644 --- a/README.md +++ b/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**: 대시보드 및 통합 런처 구현 (예정) diff --git a/README_en.md b/README_en.md index f70ec13a..8226818f 100644 --- a/README_en.md +++ b/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) diff --git a/admin-front/.gitignore b/adminfront/.gitignore similarity index 100% rename from admin-front/.gitignore rename to adminfront/.gitignore diff --git a/admin-front/README.md b/adminfront/README.md similarity index 100% rename from admin-front/README.md rename to adminfront/README.md diff --git a/admin-front/biome.json b/adminfront/biome.json similarity index 100% rename from admin-front/biome.json rename to adminfront/biome.json diff --git a/admin-front/index.html b/adminfront/index.html similarity index 91% rename from admin-front/index.html rename to adminfront/index.html index 0cd3db3c..544bf2dd 100644 --- a/admin-front/index.html +++ b/adminfront/index.html @@ -4,7 +4,7 @@ - admin-front + adminfront
diff --git a/admin-front/package-lock.json b/adminfront/package-lock.json similarity index 99% rename from admin-front/package-lock.json rename to adminfront/package-lock.json index c70f257c..882b5a06 100644 --- a/admin-front/package-lock.json +++ b/adminfront/package-lock.json @@ -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", diff --git a/admin-front/package.json b/adminfront/package.json similarity index 97% rename from admin-front/package.json rename to adminfront/package.json index 85469040..be0b0953 100644 --- a/admin-front/package.json +++ b/adminfront/package.json @@ -1,5 +1,5 @@ { - "name": "admin-front", + "name": "adminfront", "private": true, "version": "0.0.0", "type": "module", diff --git a/admin-front/postcss.config.js b/adminfront/postcss.config.js similarity index 100% rename from admin-front/postcss.config.js rename to adminfront/postcss.config.js diff --git a/admin-front/public/vite.svg b/adminfront/public/vite.svg similarity index 100% rename from admin-front/public/vite.svg rename to adminfront/public/vite.svg diff --git a/admin-front/src/app/queryClient.ts b/adminfront/src/app/queryClient.ts similarity index 100% rename from admin-front/src/app/queryClient.ts rename to adminfront/src/app/queryClient.ts diff --git a/admin-front/src/app/routes.tsx b/adminfront/src/app/routes.tsx similarity index 100% rename from admin-front/src/app/routes.tsx rename to adminfront/src/app/routes.tsx diff --git a/admin-front/src/assets/react.svg b/adminfront/src/assets/react.svg similarity index 100% rename from admin-front/src/assets/react.svg rename to adminfront/src/assets/react.svg diff --git a/admin-front/src/components/layout/AppLayout.tsx b/adminfront/src/components/layout/AppLayout.tsx similarity index 100% rename from admin-front/src/components/layout/AppLayout.tsx rename to adminfront/src/components/layout/AppLayout.tsx diff --git a/admin-front/src/components/ui/avatar.tsx b/adminfront/src/components/ui/avatar.tsx similarity index 100% rename from admin-front/src/components/ui/avatar.tsx rename to adminfront/src/components/ui/avatar.tsx diff --git a/admin-front/src/components/ui/badge.tsx b/adminfront/src/components/ui/badge.tsx similarity index 100% rename from admin-front/src/components/ui/badge.tsx rename to adminfront/src/components/ui/badge.tsx diff --git a/admin-front/src/components/ui/button.tsx b/adminfront/src/components/ui/button.tsx similarity index 100% rename from admin-front/src/components/ui/button.tsx rename to adminfront/src/components/ui/button.tsx diff --git a/admin-front/src/components/ui/card.tsx b/adminfront/src/components/ui/card.tsx similarity index 100% rename from admin-front/src/components/ui/card.tsx rename to adminfront/src/components/ui/card.tsx diff --git a/admin-front/src/components/ui/input.tsx b/adminfront/src/components/ui/input.tsx similarity index 100% rename from admin-front/src/components/ui/input.tsx rename to adminfront/src/components/ui/input.tsx diff --git a/admin-front/src/components/ui/label.tsx b/adminfront/src/components/ui/label.tsx similarity index 100% rename from admin-front/src/components/ui/label.tsx rename to adminfront/src/components/ui/label.tsx diff --git a/admin-front/src/components/ui/scroll-area.tsx b/adminfront/src/components/ui/scroll-area.tsx similarity index 100% rename from admin-front/src/components/ui/scroll-area.tsx rename to adminfront/src/components/ui/scroll-area.tsx diff --git a/admin-front/src/components/ui/separator.tsx b/adminfront/src/components/ui/separator.tsx similarity index 100% rename from admin-front/src/components/ui/separator.tsx rename to adminfront/src/components/ui/separator.tsx diff --git a/admin-front/src/components/ui/switch.tsx b/adminfront/src/components/ui/switch.tsx similarity index 100% rename from admin-front/src/components/ui/switch.tsx rename to adminfront/src/components/ui/switch.tsx diff --git a/admin-front/src/components/ui/table.tsx b/adminfront/src/components/ui/table.tsx similarity index 100% rename from admin-front/src/components/ui/table.tsx rename to adminfront/src/components/ui/table.tsx diff --git a/admin-front/src/components/ui/textarea.tsx b/adminfront/src/components/ui/textarea.tsx similarity index 100% rename from admin-front/src/components/ui/textarea.tsx rename to adminfront/src/components/ui/textarea.tsx diff --git a/admin-front/src/features/audit/AuditLogsPage.tsx b/adminfront/src/features/audit/AuditLogsPage.tsx similarity index 100% rename from admin-front/src/features/audit/AuditLogsPage.tsx rename to adminfront/src/features/audit/AuditLogsPage.tsx diff --git a/admin-front/src/features/auth/AuthPage.tsx b/adminfront/src/features/auth/AuthPage.tsx similarity index 100% rename from admin-front/src/features/auth/AuthPage.tsx rename to adminfront/src/features/auth/AuthPage.tsx diff --git a/admin-front/src/features/clients/ClientConsentsPage.tsx b/adminfront/src/features/clients/ClientConsentsPage.tsx similarity index 100% rename from admin-front/src/features/clients/ClientConsentsPage.tsx rename to adminfront/src/features/clients/ClientConsentsPage.tsx diff --git a/admin-front/src/features/clients/ClientDetailsPage.tsx b/adminfront/src/features/clients/ClientDetailsPage.tsx similarity index 100% rename from admin-front/src/features/clients/ClientDetailsPage.tsx rename to adminfront/src/features/clients/ClientDetailsPage.tsx diff --git a/admin-front/src/features/clients/ClientGeneralPage.tsx b/adminfront/src/features/clients/ClientGeneralPage.tsx similarity index 100% rename from admin-front/src/features/clients/ClientGeneralPage.tsx rename to adminfront/src/features/clients/ClientGeneralPage.tsx diff --git a/admin-front/src/features/clients/ClientsPage.tsx b/adminfront/src/features/clients/ClientsPage.tsx similarity index 100% rename from admin-front/src/features/clients/ClientsPage.tsx rename to adminfront/src/features/clients/ClientsPage.tsx diff --git a/admin-front/src/features/dashboard/DashboardPage.tsx b/adminfront/src/features/dashboard/DashboardPage.tsx similarity index 99% rename from admin-front/src/features/dashboard/DashboardPage.tsx rename to adminfront/src/features/dashboard/DashboardPage.tsx index b7e692c7..e4b29dc2 100644 --- a/admin-front/src/features/dashboard/DashboardPage.tsx +++ b/adminfront/src/features/dashboard/DashboardPage.tsx @@ -54,7 +54,7 @@ function DashboardPage() {
- admin-front ready + adminfront ready

Build the admin plane with{" "} diff --git a/admin-front/src/index.css b/adminfront/src/index.css similarity index 100% rename from admin-front/src/index.css rename to adminfront/src/index.css diff --git a/admin-front/src/lib/apiClient.ts b/adminfront/src/lib/apiClient.ts similarity index 100% rename from admin-front/src/lib/apiClient.ts rename to adminfront/src/lib/apiClient.ts diff --git a/admin-front/src/lib/utils.ts b/adminfront/src/lib/utils.ts similarity index 100% rename from admin-front/src/lib/utils.ts rename to adminfront/src/lib/utils.ts diff --git a/admin-front/src/main.tsx b/adminfront/src/main.tsx similarity index 100% rename from admin-front/src/main.tsx rename to adminfront/src/main.tsx diff --git a/admin-front/tailwind.config.ts b/adminfront/tailwind.config.ts similarity index 100% rename from admin-front/tailwind.config.ts rename to adminfront/tailwind.config.ts diff --git a/admin-front/tsconfig.app.json b/adminfront/tsconfig.app.json similarity index 100% rename from admin-front/tsconfig.app.json rename to adminfront/tsconfig.app.json diff --git a/admin-front/tsconfig.json b/adminfront/tsconfig.json similarity index 100% rename from admin-front/tsconfig.json rename to adminfront/tsconfig.json diff --git a/admin-front/tsconfig.node.json b/adminfront/tsconfig.node.json similarity index 100% rename from admin-front/tsconfig.node.json rename to adminfront/tsconfig.node.json diff --git a/admin-front/vite.config.ts b/adminfront/vite.config.ts similarity index 100% rename from admin-front/vite.config.ts rename to adminfront/vite.config.ts diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 39495683..78e1a238 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -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"), ) diff --git a/backend/internal/handler/auth_handler.go b/backend/internal/handler/auth_handler.go index 035340b5..d049552c 100644 --- a/backend/internal/handler/auth_handler.go +++ b/backend/internal/handler/auth_handler.go @@ -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) diff --git a/backend/internal/service/descope_service.go b/backend/internal/service/descope_service.go index e8869ae9..e9f44889 100644 --- a/backend/internal/service/descope_service.go +++ b/backend/internal/service/descope_service.go @@ -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, } } diff --git a/compose.infra.yaml b/compose.infra.yaml index 1346541e..f53bfe4e 100644 --- a/compose.infra.yaml +++ b/compose.infra.yaml @@ -52,5 +52,6 @@ volumes: networks: baron_net: - name: baron_network + name: baron_net + external: true driver: bridge diff --git a/compose.ory.yaml b/compose.ory.yaml index 5c18aa9a..7bd8003f 100644 --- a/compose.ory.yaml +++ b/compose.ory.yaml @@ -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 diff --git a/docker-compose.yaml b/docker-compose.yaml index 3fec1ba2..e0ba67ce 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -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 diff --git a/docker/README.md b/docker/README.md index bebf3c08..84203420 100644 --- a/docker/README.md +++ b/docker/README.md @@ -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 ``` --- diff --git a/docker/docker-compose.template.yaml b/docker/docker-compose.template.yaml index 84a1c596..1f4ee66f 100644 --- a/docker/docker-compose.template.yaml +++ b/docker/docker-compose.template.yaml @@ -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 diff --git a/docs/Gemini.md b/docs/Gemini.md index bd9d8078..156f19e3 100644 --- a/docs/Gemini.md +++ b/docs/Gemini.md @@ -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 diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml deleted file mode 100644 index 483db966..00000000 --- a/frontend/pubspec.yaml +++ /dev/null @@ -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 diff --git a/frontend/.env.sample b/userfront/.env.sample similarity index 97% rename from frontend/.env.sample rename to userfront/.env.sample index 1a40fcee..5317d76e 100644 --- a/frontend/.env.sample +++ b/userfront/.env.sample @@ -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 diff --git a/frontend/.gitignore b/userfront/.gitignore similarity index 100% rename from frontend/.gitignore rename to userfront/.gitignore diff --git a/frontend/.metadata b/userfront/.metadata similarity index 100% rename from frontend/.metadata rename to userfront/.metadata diff --git a/frontend/Dockerfile b/userfront/Dockerfile similarity index 100% rename from frontend/Dockerfile rename to userfront/Dockerfile diff --git a/frontend/analysis_options.yaml b/userfront/analysis_options.yaml similarity index 100% rename from frontend/analysis_options.yaml rename to userfront/analysis_options.yaml diff --git a/frontend/android/.gitignore b/userfront/android/.gitignore similarity index 100% rename from frontend/android/.gitignore rename to userfront/android/.gitignore diff --git a/frontend/android/app/build.gradle.kts b/userfront/android/app/build.gradle.kts similarity index 93% rename from frontend/android/app/build.gradle.kts rename to userfront/android/app/build.gradle.kts index 2b8fbcee..d674ccb1 100644 --- a/frontend/android/app/build.gradle.kts +++ b/userfront/android/app/build.gradle.kts @@ -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 diff --git a/frontend/android/app/src/debug/AndroidManifest.xml b/userfront/android/app/src/debug/AndroidManifest.xml similarity index 100% rename from frontend/android/app/src/debug/AndroidManifest.xml rename to userfront/android/app/src/debug/AndroidManifest.xml diff --git a/frontend/android/app/src/main/AndroidManifest.xml b/userfront/android/app/src/main/AndroidManifest.xml similarity index 98% rename from frontend/android/app/src/main/AndroidManifest.xml rename to userfront/android/app/src/main/AndroidManifest.xml index e8d342e9..a202ec4c 100644 --- a/frontend/android/app/src/main/AndroidManifest.xml +++ b/userfront/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - frontend + userfront CFBundlePackageType APPL CFBundleShortVersionString diff --git a/frontend/ios/Runner/Runner-Bridging-Header.h b/userfront/ios/Runner/Runner-Bridging-Header.h similarity index 100% rename from frontend/ios/Runner/Runner-Bridging-Header.h rename to userfront/ios/Runner/Runner-Bridging-Header.h diff --git a/frontend/ios/RunnerTests/RunnerTests.swift b/userfront/ios/RunnerTests/RunnerTests.swift similarity index 100% rename from frontend/ios/RunnerTests/RunnerTests.swift rename to userfront/ios/RunnerTests/RunnerTests.swift diff --git a/frontend/lib/core/notifiers/auth_notifier.dart b/userfront/lib/core/notifiers/auth_notifier.dart similarity index 100% rename from frontend/lib/core/notifiers/auth_notifier.dart rename to userfront/lib/core/notifiers/auth_notifier.dart diff --git a/frontend/lib/core/services/audit_service.dart b/userfront/lib/core/services/audit_service.dart similarity index 79% rename from frontend/lib/core/services/audit_service.dart rename to userfront/lib/core/services/audit_service.dart index 35480d79..082d6a6d 100644 --- a/frontend/lib/core/services/audit_service.dart +++ b/userfront/lib/core/services/audit_service.dart @@ -3,7 +3,14 @@ import 'package:http/http.dart' as http; import 'package:flutter_dotenv/flutter_dotenv.dart'; class AuditService { - static String get _baseUrl => dotenv.env['BACKEND_URL'] ?? 'https://sso.hmac.kr'; + static String _envOrDefault(String key, String fallback) { + if (!dotenv.isInitialized) { + return fallback; + } + return dotenv.env[key] ?? fallback; + } + + static String get _baseUrl => _envOrDefault('BACKEND_URL', 'https://sso.hmac.kr'); static Future logEvent({ required String userId, diff --git a/frontend/lib/core/services/auth_proxy_service.dart b/userfront/lib/core/services/auth_proxy_service.dart similarity index 97% rename from frontend/lib/core/services/auth_proxy_service.dart rename to userfront/lib/core/services/auth_proxy_service.dart index f17832f8..ced64e33 100644 --- a/frontend/lib/core/services/auth_proxy_service.dart +++ b/userfront/lib/core/services/auth_proxy_service.dart @@ -3,7 +3,14 @@ import 'package:http/http.dart' as http; import 'package:flutter_dotenv/flutter_dotenv.dart'; class AuthProxyService { - static String get _baseUrl => dotenv.env['BACKEND_URL'] ?? 'https://sso.hmac.kr'; + static String _envOrDefault(String key, String fallback) { + if (!dotenv.isInitialized) { + return fallback; + } + return dotenv.env[key] ?? fallback; + } + + static String get _baseUrl => _envOrDefault('BACKEND_URL', 'https://sso.hmac.kr'); static Future> fetchPasswordPolicy() async { final url = Uri.parse('$_baseUrl/api/v1/auth/password/policy'); @@ -17,11 +24,11 @@ class AuthProxyService { static Future> initEnchantedLink(String loginId, {String? method}) async { final url = Uri.parse('$_baseUrl/api/v1/auth/enchanted-link/init'); - final frontendUrl = dotenv.env['FRONTEND_URL'] ?? 'http://sso.hmac.kr'; + final userfrontUrl = _envOrDefault('USERFRONT_URL', 'http://sso.hmac.kr'); final body = { 'loginId': loginId, - 'uri': frontendUrl, + 'uri': userfrontUrl, }; if (method != null) { body['method'] = method; diff --git a/frontend/lib/core/services/logger_service.dart b/userfront/lib/core/services/logger_service.dart similarity index 98% rename from frontend/lib/core/services/logger_service.dart rename to userfront/lib/core/services/logger_service.dart index b9dd32a7..7f8df236 100644 --- a/frontend/lib/core/services/logger_service.dart +++ b/userfront/lib/core/services/logger_service.dart @@ -62,7 +62,7 @@ class LoggerService { 'time': record.time.toUtc().toIso8601String(), // Use UTC for consistency 'level': record.level.name, 'msg': record.message, - 'svc': 'baron-frontend', + 'svc': 'baron-userfront', if (record.error != null) 'error': record.error.toString(), if (record.stackTrace != null) 'stack': record.stackTrace.toString(), }; diff --git a/frontend/lib/core/services/web_auth_integration.dart b/userfront/lib/core/services/web_auth_integration.dart similarity index 100% rename from frontend/lib/core/services/web_auth_integration.dart rename to userfront/lib/core/services/web_auth_integration.dart diff --git a/frontend/lib/core/services/web_auth_integration_stub.dart b/userfront/lib/core/services/web_auth_integration_stub.dart similarity index 100% rename from frontend/lib/core/services/web_auth_integration_stub.dart rename to userfront/lib/core/services/web_auth_integration_stub.dart diff --git a/frontend/lib/core/services/web_auth_integration_web.dart b/userfront/lib/core/services/web_auth_integration_web.dart similarity index 100% rename from frontend/lib/core/services/web_auth_integration_web.dart rename to userfront/lib/core/services/web_auth_integration_web.dart diff --git a/frontend/lib/features/admin/presentation/create_user_screen.dart b/userfront/lib/features/admin/presentation/create_user_screen.dart similarity index 100% rename from frontend/lib/features/admin/presentation/create_user_screen.dart rename to userfront/lib/features/admin/presentation/create_user_screen.dart diff --git a/frontend/lib/features/admin/presentation/user_management_screen.dart b/userfront/lib/features/admin/presentation/user_management_screen.dart similarity index 100% rename from frontend/lib/features/admin/presentation/user_management_screen.dart rename to userfront/lib/features/admin/presentation/user_management_screen.dart diff --git a/frontend/lib/features/auth/presentation/approve_qr_screen.dart b/userfront/lib/features/auth/presentation/approve_qr_screen.dart similarity index 100% rename from frontend/lib/features/auth/presentation/approve_qr_screen.dart rename to userfront/lib/features/auth/presentation/approve_qr_screen.dart diff --git a/frontend/lib/features/auth/presentation/forgot_password_screen.dart b/userfront/lib/features/auth/presentation/forgot_password_screen.dart similarity index 100% rename from frontend/lib/features/auth/presentation/forgot_password_screen.dart rename to userfront/lib/features/auth/presentation/forgot_password_screen.dart diff --git a/frontend/lib/features/auth/presentation/login_screen.dart b/userfront/lib/features/auth/presentation/login_screen.dart similarity index 100% rename from frontend/lib/features/auth/presentation/login_screen.dart rename to userfront/lib/features/auth/presentation/login_screen.dart diff --git a/frontend/lib/features/auth/presentation/login_success_screen.dart b/userfront/lib/features/auth/presentation/login_success_screen.dart similarity index 100% rename from frontend/lib/features/auth/presentation/login_success_screen.dart rename to userfront/lib/features/auth/presentation/login_success_screen.dart diff --git a/frontend/lib/features/auth/presentation/qr_scan_screen.dart b/userfront/lib/features/auth/presentation/qr_scan_screen.dart similarity index 100% rename from frontend/lib/features/auth/presentation/qr_scan_screen.dart rename to userfront/lib/features/auth/presentation/qr_scan_screen.dart diff --git a/frontend/lib/features/auth/presentation/reset_password_screen.dart b/userfront/lib/features/auth/presentation/reset_password_screen.dart similarity index 100% rename from frontend/lib/features/auth/presentation/reset_password_screen.dart rename to userfront/lib/features/auth/presentation/reset_password_screen.dart diff --git a/frontend/lib/features/auth/presentation/signup_screen.dart b/userfront/lib/features/auth/presentation/signup_screen.dart similarity index 100% rename from frontend/lib/features/auth/presentation/signup_screen.dart rename to userfront/lib/features/auth/presentation/signup_screen.dart diff --git a/frontend/lib/features/dashboard/presentation/dashboard_screen.dart b/userfront/lib/features/dashboard/presentation/dashboard_screen.dart similarity index 100% rename from frontend/lib/features/dashboard/presentation/dashboard_screen.dart rename to userfront/lib/features/dashboard/presentation/dashboard_screen.dart diff --git a/frontend/lib/features/profile/data/models/user_profile_model.dart b/userfront/lib/features/profile/data/models/user_profile_model.dart similarity index 100% rename from frontend/lib/features/profile/data/models/user_profile_model.dart rename to userfront/lib/features/profile/data/models/user_profile_model.dart diff --git a/frontend/lib/features/profile/data/repositories/profile_repository.dart b/userfront/lib/features/profile/data/repositories/profile_repository.dart similarity index 91% rename from frontend/lib/features/profile/data/repositories/profile_repository.dart rename to userfront/lib/features/profile/data/repositories/profile_repository.dart index 911f11d7..005df473 100644 --- a/frontend/lib/features/profile/data/repositories/profile_repository.dart +++ b/userfront/lib/features/profile/data/repositories/profile_repository.dart @@ -5,7 +5,14 @@ import '../models/user_profile_model.dart'; import 'package:descope/descope.dart'; class ProfileRepository { - static String get _baseUrl => dotenv.env['BACKEND_URL'] ?? 'https://sso.hmac.kr'; + static String _envOrDefault(String key, String fallback) { + if (!dotenv.isInitialized) { + return fallback; + } + return dotenv.env[key] ?? fallback; + } + + static String get _baseUrl => _envOrDefault('BACKEND_URL', 'https://sso.hmac.kr'); // Helper to get session token static Future _getToken() async { diff --git a/frontend/lib/features/profile/domain/notifiers/profile_notifier.dart b/userfront/lib/features/profile/domain/notifiers/profile_notifier.dart similarity index 100% rename from frontend/lib/features/profile/domain/notifiers/profile_notifier.dart rename to userfront/lib/features/profile/domain/notifiers/profile_notifier.dart diff --git a/frontend/lib/features/profile/presentation/pages/edit_profile_page.dart b/userfront/lib/features/profile/presentation/pages/edit_profile_page.dart similarity index 100% rename from frontend/lib/features/profile/presentation/pages/edit_profile_page.dart rename to userfront/lib/features/profile/presentation/pages/edit_profile_page.dart diff --git a/frontend/lib/features/profile/presentation/pages/profile_page.dart b/userfront/lib/features/profile/presentation/pages/profile_page.dart similarity index 100% rename from frontend/lib/features/profile/presentation/pages/profile_page.dart rename to userfront/lib/features/profile/presentation/pages/profile_page.dart diff --git a/frontend/lib/features/profile/presentation/widgets/profile_info_row.dart b/userfront/lib/features/profile/presentation/widgets/profile_info_row.dart similarity index 100% rename from frontend/lib/features/profile/presentation/widgets/profile_info_row.dart rename to userfront/lib/features/profile/presentation/widgets/profile_info_row.dart diff --git a/frontend/lib/main.dart b/userfront/lib/main.dart similarity index 92% rename from frontend/lib/main.dart rename to userfront/lib/main.dart index 09c8e693..8aa98188 100644 --- a/frontend/lib/main.dart +++ b/userfront/lib/main.dart @@ -27,9 +27,6 @@ void main() async { WidgetsFlutterBinding.ensureInitialized(); usePathUrlStrategy(); - // 0. Initialize Logger - LoggerService.init(); - // 1. Global Error Handling FlutterError.onError = (details) { FlutterError.presentError(details); @@ -44,15 +41,21 @@ void main() async { return true; }; - // Load Env (Handling error if missing for now) + // .env가 없더라도 초기화 상태를 보장하도록 optional 로딩 try { - await dotenv.load(fileName: ".env"); + await dotenv.load(fileName: ".env", isOptional: true); } catch (e) { - _log.warning("Warning: .env file not found."); + _log.warning("Warning: .env file load failed: $e"); } - // Initialize Descope - final projectId = dotenv.env['DESCOPE_PROJECT_ID'] ?? 'your-project-id'; + // 0. Initialize Logger + LoggerService.init(); + + // Initialize Descope (프로젝트 ID가 없으면 경고만 남기고 진행) + final projectId = dotenv.maybeGet('DESCOPE_PROJECT_ID') ?? ''; + if (projectId.isEmpty || projectId == 'your-project-id') { + _log.severe("DESCOPE_PROJECT_ID is missing. Descope may not work correctly."); + } Descope.setup(projectId); // Load saved session if any @@ -208,4 +211,4 @@ class BaronSSOApp extends StatelessWidget { routerConfig: _router, ); } -} \ No newline at end of file +} diff --git a/frontend/nginx.conf b/userfront/nginx.conf similarity index 97% rename from frontend/nginx.conf rename to userfront/nginx.conf index 8d160cb8..fd8da73a 100644 --- a/frontend/nginx.conf +++ b/userfront/nginx.conf @@ -9,7 +9,7 @@ log_format json_combined escape=json '"time":"$time_custom",' '"level":"INFO",' '"msg":"http_access",' - '"svc":"baron-frontend",' + '"svc":"baron-userfront",' '"status":$status,' '"method":"$request_method",' '"path":"$request_uri",' diff --git a/frontend/pubspec.lock b/userfront/pubspec.lock similarity index 99% rename from frontend/pubspec.lock rename to userfront/pubspec.lock index 3d5a88ed..5ee563c5 100644 --- a/frontend/pubspec.lock +++ b/userfront/pubspec.lock @@ -184,10 +184,10 @@ packages: description: flutter source: sdk version: "0.0.0" - frontend_server_client: + userfront_server_client: dependency: transitive description: - name: frontend_server_client + name: userfront_server_client sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted diff --git a/userfront/pubspec.yaml b/userfront/pubspec.yaml new file mode 100644 index 00000000..e468faf4 --- /dev/null +++ b/userfront/pubspec.yaml @@ -0,0 +1,98 @@ +name: app.brsw.kr +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 diff --git a/frontend/test/widget_test.dart b/userfront/test/widget_test.dart similarity index 93% rename from frontend/test/widget_test.dart rename to userfront/test/widget_test.dart index 1ba2b4a1..bef062e6 100644 --- a/frontend/test/widget_test.dart +++ b/userfront/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:frontend/main.dart' show BaronSSOApp; +import 'package:userfront/main.dart' show BaronSSOApp; void main() { testWidgets('BaronSSOApp builds', (WidgetTester tester) async { diff --git a/frontend/web/favicon.png b/userfront/web/favicon.png similarity index 100% rename from frontend/web/favicon.png rename to userfront/web/favicon.png diff --git a/frontend/web/icons/Icon-192.png b/userfront/web/icons/Icon-192.png similarity index 100% rename from frontend/web/icons/Icon-192.png rename to userfront/web/icons/Icon-192.png diff --git a/frontend/web/icons/Icon-512.png b/userfront/web/icons/Icon-512.png similarity index 100% rename from frontend/web/icons/Icon-512.png rename to userfront/web/icons/Icon-512.png diff --git a/frontend/web/icons/Icon-maskable-192.png b/userfront/web/icons/Icon-maskable-192.png similarity index 100% rename from frontend/web/icons/Icon-maskable-192.png rename to userfront/web/icons/Icon-maskable-192.png diff --git a/frontend/web/icons/Icon-maskable-512.png b/userfront/web/icons/Icon-maskable-512.png similarity index 100% rename from frontend/web/icons/Icon-maskable-512.png rename to userfront/web/icons/Icon-maskable-512.png diff --git a/frontend/web/index.html b/userfront/web/index.html similarity index 93% rename from frontend/web/index.html rename to userfront/web/index.html index b82ea397..b1a8f2de 100644 --- a/frontend/web/index.html +++ b/userfront/web/index.html @@ -23,13 +23,13 @@ - + - frontend + userfront diff --git a/frontend/web/manifest.json b/userfront/web/manifest.json similarity index 93% rename from frontend/web/manifest.json rename to userfront/web/manifest.json index 409f4c96..4b543557 100644 --- a/frontend/web/manifest.json +++ b/userfront/web/manifest.json @@ -1,6 +1,6 @@ { - "name": "frontend", - "short_name": "frontend", + "name": "userfront", + "short_name": "userfront", "start_url": ".", "display": "standalone", "background_color": "#0175C2",