-
Notifications
You must be signed in to change notification settings - Fork 0
[fix] 쿠키 방식에서 js 이벤트 방식으로 변경 #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "46-fix-\uC54C\uB9BC-\uD1A0\uD070-\uB85C\uC9C1-\uBCC0\uACBD"
Changes from all commits
a9dec1c
77cc8be
c226c9d
a9ac420
9b0c338
d5c0aaa
6934332
03df4a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ on: | |
| - development | ||
| - preview | ||
| - production | ||
| - stage | ||
| jobs: | ||
| build: | ||
| runs-on: macos-26 | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,9 @@ | ||||||||||||||||||||||||||||||||||||||
| import { ExpoConfig } from 'expo/config'; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| const APP_ENV = process.env.EXPO_PUBLIC_APP_ENV || 'production'; | ||||||||||||||||||||||||||||||||||||||
| const appName = APP_ENV === 'development' ? 'KONECT D' : 'KONECT'; | ||||||||||||||||||||||||||||||||||||||
| const API_ENV = process.env.EXPO_PUBLIC_API_ENV || APP_ENV; | ||||||||||||||||||||||||||||||||||||||
| const appName = | ||||||||||||||||||||||||||||||||||||||
| APP_ENV === 'development' ? 'KONECT D' : API_ENV === 'development' ? 'KONECT S' : 'KONECT'; | ||||||||||||||||||||||||||||||||||||||
| const packageName = APP_ENV === 'development' ? 'com.bcsdlab.konect.dev' : 'com.bcsdlab.konect'; | ||||||||||||||||||||||||||||||||||||||
| const googleServicesFile = | ||||||||||||||||||||||||||||||||||||||
| APP_ENV === 'development' ? './google-services-debug.json' : './google-services.json'; | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
3
to
9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prevent APP_ENV/API_ENV mismatch from producing a stage‑named app with production identifiers. If Suggested guard to avoid unsafe env combinations const APP_ENV = process.env.EXPO_PUBLIC_APP_ENV || 'production';
const API_ENV = process.env.EXPO_PUBLIC_API_ENV || APP_ENV;
+if (APP_ENV === 'production' && API_ENV === 'development') {
+ throw new Error(
+ 'Invalid env combo: API_ENV=development with APP_ENV=production will use prod bundle IDs/Firebase.'
+ );
+}
const appName =
APP_ENV === 'development' ? 'KONECT D' : API_ENV === 'development' ? 'KONECT S' : 'KONECT';📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
|
|
@@ -20,7 +22,7 @@ const config: ExpoConfig = { | |||||||||||||||||||||||||||||||||||||
| supportsTablet: true, | ||||||||||||||||||||||||||||||||||||||
| usesAppleSignIn: true, | ||||||||||||||||||||||||||||||||||||||
| bundleIdentifier: packageName, | ||||||||||||||||||||||||||||||||||||||
| buildNumber: '1010500', | ||||||||||||||||||||||||||||||||||||||
| buildNumber: '1010604', | ||||||||||||||||||||||||||||||||||||||
| infoPlist: { | ||||||||||||||||||||||||||||||||||||||
| ITSAppUsesNonExemptEncryption: false, | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,8 +4,9 @@ import { AppState } from 'react-native'; | |
| import { getForceUpdate, appVersion, versionToNumber } from '../services/forceupdate'; | ||
| import * as Notifications from 'expo-notifications'; | ||
| import { registerForPushNotificationsAsync, shouldRecheckPermission } from '../services/notifications'; | ||
| import CookieManager from '@react-native-cookies/cookies'; | ||
| import { storePushToken } from '../utils/pushTokenStore'; | ||
| import { storePushToken, initPushTokenStore, getStoredToken } from '../utils/pushTokenStore'; | ||
| import { getAccessToken } from '../services/nativeAuthStore'; | ||
| import { registerPushToken } from '../services/pushTokenApi'; | ||
|
|
||
| Notifications.setNotificationHandler({ | ||
| handleNotification: async () => ({ | ||
|
|
@@ -16,14 +17,6 @@ Notifications.setNotificationHandler({ | |
| }), | ||
| }); | ||
|
|
||
| function addTokenToCookie(token: string) { | ||
| CookieManager.set('https://agit.gg', { | ||
| name: 'EXPO_PUSH_TOKEN', | ||
| value: token, | ||
| domain: '.agit.gg', | ||
| path: '/', | ||
| }); | ||
| } | ||
|
|
||
| export default function RootLayout() { | ||
| const { replace } = useRouter(); | ||
|
|
@@ -34,11 +27,28 @@ export default function RootLayout() { | |
| }, []); | ||
|
|
||
| useEffect(() => { | ||
| const handleToken = (token?: string) => { | ||
| initPushTokenStore(); | ||
| }, []); | ||
|
|
||
| useEffect(() => { | ||
| let tokenObtained = false; | ||
| let permissionDenied = false; | ||
|
|
||
| const handleToken = async (token?: string) => { | ||
| if (token) { | ||
| addTokenToCookie(token); | ||
| storePushToken(token); | ||
| tokenObtained = true; | ||
| permissionDenied = false; | ||
| await storePushToken(token); | ||
| console.log('Expo Push Token:', token); | ||
|
|
||
| const accessToken = await getAccessToken(); | ||
| if (accessToken) { | ||
| registerPushToken(token).catch((e) => | ||
| console.error('자동 푸시 토큰 등록 실패:', e) | ||
| ); | ||
| } | ||
| } else { | ||
| permissionDenied = true; | ||
| } | ||
| }; | ||
|
|
||
|
|
@@ -47,7 +57,10 @@ export default function RootLayout() { | |
| .catch((error: any) => console.error(error)); | ||
|
|
||
| const subscription = AppState.addEventListener('change', (nextAppState) => { | ||
| if (nextAppState === 'active' && shouldRecheckPermission()) { | ||
| if (nextAppState !== 'active') return; | ||
|
|
||
| const fromSettings = shouldRecheckPermission(); | ||
| if (fromSettings || (!tokenObtained && !permissionDenied)) { | ||
| registerForPushNotificationsAsync() | ||
|
Comment on lines
+62
to
64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid clearing Suggested fix- const fromSettings = shouldRecheckPermission();
- if (nextAppState === 'active' && (fromSettings || (!tokenObtained && !permissionDenied))) {
- registerForPushNotificationsAsync()
- .then(handleToken)
- .catch((error: any) => console.error(error));
- }
+ if (nextAppState === 'active') {
+ const fromSettings = shouldRecheckPermission();
+ if (fromSettings || (!tokenObtained && !permissionDenied)) {
+ registerForPushNotificationsAsync()
+ .then(handleToken)
+ .catch((error: any) => console.error(error));
+ }
+ }🤖 Prompt for AI Agents |
||
| .then(handleToken) | ||
| .catch((error: any) => console.error(error)); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,15 +10,19 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AppStateStatus, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from 'react-native'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Slot, useLocalSearchParams } from 'expo-router'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { WebView } from 'react-native-webview'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { WebView, WebViewMessageEvent } from 'react-native-webview'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { SafeAreaView } from 'react-native-safe-area-context'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import CookieManager from '@react-native-cookies/cookies'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { generateUserAgent } from '../../utils/userAgent'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { webUrl } from '../../constants/constants'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { onPushToken } from '../../utils/pushTokenStore'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getStoredToken } from '../../utils/pushTokenStore'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { saveAccessToken, clearAccessToken } from '../../services/nativeAuthStore'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { registerPushToken, unregisterPushToken } from '../../services/pushTokenApi'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ALLOWED_URL_SCHEMES = ['kakaotalk', 'nidlogin']; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ALLOWED_ORIGINS = [new URL(webUrl).origin]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const userAgent = generateUserAgent(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleOnShouldStartLoadWithRequest = ({ url }: ShouldStartLoadRequest) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -42,37 +46,63 @@ const handleOnShouldStartLoadWithRequest = ({ url }: ShouldStartLoadRequest) => | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default function Index() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const webViewRef = useRef<WebView>(null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const canGoBackRef = useRef(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const pageLoadedRef = useRef(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const pendingTokenRef = useRef<string | null>(null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const local = useLocalSearchParams(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const injectPushToken = useCallback((token: string) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const safeToken = JSON.stringify(token); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| webViewRef.current?.injectJavaScript(` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window.dispatchEvent(new MessageEvent('message', { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data: JSON.stringify({ type: 'PUSH_TOKEN', token: ${safeToken} }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleMessage = useCallback(async (event: WebViewMessageEvent) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const origin = event.nativeEvent.url; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!origin || !ALLOWED_ORIGINS.some((allowed) => origin.startsWith(allowed))) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return onPushToken((token) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (pageLoadedRef.current) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| injectPushToken(token); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pendingTokenRef.current = token; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [injectPushToken]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const data = JSON.parse(event.nativeEvent.data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { type } = data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleLoadEnd = useCallback(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pageLoadedRef.current = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (pendingTokenRef.current) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| injectPushToken(pendingTokenRef.current); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pendingTokenRef.current = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (type === 'LOGIN_COMPLETE') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { accessToken } = data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!accessToken) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await saveAccessToken(accessToken); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('LOGIN_COMPLETE: accessToken 저장 완료'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const pushToken = getStoredToken(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (pushToken) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await registerPushToken(pushToken); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('푸시 토큰 백엔드 등록 완료'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| webViewRef.current?.injectJavaScript( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `window.dispatchEvent(new CustomEvent('NOTIFICATION_STATUS', { detail: { registered: true } }));true;` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('푸시 토큰 등록 실패:', e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| webViewRef.current?.injectJavaScript( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `window.dispatchEvent(new CustomEvent('NOTIFICATION_STATUS', { detail: { registered: false } }));true;` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (type === 'TOKEN_REFRESH') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { accessToken } = data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (accessToken) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await saveAccessToken(accessToken); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('TOKEN_REFRESH: accessToken 갱신 완료'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (type === 'LOGOUT') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const pushToken = getStoredToken(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (pushToken) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await unregisterPushToken(pushToken); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('푸시 토큰 백엔드 삭제 완료'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('푸시 토큰 삭제 실패:', e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await clearAccessToken(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('LOGOUT: accessToken 삭제 완료'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // JSON 파싱 실패 등 무시 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [injectPushToken]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+51
to
+105
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -name "[path].tsx" -o -name "*webview*" | grep -i path | head -20Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 53 🏁 Script executed: fd -t f "path\].tsx"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 93 🏁 Script executed: fd -t f "\[path\]\.tsx"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 93 🏁 Script executed: git ls-files | grep -i webviewRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 93 🏁 Script executed: cat -n app/webview/[path].tsx | head -120Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 4852 🏁 Script executed: rg "webUrl|WebView" app/webview/[path].tsx -A 3 -B 3Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 1514 🏁 Script executed: rg "onMessage|event.nativeEvent" app/webview/[path].tsx -B 5 -A 5Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 705 🏁 Script executed: cat -n app/webview/[path].tsx | grep -A 20 "WebView"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 3216 🏁 Script executed: cat app/constants/constants.tsRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 129 🏁 Script executed: web_search
react-native-webview WebViewMessageEvent nativeEvent.url propertyRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 180 🏁 Script executed: fd -type f "constants" app/Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 241 🏁 Script executed: rg "webUrl\s*=" --type ts --type tsx -A 2Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 98 🏁 Script executed: npm list react-native-webview 2>/dev/null || echo "npm unavailable, checking package files"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 168 🏁 Script executed: cat package.json | rg "react-native-webview"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 109 🏁 Script executed: fd "constants" -e ts -e tsxRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 93 🏁 Script executed: find . -name "constants*" -type fRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 13406 🏁 Script executed: rg "export.*webUrl" --type tsRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 188 🏁 Script executed: cat package.json | head -50Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 1624 🏁 Script executed: rg "WebViewMessageEvent\|nativeEvent" --no-filename -A 5 -B 5Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 53 🏁 Script executed: find . -path ./node_modules -prune -o -name "*.ts" -o -name "*.tsx" -exec grep -l "postMessage\|onMessage" {} \;Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 95 🏁 Script executed: cat ./node_modules/.pnpm/react-native-webview*/node_modules/react-native-webview/lib/WebViewTypes.d.ts 2>/dev/null | head -100Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 4257 🏁 Script executed: find ./node_modules -path "*react-native-webview*" -name "*.d.ts" -exec cat {} \; | head -200Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 7357 🏁 Script executed: cat ./node_modules/.pnpm/react-native-webview@13.15.0/node_modules/react-native-webview/lib/WebViewTypes.d.ts | grep -A 20 "WebViewMessage"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 208 🏁 Script executed: find ./node_modules -path "*react-native-webview*13.15*" -name "WebViewTypes.d.ts"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 263 🏁 Script executed: find ./node_modules -path "*react-native-webview*" -name "WebViewTypes.d.ts" 2>/dev/null | head -1 | xargs catRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 43378 🏁 Script executed: ls -la ./node_modules/.pnpm/ | grep react-native-webviewRepository: BCSDLab/KONECT_REACT_NATIVE Length of output: 239 🏁 Script executed: cat ./node_modules/.pnpm/react-native-webview@13.15.0_react-native@0.81.5_@babel+core@7.29.0_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/react-native-webview/lib/WebViewTypes.d.ts | grep -A 10 "interface WebViewMessage"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 338 🏁 Script executed: cat ./node_modules/.pnpm/react-native-webview@13.15.0_react-native@0.81.5_@babel+core@7.29.0_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/react-native-webview/lib/WebViewTypes.d.ts | grep -B 5 "interface WebViewMessage"Repository: BCSDLab/KONECT_REACT_NATIVE Length of output: 250 Validate WebView message origin before handling auth/token actions.
Suggested change const handleMessage = useCallback(async (event: WebViewMessageEvent) => {
try {
+ const trustedOrigin = new URL(webUrl).origin;
+ const messageUrl = event.nativeEvent.url;
+ if (!messageUrl) return;
+ if (new URL(messageUrl).origin !== trustedOrigin) return;
+
const data = JSON.parse(event.nativeEvent.data);
const { type } = data;
+ if (!['LOGIN_COMPLETE', 'TOKEN_REFRESH', 'LOGOUT'].includes(type)) return;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (Platform.OS === 'android') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -121,7 +151,7 @@ export default function Index() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onShouldStartLoadWithRequest={handleOnShouldStartLoadWithRequest} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| originWhitelist={['*']} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| startInLoadingState | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onLoadEnd={handleLoadEnd} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMessage={handleMessage} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </SafeAreaView> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| const APP_ENV = process.env.EXPO_PUBLIC_APP_ENV || 'production'; | ||
| const API_ENV = process.env.EXPO_PUBLIC_API_ENV || APP_ENV; | ||
|
|
||
| export const apiUrl = | ||
| APP_ENV === 'development' ? 'https://api.stage.agit.gg' : 'https://api.agit.gg'; | ||
| export const webUrl = APP_ENV === 'development' ? 'https://stage.agit.gg' : 'https://agit.gg'; | ||
| API_ENV === 'development' ? 'https://api.stage.agit.gg' : 'https://api.agit.gg'; | ||
| export const webUrl = API_ENV === 'development' ? 'https://stage.agit.gg' : 'https://agit.gg'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,16 @@ | |
| "resourceClass": "m-medium" | ||
| } | ||
| }, | ||
| "stage": { | ||
| "distribution": "store", | ||
| "env": { | ||
| "EXPO_PUBLIC_APP_ENV": "production", | ||
| "EXPO_PUBLIC_API_ENV": "development" | ||
| }, | ||
| "ios": { | ||
| "resourceClass": "m-medium" | ||
| } | ||
| }, | ||
|
Comment on lines
+16
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirm
If the intent is to have a dedicated staging environment, consider using a distinct value (e.g., 🔧 Suggested change if a distinct stage env is intended "stage": {
"distribution": "store",
"env": {
- "EXPO_PUBLIC_APP_ENV": "development"
+ "EXPO_PUBLIC_APP_ENV": "stage"
},🤖 Prompt for AI Agents |
||
| "preview": { | ||
| "distribution": "internal", | ||
| "android": { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import * as SecureStore from 'expo-secure-store'; | ||
|
|
||
| const ACCESS_TOKEN_KEY = 'ACCESS_TOKEN'; | ||
|
|
||
| export async function saveAccessToken(token: string): Promise<void> { | ||
| await SecureStore.setItemAsync(ACCESS_TOKEN_KEY, token); | ||
| } | ||
|
|
||
| export async function getAccessToken(): Promise<string | null> { | ||
| return SecureStore.getItemAsync(ACCESS_TOKEN_KEY); | ||
| } | ||
|
|
||
| export async function clearAccessToken(): Promise<void> { | ||
| await SecureStore.deleteItemAsync(ACCESS_TOKEN_KEY); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import { apiUrl } from '../constants/constants'; | ||
| import { getAccessToken } from './nativeAuthStore'; | ||
|
|
||
| const REQUEST_TIMEOUT_MS = 10_000; | ||
|
|
||
| function fetchWithTimeout(url: string, options: RequestInit): Promise<Response> { | ||
| const controller = new AbortController(); | ||
| const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS); | ||
|
|
||
| return fetch(url, { ...options, signal: controller.signal }).finally(() => | ||
| clearTimeout(timeoutId) | ||
| ); | ||
| } | ||
|
|
||
| export async function registerPushToken(pushToken: string): Promise<void> { | ||
| const accessToken = await getAccessToken(); | ||
| if (!accessToken) { | ||
| console.warn('registerPushToken: accessToken 없음, 등록 생략'); | ||
| return; | ||
| } | ||
|
|
||
| const res = await fetchWithTimeout(`${apiUrl}/notifications/tokens`, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| Authorization: `Bearer ${accessToken}`, | ||
| }, | ||
| body: JSON.stringify({ token: pushToken }), | ||
| }); | ||
|
|
||
| if (!res.ok) { | ||
| throw new Error(`registerPushToken failed: ${res.status}`); | ||
| } | ||
| } | ||
|
|
||
| export async function unregisterPushToken(pushToken: string): Promise<void> { | ||
| const accessToken = await getAccessToken(); | ||
| if (!accessToken) { | ||
| console.warn('unregisterPushToken: accessToken 없음, 삭제 생략'); | ||
| return; | ||
| } | ||
|
|
||
| const res = await fetchWithTimeout(`${apiUrl}/notifications/tokens`, { | ||
| method: 'DELETE', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| Authorization: `Bearer ${accessToken}`, | ||
| }, | ||
| body: JSON.stringify({ token: pushToken }), | ||
| }); | ||
|
|
||
| if (!res.ok) { | ||
| throw new Error(`unregisterPushToken failed: ${res.status}`); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 근데 expo 빌드 타입에 stage는 없지 않나요
그래서
으로 만들었습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 추가하셨군요
근데 그냥 preview를 써도 되지 않나요...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
development: 개발자용. developmentClient가 활성화되어 Expo Dev Client로 실행, 별도 패키지명/구글서비스로 분리됨
preview: QA/테스트 내부 배포용. 스토어 제출 없이 APK로 내부 팀에게 배포
stage: TestFlight(iOS) 용도로 특수하게 사용. 앱 자체는 production 빌드이나 API는 개발 서버(API_ENV: development)를 바라봄 → 앱 이름이 "KONECT S"로 표시
production: 실제 스토어 배포용. Android는 AAB(Play Store 업로드 형식), iOS는 App Store Connect 제출용
이렇게 생각하고 만들었습니다
preview는 internal distribution 이라 testflight 업로드가 안된다고 해서 일단 임의로 stage를 만들었는데 이번 테스트에서만 사용될 것 같아 불필요하다면 푸시 알림 해결되면 제거해도 괜찮을것 같아요