diff --git a/web-app/src/app/screens/Account.tsx b/web-app/src/app/screens/Account.tsx index 5972d05df..c165f2d6a 100644 --- a/web-app/src/app/screens/Account.tsx +++ b/web-app/src/app/screens/Account.tsx @@ -8,32 +8,53 @@ import { Snackbar, } from '@mui/material'; import { Visibility, VisibilityOff, ContentCopy } from '@mui/icons-material'; - +import { useSelector } from 'react-redux'; +import { selectUserProfile } from '../store/selectors'; interface APIAccountState { - apiKey: string; - showApiKey: boolean; + refreshToken: string; + showRefreshToken: boolean; + accessToken: string; + showAccessToken: boolean; } export default function APIAccount(): React.ReactElement { const [values, setValues] = React.useState({ - apiKey: 'Your key is hidden', - showApiKey: false, + refreshToken: 'Your refresh token is hidden', + showRefreshToken: false, + accessToken: 'Your access token is hidden', + showAccessToken: false, }); + const user = useSelector(selectUserProfile); const [openSnackbar, setOpenSnackbar] = React.useState(false); - const handleClickShowApiKey = (): void => { - setValues({ - ...values, - showApiKey: !values.showApiKey, - apiKey: values.showApiKey - ? 'Your key is hidden' - : 'your-api-key-here-12345', - }); + const handleClickShowApiKey = (tokenType: 'access' | 'refresh'): void => { + switch (tokenType) { + case 'access': + setValues({ + ...values, + showAccessToken: !values.showAccessToken, + accessToken: values.showAccessToken + ? 'Your access token is hidden' + : user?.accessToken ?? 'Your access token is unavailable', + }); + break; + case 'refresh': + setValues({ + ...values, + showRefreshToken: !values.showRefreshToken, + refreshToken: values.showRefreshToken + ? 'Your refresh token is hidden' + : user?.refreshToken ?? 'Your refresh token is unavailable', + }); + break; + default: + break; + } }; - const handleCopyToClipboard = (): void => { + const handleCopyToClipboard = (token: string): void => { navigator.clipboard - .writeText('your-api-key-here-12345') + .writeText(token) .then(() => { setOpenSnackbar(true); }) @@ -77,10 +98,9 @@ export default function APIAccount(): React.ReactElement { color='primary' sx={{ mt: 2, fontWeight: 'bold' }} > - API Key + Refresh Token - {values.apiKey} + {values.refreshToken} { + handleCopyToClipboard(values.refreshToken); + }} sx={{ display: 'inline-block', verticalAlign: 'middle' }} > { + handleClickShowApiKey('refresh'); + }} + edge='end' + sx={{ display: 'inline-block', verticalAlign: 'middle' }} + > + {values.showRefreshToken ? : } + + + { + setOpenSnackbar(false); + }} + message='Your Refresh Token is copied to your clipboard.' + anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }} + action={ + + + + } + /> + + + Access Token + + + {values.accessToken} + + { + handleCopyToClipboard(values.accessToken); + }} + sx={{ display: 'inline-block', verticalAlign: 'middle' }} + > + + + { + handleClickShowApiKey('access'); + }} edge='end' sx={{ display: 'inline-block', verticalAlign: 'middle' }} > - {values.showApiKey ? : } + {values.showAccessToken ? : } { setOpenSnackbar(false); }} - message='Your API key is copied to your clipboard.' + message='Your Access Token is copied to your clipboard.' anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }} action={ diff --git a/web-app/src/app/services/profile-service.ts b/web-app/src/app/services/profile-service.ts index 1bd5a92ec..69c64a3ad 100644 --- a/web-app/src/app/services/profile-service.ts +++ b/web-app/src/app/services/profile-service.ts @@ -21,16 +21,22 @@ export const sendEmailVerification = async (): Promise => { /** * Return the current user or null if the user is not logged in. */ -export const getUserFromSession = (): User | null => { +export const getUserFromSession = async (): Promise => { const currentUser = app.auth().currentUser; if (currentUser === null) { return null; } + const idTokenResult = await currentUser.getIdTokenResult(true); + const refreshToken = currentUser.refreshToken; + const accessToken = idTokenResult.token; + // const expiresIn = idTokenResult.expirationTime; return { fullname: currentUser?.displayName ?? undefined, email: currentUser?.email ?? '', // Organization cannot be retrieved from the current user organization: undefined, + refreshToken, + accessToken, }; }; diff --git a/web-app/src/app/store/saga/auth-saga.ts b/web-app/src/app/store/saga/auth-saga.ts index 5a7413f81..8a52ebc7e 100644 --- a/web-app/src/app/store/saga/auth-saga.ts +++ b/web-app/src/app/store/saga/auth-saga.ts @@ -80,11 +80,11 @@ function* signUpSaga({ }>): Generator { try { yield app.auth().createUserWithEmailAndPassword(email, password); - const user = getUserFromSession(); + const user = yield call(getUserFromSession); if (user === null) { throw new Error('User not found'); } - yield put(signUpSuccess(user)); + yield put(signUpSuccess(user as User)); navigateTo(redirectScreen); } catch (error) { yield put(signUpFail(getAppError(error))); diff --git a/web-app/src/app/types.ts b/web-app/src/app/types.ts index eeec6927f..98cf0f2df 100644 --- a/web-app/src/app/types.ts +++ b/web-app/src/app/types.ts @@ -13,6 +13,8 @@ export interface User { fullname?: string; email: string; organization?: string; + accessToken?: string; + refreshToken?: string; } export const USER_PROFILE = 'userProfile';