Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/web-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: deploy flutter web to github pages

on:
# main branch에 푸쉬가 들어올 경우 실행
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
steps:
# git 기본 세팅
- name: Checkout
uses: actions/checkout@v4

# 플러터 세팅
- name: Setup flutter
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.29.2

# 임의로 .env 파일 생성
- name: Generate .env
run: |
cat <<EOF > .env
SUPABASE_URL=${{ secrets.SUPABASE_URL }}
SUPABASE_ANON_KEY=${{ secrets.SUPABASE_ANON_KEY }}
EOF

# 추가: 의존성 설치
- name: Install dependencies
run: flutter pub get

# Generator 빌드
- name: Run Code Generation
run: flutter pub run build_runner build --delete-conflicting-outputs

# Flutter Test 진행
# => test에서 실패하면 배포가 되지 않도록 설정
- name: Run Tests
run: flutter test

# 플러터 웹 빌드
- name: Build web
run: flutter build web --base-href "/${{ github.event.repository.name }}/"

# 404.html = index.html 복사
# => 강제 url로 라우팅이 404에러를 해결
- name: Copy index.html to 404.html
run: cp build/web/index.html build/web/404.html

# github page 배포
- name: Deploy to github pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.WEB_DEPLOY_KEY }}
publish_dir: ./build/web
18 changes: 9 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
pubspec.lock
package_config.json

# Flutter Web 관련
/web/favicon.png
/web/icons/
/web/splash/
/web/manifest.json
/web/index.html
/web/flutter_service_worker.js
/web/assets/
# Flutter Web 관련 ignore 설정 주석처리
# /web/favicon.png
# /web/icons/
# /web/splash/
# /web/manifest.json
# /web/index.html
# /web/flutter_service_worker.js
# /web/assets/

# Android 관련
**/android/**/gradle-wrapper.jar
Expand Down Expand Up @@ -156,4 +156,4 @@ logs/
devtools_options.yaml

# Firebase
lib/firebase_options.dart
# lib/firebase_options.dart
2 changes: 1 addition & 1 deletion lib/auth/presentation/components/auth_header_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AuthHeaderWidget extends StatelessWidget {
),
child: Center(
child: Image.asset(
'images/mongo_ai_logo.png',
'assets/images/mongo_ai_logo.png',
width: 24,
height: 24,
),
Expand Down
39 changes: 32 additions & 7 deletions lib/auth/presentation/sign_in/screen/sign_in_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ class _SignInScreenState extends State<SignInScreen> {
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: const BorderSide(color: AppColor.primary),
borderSide: const BorderSide(
color: AppColor.primary,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
Expand Down Expand Up @@ -204,7 +206,9 @@ class _SignInScreenState extends State<SignInScreen> {
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: const BorderSide(color: AppColor.primary),
borderSide: const BorderSide(
color: AppColor.primary,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
Expand Down Expand Up @@ -287,7 +291,9 @@ class _SignInScreenState extends State<SignInScreen> {

ElevatedButton(
onPressed: () {
widget.onAction(const SignInAction.onTapGoogleSingIn());
widget.onAction(
const SignInAction.onTapGoogleSingIn(),
);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.white,
Expand All @@ -300,11 +306,28 @@ class _SignInScreenState extends State<SignInScreen> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: SizedBox(width: 40, height: 40, child: Image.asset('images/google_logo.png', width: 40, height: 40,)),
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: SizedBox(
width: 40,
height: 40,
child: Image.asset(
'assets/images/google_logo.png',
width: 40,
height: 40,
),
),
),
const Gap(10),
Text('Sign in with Google', style: AppTextStyle.bodyMedium.copyWith(fontWeight: FontWeight.w500, color: AppColor.black, fontSize: 16))
Text(
'Sign in with Google',
style: AppTextStyle.bodyMedium.copyWith(
fontWeight: FontWeight.w500,
color: AppColor.black,
fontSize: 16,
),
),
],
),
),
Expand All @@ -325,7 +348,9 @@ class _SignInScreenState extends State<SignInScreen> {
),
GestureDetector(
onTap:
() => widget.onAction(const SignInAction.onTapSignUp()),
() => widget.onAction(
const SignInAction.onTapSignUp(),
),
child: Text(
'회원가입',
style: AppTextStyle.captionRegular.copyWith(
Expand Down
64 changes: 33 additions & 31 deletions lib/dashboard/presentation/dashboard_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
super.initState();

WidgetsBinding.instance.addPostFrameCallback((_) {
unawaited(ref.read(dashboardViewModelProvider.notifier).fetchSelectedTeam());
unawaited(
ref.read(dashboardViewModelProvider.notifier).fetchSelectedTeam(),
);
});
}

Expand All @@ -51,7 +53,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
_currentPath = ['최근 항목'];
} else if (selectedIndex == 3) {
_currentPath = ['휴지통'];
} else if(selectedIndex == 4) {
} else if (selectedIndex == 4) {
_currentPath = ['내 정보'];
}

Expand All @@ -74,35 +76,35 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
children: [
PathWidget(path: _currentPath),
const Spacer(),
ElevatedButton(
onPressed: () {
context.go(Routes.myProfile);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.white,
shadowColor: Colors.transparent,
overlayColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
),
child: Row(
children: [
const Icon(
Icons.person,
color: AppColor.deepBlack,
),
const Gap(10),
Text(
dashboard.userProfile.userName,
style: AppTextStyle.bodyMedium.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.black
ElevatedButton(
onPressed: () {
context.go(Routes.myProfile);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.white,
shadowColor: Colors.transparent,
overlayColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
),
],
),
),
child: Row(
children: [
const Icon(
Icons.person,
color: AppColor.deepBlack,
),
const Gap(10),
Text(
dashboard.userProfile.userName,
style: AppTextStyle.bodyMedium.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.black,
),
),
],
),
),
],
),
),
Expand Down Expand Up @@ -166,7 +168,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
height: 40,
child: SelectModeButtonWidget(
onClick: () {
if(dashboard.currentTeamId != null) {
if (dashboard.currentTeamId != null) {
viewModel.toggleSelectMode();
}
},
Expand Down Expand Up @@ -235,7 +237,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
),
child: Center(
child: Image.asset(
'images/mongo_ai_logo.png',
'assets/images/mongo_ai_logo.png',
width: 16,
height: 16,
),
Expand Down
64 changes: 64 additions & 0 deletions lib/firebase_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// File generated by FlutterFire CLI.
// ignore_for_file: type=lint
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;

/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for android - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.iOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for ios - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}

static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyDv6taLhWiRmfLBY7v7h2iZRHABowiB4UU',
appId: '1:108515543625:web:3a816c4fb36a9baaa74d98',
messagingSenderId: '108515543625',
projectId: 'mongo-ai-9d6ac',
authDomain: 'mongo-ai-9d6ac.firebaseapp.com',
storageBucket: 'mongo-ai-9d6ac.firebasestorage.app',
measurementId: 'G-ZB5G231MQH',
);
}
Comment on lines +1 to +64
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Firebase 웹 구성이 완료되었습니다.

FlutterFire CLI로 생성된 Firebase 구성 파일이 적절하게 추가되었습니다. 이 파일은 웹 플랫폼에 대한 Firebase 설정을 올바르게 제공합니다.

하지만 다음 보안 문제에 대해 주의가 필요합니다:

코드에 Firebase API 키가 노출되어 있습니다. 이는 Flutter 웹 애플리케이션에서는 일반적인 패턴이지만, GitHub의 공개 저장소에 API 키가 그대로 노출되는 것은 보안 위험을 초래할 수 있습니다.

Firebase의 웹 API 키는 기본적으로 제한된 권한을 가지고 있으며, Firebase 콘솔에서 앱 제한사항을 설정하여 추가 보호 조치를 취하는 것이 좋습니다:

  1. Firebase 콘솔에서 API 키 제한 설정 (허용된 도메인, IP 주소 등)
  2. 올바른 Firebase 보안 규칙 구성
  3. OAuth 클라이언트 ID 제한 설정

PR 설명에 언급된 Google 로그인 기능이 작동하지 않는 문제는 이 API 키 설정 및 OAuth 클라이언트 구성과 관련이 있을 수 있습니다.

🧰 Tools
🪛 Gitleaks (8.26.0)

56-56: Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches.

(gcp-api-key)

🤖 Prompt for AI Agents
In lib/firebase_options.dart lines 1 to 64, the Firebase API key is exposed in
the code, which poses a security risk if pushed to a public repository. To fix
this, do not hardcode the API key directly in the source file; instead, move
sensitive configuration like the API key to environment variables or secure
storage. Additionally, configure API key restrictions in the Firebase console by
limiting allowed domains and IPs, and ensure proper Firebase security rules and
OAuth client ID restrictions are set up to protect your app and enable Google
login functionality.

1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ flutter:
uses-material-design: true
assets:
- .env
- assets/images/

fonts:
- family: Pretendard
Expand Down
Binary file added web/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/icons/Icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/icons/Icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/icons/Icon-maskable-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/icons/Icon-maskable-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.

The path provided below has to start and end with a slash "/" in order for
it to work correctly.

For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">

<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">

<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="mongoai_web">
<link rel="apple-touch-icon" href="icons/Icon-192.png">

<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>

<title>mongoai_web</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>
Loading