diff --git a/.gitignore b/.gitignore index 2510fc5..67772e0 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +certificates \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cfa03e5..a479e26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,8 @@ "@ant-design/cssinjs": "^1.18.1", "@ant-design/icons": "^5.2.6", "@ant-design/nextjs-registry": "^1.0.0", + "@greatsumini/react-facebook-login": "^3.3.3", + "@react-oauth/google": "^0.12.1", "antd": "^5.12.1", "antd-img-crop": "^4.21.0", "axios": "^1.6.5", @@ -19,6 +21,7 @@ "next": "14.0.3", "next-intl": "^3.3.1", "react": "^18", + "react-apple-login": "^1.1.6", "react-dom": "^18", "react-slick": "^0.29.0", "slick-carousel": "^1.8.1", @@ -309,6 +312,14 @@ "tslib": "^2.4.0" } }, + "node_modules/@greatsumini/react-facebook-login": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@greatsumini/react-facebook-login/-/react-facebook-login-3.3.3.tgz", + "integrity": "sha512-Y5D7EncR3iy/X/OfWwjjpM5OW0XV6PCE08RZUV/yhAE413PEBIlML7S6z69BcpUPWO5XzEt7cytHChUdwXO4Dw==", + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -638,6 +649,15 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@react-oauth/google": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.1.tgz", + "integrity": "sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz", @@ -3498,7 +3518,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3784,7 +3803,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -4419,6 +4437,20 @@ "node": ">=0.10.0" } }, + "node_modules/react-apple-login": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/react-apple-login/-/react-apple-login-1.1.6.tgz", + "integrity": "sha512-ySV6ax0aB+ksA7lKzhr4MvsgjwSH068VtdHJXS+7rL380IJnNQNl14SszR31k3UqB8q8C1H1oyjJFGq4MyO6tw==", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "prop-types": "^15.5.4", + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -4452,8 +4484,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-slick": { "version": "0.29.0", @@ -5582,6 +5613,12 @@ "tslib": "^2.4.0" } }, + "@greatsumini/react-facebook-login": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@greatsumini/react-facebook-login/-/react-facebook-login-3.3.3.tgz", + "integrity": "sha512-Y5D7EncR3iy/X/OfWwjjpM5OW0XV6PCE08RZUV/yhAE413PEBIlML7S6z69BcpUPWO5XzEt7cytHChUdwXO4Dw==", + "requires": {} + }, "@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -5772,6 +5809,12 @@ "rc-util": "^5.38.0" } }, + "@react-oauth/google": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.1.tgz", + "integrity": "sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==", + "requires": {} + }, "@rushstack/eslint-patch": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz", @@ -7881,8 +7924,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.13.1", @@ -8079,7 +8121,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -8507,6 +8548,12 @@ "loose-envify": "^1.1.0" } }, + "react-apple-login": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/react-apple-login/-/react-apple-login-1.1.6.tgz", + "integrity": "sha512-ySV6ax0aB+ksA7lKzhr4MvsgjwSH068VtdHJXS+7rL380IJnNQNl14SszR31k3UqB8q8C1H1oyjJFGq4MyO6tw==", + "requires": {} + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -8535,8 +8582,7 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-slick": { "version": "0.29.0", diff --git a/package.json b/package.json index 35d2112..d48b35e 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "@ant-design/cssinjs": "^1.18.1", "@ant-design/icons": "^5.2.6", "@ant-design/nextjs-registry": "^1.0.0", + "@greatsumini/react-facebook-login": "^3.3.3", + "@react-oauth/google": "^0.12.1", "antd": "^5.12.1", "antd-img-crop": "^4.21.0", "axios": "^1.6.5", @@ -20,6 +22,7 @@ "next": "14.0.3", "next-intl": "^3.3.1", "react": "^18", + "react-apple-login": "^1.1.6", "react-dom": "^18", "react-slick": "^0.29.0", "slick-carousel": "^1.8.1", diff --git a/src/app/[locale]/apple-registration/page.tsx b/src/app/[locale]/apple-registration/page.tsx new file mode 100644 index 0000000..70e4564 --- /dev/null +++ b/src/app/[locale]/apple-registration/page.tsx @@ -0,0 +1,40 @@ +'use client' + +import React from 'react'; +import { useEffect, useRef } from 'react'; +import { apiClient } from '../../../lib/apiClient'; + +export default function BbAppleLogIn() { + + const urlParams = new URLSearchParams(location.search); + var code = urlParams.getAll('code')[0]; + const ref = useRef(false); + + var makeRequest = async (c) => { + + if(ref.current) { + return; + } + ref.current = true; + + try { + var result = await apiClient.post('http://192.168.0.106:5090/api/auth/registerexternalappleweb', { + code: c + }); + localStorage.setItem('bbuddy_token_test', result.data.jwtToken); + window.location.href="/"; + } + catch (err) { + /*process*/ + } + + } + + useEffect(() => { + makeRequest(code); + },[code]); + return ( + <> + + ); +}; diff --git a/src/app/[locale]/apple-sign-in/page.tsx b/src/app/[locale]/apple-sign-in/page.tsx new file mode 100644 index 0000000..d5196ec --- /dev/null +++ b/src/app/[locale]/apple-sign-in/page.tsx @@ -0,0 +1,40 @@ +'use client' + +import React from 'react'; +import { useEffect, useRef } from 'react'; +import { apiClient } from '../../../lib/apiClient'; + +export default function BbAppleLogIn() { + + const urlParams = new URLSearchParams(location.search); + var code = urlParams.getAll('code')[0]; + const ref = useRef(false); + + var makeRequest = async (c) => { + + if(ref.current) { + return; + } + ref.current = true; + + try { + var result = await apiClient.post('http://192.168.0.106:5090/api/auth/tryloginexternalappleweb', { + code: c + }); + localStorage.setItem('bbuddy_token_test', result.data.jwtToken); + window.location.href="/"; + } + catch (err) { + /*process*/ + } + + } + + useEffect(() => { + makeRequest(code); + },[code]); + return ( + <> + + ); +}; diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 520e6ae..b6c838d 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -8,6 +8,9 @@ import theme from '../../constants/theme'; import { ALLOWED_LOCALES } from '../../constants/locale'; import { Header, Footer } from '../../components/Page'; +import { GoogleOAuthProvider } from '@react-oauth/google'; +import { SessionProvider } from "next-auth/react" + type LayoutProps = { children: ReactNode; params: { locale: string }; @@ -28,7 +31,8 @@ export default function LocaleLayout({ children, params: { locale } }: LayoutPro return ( - + +
@@ -36,7 +40,8 @@ export default function LocaleLayout({ children, params: { locale } }: LayoutPro
-
+
+
); }; diff --git a/src/components/Modals/authModalContent/EnterContent.tsx b/src/components/Modals/authModalContent/EnterContent.tsx index f414bfa..b9cff81 100644 --- a/src/components/Modals/authModalContent/EnterContent.tsx +++ b/src/components/Modals/authModalContent/EnterContent.tsx @@ -1,4 +1,4 @@ -import React, { FC, useState } from 'react'; +import React, { FC, useState, useEffect } from 'react'; import { Form, FormInstance, notification } from 'antd'; import Image from 'next/image'; import { Social } from '../../../types/social'; @@ -13,6 +13,15 @@ import { FilledButton } from '../../view/FilledButton'; import { OutlinedButton } from '../../view/OutlinedButton'; import { LinkButton } from '../../view/LinkButton'; +import { apiClient } from 'lib/apiClient'; +import { useGoogleLogin } from '@react-oauth/google'; +import { FacebookLoginClient, SuccessResponse } from '@greatsumini/react-facebook-login'; +import FacebookLogin from '@greatsumini/react-facebook-login'; + +import AppleLogin from 'react-apple-login' + +const appId = '581373996992475'; + type EnterProps = { form: FormInstance; updateMode: (mode: 'enter' | 'register' | 'reset' | 'finish') => void; @@ -58,7 +67,51 @@ export const EnterContent: FC = ({ }); }; + + const googleLogin = useGoogleLogin({ + onError: (err) => { + console.log(err); + }, + onSuccess: async (tokenResponse) => { + var result = await apiClient.post('http://192.168.0.106:5090/api/auth/tryloginexternal', { + platform: 0, + provider: 4, + accesstoken: tokenResponse.access_token + }); + localStorage.setItem('bbuddy_token_test', result.data.jwtToken); + console.log(result); + } + }); + + const facebookLogin = async (response: SuccessResponse) => { + console.log('Login Success!', response); + var result = await apiClient.post('http://192.168.0.106:5090/api/auth/tryloginexternal', { + platform: 0, + provider: 1, + accesstoken: response.accessToken + }); + localStorage.setItem('bbuddy_token_test', result.data.jwtToken); + console.log(result); + } + + const authRequest = async () => { + try { + await apiClient.post('/home/userdata'); + console.log('success'); + } + catch(err) { + console.log(err); + } + + } + + const logout = () => { + localStorage.removeItem('bbuddy_token_test'); + } + + const onSocialEnter = (type: Social) => { + const url = SocialConfig[type].oauthUrl; if (!url) return; @@ -154,24 +207,45 @@ export const EnterContent: FC = ({ Forgot password? or - } - onClick={() => onSocialEnter(Social.FACEBOOK)} - > - Facebook account - - } - onClick={() => onSocialEnter(Social.APPLE)} - > - Apple account - + + + + } - onClick={() => onSocialEnter(Social.GOOGLE)} + onClick={() => googleLogin()} > Google account + + authRequest()} + > + Test Request + + + logout()} + > + Log Out + + + ); }; diff --git a/src/components/Modals/authModalContent/RegisterContent.tsx b/src/components/Modals/authModalContent/RegisterContent.tsx index dbd8ed0..df2375d 100644 --- a/src/components/Modals/authModalContent/RegisterContent.tsx +++ b/src/components/Modals/authModalContent/RegisterContent.tsx @@ -12,6 +12,15 @@ import { CustomInputPassword } from '../../view/CustomInputPassword'; import { FilledButton } from '../../view/FilledButton'; import { OutlinedButton } from '../../view/OutlinedButton'; +import { apiClient } from 'lib/apiClient'; +import { useGoogleLogin } from '@react-oauth/google'; +import { FacebookLoginClient, SuccessResponse } from '@greatsumini/react-facebook-login'; +import FacebookLogin from '@greatsumini/react-facebook-login'; + +import AppleLogin from 'react-apple-login'; + +const appId = '581373996992475'; + type RegisterProps = { form: FormInstance; locale: string; @@ -30,6 +39,17 @@ export const RegisterContent: FC = ({ const [isLoading, setIsLoading] = useState(false); const { openOauthWindow } = useOauthWindow(); + const facebookLogin = async (response: SuccessResponse) => { + console.log('Login Success!', response); + var result = await apiClient.post('http://192.168.0.106:5090/api/auth/registerexternal', { + platform: 0, + provider: 1, + accesstoken: response.accessToken + }); + localStorage.setItem('bbuddy_token_test', result.data.jwtToken); + console.log(result); + } + const onRegister = () => { form.validateFields().then(() => { const { login, password } = form.getFieldsValue(); @@ -63,6 +83,22 @@ export const RegisterContent: FC = ({ }); }; + const googleLogin = useGoogleLogin({ + onError: (err) => { + console.log(err); + }, + onSuccess: async (tokenResponse) => { + var result = await apiClient.post('http://192.168.0.106:5090/api/auth/registerexternal', { + platform: 0, + provider: 4, + accesstoken: tokenResponse.access_token + }); + localStorage.setItem('bbuddy_token_test', result.data.jwtToken); + console.log(result); + } + }); + + const onSocialRegister = (type: Social) => { const url = SocialConfig[type].oauthUrl; @@ -176,21 +212,30 @@ export const RegisterContent: FC = ({ updateMode('enter')}>Enter or - } - onClick={() => onSocialRegister(Social.FACEBOOK)} - > - Facebook account - - } - onClick={() => onSocialRegister(Social.APPLE)} - > - Apple account - + + + + } - onClick={() => onSocialRegister(Social.GOOGLE)} + onClick={() => googleLogin()} > Google account diff --git a/src/lib/apiClient.ts b/src/lib/apiClient.ts index f6beada..8b7008a 100644 --- a/src/lib/apiClient.ts +++ b/src/lib/apiClient.ts @@ -17,6 +17,27 @@ export const onSuccessRequestCallback = (config: InternalAxiosRequestConfig) => return newConfig; }; +export const onSuccessRequestJwtCallback = (config: InternalAxiosRequestConfig) => { + const newConfig = { ...config }; + + if (typeof window !== 'undefined') { + var jwt = localStorage.getItem('bbuddy_token_test'); + + if(jwt) { + newConfig.headers.set('Authorization', `Bearer ${jwt}`); + } + } + return newConfig; +}; + +export const onSuccessResponseJwtCallback = (response: AxiosResponse) => { + var header = response.headers['x-new-token']; + if(header) { + localStorage.setItem('bbuddy_token_test', header); + } + return response; +}; + export const onSuccessResponseCallback = (response: AxiosResponse) => response; export const onErrorResponseCallback = (error: any) => Promise.reject(error); @@ -31,3 +52,6 @@ apiClient.interceptors.response.use( onSuccessResponseCallback, onErrorResponseCallback ); + +apiClient.interceptors.response.use(onSuccessResponseJwtCallback); +apiClient.interceptors.request.use(onSuccessRequestJwtCallback);