diff --git a/.env.example b/.env.example index 1190c35..f007afc 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ -GOOGLE_API_KEY = secret -GOOGLE_CLIENT_ID = secret +MICROSOFT_API_KEY = secret +MICROSOFT_CLIENT_ID = secret AUTH_HEADER = secret URL_ORIGIN = lara.exampleCompany diff --git a/.github/workflows/reusable-build-job.yml b/.github/workflows/reusable-build-job.yml index 09c9136..8307fa4 100644 --- a/.github/workflows/reusable-build-job.yml +++ b/.github/workflows/reusable-build-job.yml @@ -25,7 +25,7 @@ jobs: DEBUG: ${{ inputs.debug }} MODE: ${{ inputs.mode }} AUTH_HEADER: ${{ secrets.AUTH_HEADER }} - GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + MICROSOFT_TENANT_ID: ${{ secrets.MICROSOFT_TENANT_ID }} SUPPORT_MAIL: ${{ secrets.SUPPORT_MAIL }} URL_ORIGIN: ${{ secrets.URL_ORIGIN }} COMPANY_ABBREVIATION: ${{ secrets.COMPANY_ABBREVIATION }} @@ -55,6 +55,18 @@ jobs: if: env.ENVIRONMENT_NAME == 'staging' run: | echo "BACKEND_URL=${{ secrets.STAGING_BE_URL }}" >> $GITHUB_ENV + + ############## + # Set MICROSOFT CLIENT_ID env variable this way, so not all variables have to be passed to the reusable workflow + - name: Set production MICROSOFT CLIENT_ID + if: env.ENVIRONMENT_NAME == 'production' + run: | + echo "MICROSOFT_CLIENT_ID=${{ secrets.PROD_MICROSOFT_CLIENT_ID }}" >> $GITHUB_ENV + - name: Set staging MICROSOFT CLIENT_ID + if: env.ENVIRONMENT_NAME == 'staging' + run: | + echo "MICROSOFT_CLIENT_ID=${{ secrets.STAGING_MICROSOFT_CLIENT_ID }}" >> $GITHUB_ENV + ############## - name: Compile and build run: yarn clean && yarn compile && yarn build diff --git a/.github/workflows/reusable-deploy-job.yml b/.github/workflows/reusable-deploy-job.yml index cafe368..4a8eb96 100644 --- a/.github/workflows/reusable-deploy-job.yml +++ b/.github/workflows/reusable-deploy-job.yml @@ -29,8 +29,7 @@ jobs: AUTH_HEADER: ${{ secrets.AUTH_HEADER }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + MICROSOFT_TENANT_ID: ${{ secrets.MICROSOFT_TENANT_ID }} LARA_SECRET: ${{ secrets.LARA_SECRET }} SES_EMAIL: ${{ secrets.SES_EMAIL }} SUPPORT_MAIL: ${{ secrets.SUPPORT_MAIL }} @@ -77,6 +76,17 @@ jobs: echo "FRONTEND_URL=${{ secrets.STAGING_FE_URL }}" >> $GITHUB_ENV echo "BACKEND_URL=${{ secrets.STAGING_BE_URL }}" >> $GITHUB_ENV + ############## + # Set MICROSOFT CLIENT_ID env variable this way, so not all variables have to be passed to the reusable workflow + - name: Set production MICROSOFT CLIENT_ID + if: env.ENVIRONMENT_NAME == 'production' + run: | + echo "MICROSOFT_CLIENT_ID=${{ secrets.PROD_MICROSOFT_CLIENT_ID }}" >> $GITHUB_ENV + - name: Set staging MICROSOFT CLIENT_ID + if: env.ENVIRONMENT_NAME == 'staging' + run: | + echo "MICROSOFT_CLIENT_ID=${{ secrets.STAGING_MICROSOFT_CLIENT_ID }}" >> $GITHUB_ENV + - name: Deploy Frontend run: serverless s3sync bucket --bucket ${{ secrets.COMPANY_ABBREVIATION }}-lara-frontend-${{ inputs.target }} diff --git a/packages/api/schema.gql b/packages/api/schema.gql index f89bc98..26c2a79 100644 --- a/packages/api/schema.gql +++ b/packages/api/schema.gql @@ -140,9 +140,9 @@ type Mutation { deleteEntry(id: ID!): MutateEntryPayload! """ - Login via google. + Login via microsoft """ - login(googleToken: String!): OAuthPayload + login(email: String!): OAuthPayload """ Unclaims a Trainee by the current Trainer diff --git a/packages/api/src/graphql.ts b/packages/api/src/graphql.ts index d30f8fa..8ed54b3 100644 --- a/packages/api/src/graphql.ts +++ b/packages/api/src/graphql.ts @@ -165,7 +165,7 @@ export type GqlMutation = { deleteEntry: GqlMutateEntryPayload; /** Link Alexa account */ linkAlexa?: Maybe; - /** Login via google. */ + /** Login via microsoft */ login?: Maybe; /** Marks User to be deleted */ markUserForDeletion?: Maybe; @@ -256,7 +256,7 @@ export type GqlMutationLinkAlexaArgs = { export type GqlMutationLoginArgs = { - googleToken: Scalars['String']; + email: Scalars['String']; }; @@ -770,7 +770,7 @@ export type GqlMutationResolvers, ParentType, ContextType, RequireFields>; deleteEntry?: Resolver>; linkAlexa?: Resolver, ParentType, ContextType, RequireFields>; - login?: Resolver, ParentType, ContextType, RequireFields>; + login?: Resolver, ParentType, ContextType, RequireFields>; markUserForDeletion?: Resolver, ParentType, ContextType, RequireFields>; unclaimTrainee?: Resolver, ParentType, ContextType, RequireFields>; unlinkAlexa?: Resolver, ParentType, ContextType>; diff --git a/packages/backend/src/google-auth.ts b/packages/backend/src/google-auth.ts deleted file mode 100644 index 804a378..0000000 --- a/packages/backend/src/google-auth.ts +++ /dev/null @@ -1,15 +0,0 @@ -import fetch from 'node-fetch' - -const { GOOGLE_API_KEY } = process.env -if (!GOOGLE_API_KEY) { - throw new Error("Missing Environment Variable: 'GOOGLE_API_KEY'") -} - -export const validateToken = async (token: string): Promise => { - const url = 'https://www.googleapis.com/oauth2/v2/tokeninfo' - const params = `?key=${GOOGLE_API_KEY}&access_token=${token}` - - return fetch(url + params) - .then((res) => res.json()) - .then((json) => json.email) -} diff --git a/packages/backend/src/resolvers/auth.resolver.ts b/packages/backend/src/resolvers/auth.resolver.ts index 2d90b9f..fbed342 100644 --- a/packages/backend/src/resolvers/auth.resolver.ts +++ b/packages/backend/src/resolvers/auth.resolver.ts @@ -4,7 +4,6 @@ import { GraphQLError } from 'graphql' import { GqlResolvers } from '@lara/api' -import { validateToken } from '../google-auth' import { t } from '../i18n' import { isDebug } from '../permissions' import { saveUser, userByEmail, userById } from '../repositories/user.repo' @@ -27,9 +26,7 @@ const createMockUser = async (email: string) => { export const authResolver: GqlResolvers = { Mutation: { - login: async (_parent, { googleToken }) => { - const email = await validateToken(googleToken) - + login: async (_parent, { email }) => { if (!email) { return } diff --git a/packages/backend/src/test/getEnv.js b/packages/backend/src/test/getEnv.js index 7afe322..7146c9d 100644 --- a/packages/backend/src/test/getEnv.js +++ b/packages/backend/src/test/getEnv.js @@ -12,7 +12,8 @@ process.env = { GOOGLE_API_KEY: 'secret', GOOGLE_CLIENT_ID: 'secret', - + MICROSOFT_CLIENT_ID: 'secret', + MICROSOFT_TENANT_ID: 'secret', AUTH_HEADER: 'secret', DEBUG: true, diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 6291a91..a7f16a9 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -15,8 +15,10 @@ }, "dependencies": { "@apollo/client": "^3.2.2", + "@azure/msal-browser": "^2.37.1", + "@azure/msal-react": "^1.5.8", "@lara/components": "^1.0.0", - "@react-oauth/google": "^0.5.1", + "@microsoft/microsoft-graph-client": "^3.0.5", "@rebass/grid": "^6.1.0", "apollo-link-token-refresh": "^0.4.0", "date-fns": "^2.16.1", diff --git a/packages/frontend/src/app.tsx b/packages/frontend/src/app.tsx index f2a37f3..8d60424 100644 --- a/packages/frontend/src/app.tsx +++ b/packages/frontend/src/app.tsx @@ -1,29 +1,31 @@ import React from 'react' import { Router, Switch } from 'react-router-dom' -import { GoogleOAuthProvider } from '@react-oauth/google' - import ApolloProvider from './apollo-provider' import AppHistory from './app-history' -import { GlobalFonts } from './components/fonts' import StatusBar from './components/status-bar' -import { ToastContextProvider } from './context/toast/toast-context-provider' -import { useCurrentUserQuery } from './graphql' -import { AuthenticatedState, AuthenticationContext } from './hooks/use-authentication' -import { SplashPage } from './pages/splash-page' import Routes from './routes' import ThemeProvider from './theme-provider' +import { AuthenticatedState, AuthenticationContext } from './hooks/use-authentication' +import { GlobalFonts } from './components/fonts' +import { MsalProvider } from '@azure/msal-react' +import { msalConfig } from './hooks/ms-auth' +import { PublicClientApplication } from '@azure/msal-browser' +import { SplashPage } from './pages/splash-page' +import { ToastContextProvider } from './context/toast/toast-context-provider' +import { useCurrentUserQuery } from './graphql' +const msalInstance = new PublicClientApplication(msalConfig) export const App: React.FunctionComponent = () => { const [authenticated, setAuthenticated] = React.useState('loading') return ( - - + + - - + + ) } @@ -36,19 +38,20 @@ const InnerApp: React.FunctionComponent = () => { * the redundant api call */ const { data, loading } = useCurrentUserQuery() + const currentUser = data?.currentUser return ( - + {loading && } {!loading && ( - + - {ENVIRONMENT.debug && } + {ENVIRONMENT.debug && } )} diff --git a/packages/frontend/src/components/ms-sign-in-button.tsx b/packages/frontend/src/components/ms-sign-in-button.tsx new file mode 100644 index 0000000..b74b198 --- /dev/null +++ b/packages/frontend/src/components/ms-sign-in-button.tsx @@ -0,0 +1,40 @@ +import React, { ButtonHTMLAttributes } from 'react' +import AppHistory from '../app-history' +import { PrimaryButton } from './button' +import { useMsal } from '@azure/msal-react' +import { loginRequest } from '../hooks/ms-auth' +import { useAuthentication } from '../hooks/use-authentication' +import { useLoginPageLoginMutation } from '../graphql' +import { useIsAuthenticated } from '@azure/msal-react' + +export interface ButtonProps extends ButtonHTMLAttributes { + fullsize?: boolean +} + +export const SignInButton: React.FunctionComponent = () => { + const { instance } = useMsal() + const { login } = useAuthentication() + const [mutate] = useLoginPageLoginMutation() + const isAuthenticated = useIsAuthenticated() + + const handleLogin = async () => { + const loginResponse = await instance.loginPopup(loginRequest) + if (isAuthenticated) { + const email = loginResponse.account?.username + if (email) { + mutate({ variables: { email } }) + .then((response) => { + const { data } = response + if (!data?.login) { + return AppHistory.getInstance().push('/no-user-found') + } + login(data.login) + }) + .catch((err) => { + console.log(err) + }) + } + } + } + return handleLogin()}>Sign in with Microsoft +} diff --git a/packages/frontend/src/frontend.tsx b/packages/frontend/src/frontend.tsx index 0a0dd3a..863e254 100644 --- a/packages/frontend/src/frontend.tsx +++ b/packages/frontend/src/frontend.tsx @@ -3,7 +3,9 @@ import ReactDOM from 'react-dom' import { App } from './app' -ReactDOM.render(, document.getElementById('app')) +if (window.location.hash === '') { + ReactDOM.render(, document.getElementById('app')) +} if (module.hot && ENVIRONMENT.debug) { module.hot.accept() diff --git a/packages/frontend/src/global.d.ts b/packages/frontend/src/global.d.ts index 8df0f2d..e37d11f 100644 --- a/packages/frontend/src/global.d.ts +++ b/packages/frontend/src/global.d.ts @@ -22,9 +22,11 @@ declare module '*.png' declare const ENVIRONMENT: { name: string debug: boolean - googleClientID: string + microsoftClientID: string + microsoftTenantID: string authHeader: string backendUrl: string + frontendUrl: string supportMail: string } diff --git a/packages/frontend/src/graphql/index.tsx b/packages/frontend/src/graphql/index.tsx index 6af9264..b63c515 100644 --- a/packages/frontend/src/graphql/index.tsx +++ b/packages/frontend/src/graphql/index.tsx @@ -164,7 +164,7 @@ export type Mutation = { deleteEntry: MutateEntryPayload; /** Link Alexa account */ linkAlexa?: Maybe; - /** Login via google. */ + /** Login via microsoft */ login?: Maybe; /** Marks User to be deleted */ markUserForDeletion?: Maybe; @@ -255,7 +255,7 @@ export type MutationLinkAlexaArgs = { export type MutationLoginArgs = { - googleToken: Scalars['String']; + email: Scalars['String']; }; @@ -637,7 +637,7 @@ export type LinkAlexaMutationVariables = Exact<{ export type LinkAlexaMutation = { __typename?: 'Mutation', linkAlexa?: { __typename?: 'Admin', id: string, alexaSkillLinked?: boolean | undefined } | { __typename?: 'Trainee', id: string, alexaSkillLinked?: boolean | undefined } | { __typename?: 'Trainer', id: string, alexaSkillLinked?: boolean | undefined } | undefined }; export type LoginPageLoginMutationVariables = Exact<{ - token: Scalars['String']; + email: Scalars['String']; }>; @@ -1136,8 +1136,8 @@ export function useLinkAlexaMutation(baseOptions?: Apollo.MutationHookOptions
  • ; export const LoginPageLoginDocument = gql` - mutation LoginPageLogin($token: String!) { - login(googleToken: $token) { + mutation LoginPageLogin($email: String!) { + login(email: $email) { accessToken refreshToken expiresIn diff --git a/packages/frontend/src/graphql/mutations/login-page-login.gql b/packages/frontend/src/graphql/mutations/login-page-login.gql index f960d88..5963147 100644 --- a/packages/frontend/src/graphql/mutations/login-page-login.gql +++ b/packages/frontend/src/graphql/mutations/login-page-login.gql @@ -1,5 +1,5 @@ -mutation LoginPageLogin($token: String!) { - login(googleToken: $token) { +mutation LoginPageLogin($email: String!) { + login(email: $email) { accessToken refreshToken expiresIn diff --git a/packages/frontend/src/hooks/ms-auth.ts b/packages/frontend/src/hooks/ms-auth.ts new file mode 100644 index 0000000..0397b67 --- /dev/null +++ b/packages/frontend/src/hooks/ms-auth.ts @@ -0,0 +1,15 @@ +export const msalConfig = { + auth: { + clientId: ENVIRONMENT.microsoftClientID ?? '', + authority: 'https://login.microsoftonline.com/' + ENVIRONMENT.microsoftTenantID, + redirectUri: ENVIRONMENT.frontendUrl, + }, + cache: { + cacheLocation: 'sessionStorage', + storeAuthStateInCookie: false, + }, +} + +export const loginRequest = { + scopes: ['User.Read', 'openid', 'profile'], +} diff --git a/packages/frontend/src/pages/login-page.tsx b/packages/frontend/src/pages/login-page.tsx index 8ca05bc..b8c1c36 100644 --- a/packages/frontend/src/pages/login-page.tsx +++ b/packages/frontend/src/pages/login-page.tsx @@ -1,68 +1,23 @@ -import React, { useState } from 'react' -import { TokenResponse, useGoogleLogin } from '@react-oauth/google' - +import React from 'react' import { Container, Paragraph, Spacer, StyledLogo } from '@lara/components' -import AppHistory from '../app-history' -import { useLoginPageLoginMutation } from '../graphql' -import { useAuthentication } from '../hooks/use-authentication' import { Template } from '../templates/template' -import { SplashPage } from './splash-page' -import { PrimaryButton } from '../components/button' +import { SignInButton } from '../components/ms-sign-in-button' const LoginPage: React.FunctionComponent = () => { - const { login } = useAuthentication() - const [mutate] = useLoginPageLoginMutation() - - const [authLoading, setAuthLoading] = useState(false) - - const googleLogin = useGoogleLogin({ - onSuccess: (tokenResponse: TokenResponse) => onLoginSuccess(tokenResponse), - onError: () => onLoginFailure, - }) - - const onLoginSuccess = (tokenResponse: TokenResponse) => { - setAuthLoading(true) - - if (!tokenResponse) { - return - } - - const accessToken = tokenResponse.access_token - - mutate({ variables: { token: accessToken } }).then((response) => { - const { data } = response - - if (!data?.login) { - return AppHistory.getInstance().push('/no-user-found') - } - - login(data.login) - }) - } - - const onLoginFailure = (error: string) => { - console.log('Login error', error) - return - } - - if (authLoading) { - return - } - return ( diff --git a/packages/frontend/src/routes.tsx b/packages/frontend/src/routes.tsx index ee1330f..aec2d04 100644 --- a/packages/frontend/src/routes.tsx +++ b/packages/frontend/src/routes.tsx @@ -43,7 +43,6 @@ const Routes: React.FunctionComponent = ({ currentUser }) => { } else { if (currentUser) { strings.setLanguage(currentUser.language || navigator.language) - // Current user was found // eslint-disable-next-line no-underscore-dangle if (currentUser.type === UserTypeEnum.Trainee && currentUser.__typename === 'Trainee') { diff --git a/packages/frontend/webpack.config.js b/packages/frontend/webpack.config.js index ae12333..e5e8ed7 100644 --- a/packages/frontend/webpack.config.js +++ b/packages/frontend/webpack.config.js @@ -10,12 +10,22 @@ const dotenv = require('dotenv') /* eslint-enable @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment, no-undef */ // eslint-disable-next-line no-undef -const { GOOGLE_CLIENT_ID, DEBUG, AUTH_HEADER, BACKEND_URL, MODE, ENVIRONMENT_NAME, SUPPORT_MAIL } = process.env +const { + MICROSOFT_CLIENT_ID, + MICROSOFT_TENANT_ID, + DEBUG, + AUTH_HEADER, + BACKEND_URL, + FRONTEND_URL, + MODE, + ENVIRONMENT_NAME, + SUPPORT_MAIL, +} = process.env const DEFAULT_ENVIRONMENT = 'development' const DEFAULT_MODE = 'development' -/** @returns { { name: string; mode: string; debug: boolean; googleClientID: string; authHeader: string; backendUrl: string; supportMail: string; } }} */ +/** @returns {{mode: string, authHeader: string, supportMail: string, debug: boolean, microsoftClientID: string, frontendUrl: string, name: (*|string), microsoftTenantID: string, backendUrl: string}}} */ const getEnvironmentConfig = () => { // eslint-disable-next-line no-undef const name = ENVIRONMENT_NAME ?? DEFAULT_ENVIRONMENT @@ -28,10 +38,12 @@ const getEnvironmentConfig = () => { return { name, mode: parsed.MODE, - googleClientID: parsed.GOOGLE_CLIENT_ID, + microsoftClientID: parsed.MICROSOFT_CLIENT_ID, + microsoftTenantID: parsed.MICROSOFT_TENANT_ID, debug: parsed.DEBUG === 'true', authHeader: parsed.AUTH_HEADER, backendUrl: parsed.BACKEND_URL, + frontendUrl: parsed.FRONTEND_URL, supportMail: parsed.SUPPORT_MAIL, } } @@ -41,10 +53,12 @@ const getEnvironmentConfig = () => { return { name, mode: MODE, - googleClientID: GOOGLE_CLIENT_ID, + microsoftClientID: MICROSOFT_CLIENT_ID, + microsoftTenantID: MICROSOFT_TENANT_ID, debug: DEBUG === 'true', authHeader: AUTH_HEADER, backendUrl: BACKEND_URL, + frontendUrl: FRONTEND_URL, supportMail: SUPPORT_MAIL, } } diff --git a/readme.md b/readme.md index 61655cb..8a222a8 100644 --- a/readme.md +++ b/readme.md @@ -99,9 +99,9 @@ The following variables should be added to your cloned version of Lara. - AWS_SECRET_ACCESS_KEY - COMPANY_ABBREVIATION - Shortform of your companies name to create s3-buckets -- GOOGLE_API_KEY -- GOOGLE_CLIENT_ID - - Google keys to use for login +- MICROSOFT_CLIENT_ID +- MICROSOFT_TENANT_ID + - Microsoft keys to use for login - LARA_SECRET - Secret used in creating oauth secrets - OLD_COMPANY_NAME diff --git a/yarn.lock b/yarn.lock index 0ee54ba..d085c96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1048,6 +1048,23 @@ dependencies: tslib "^2.3.1" +"@azure/msal-browser@^2.37.0": + version "2.37.0" + resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-2.37.0.tgz#32d7af74eef53f2692f8a9d6bd6818c78faf4c1b" + integrity sha512-YNGD/W/tw/5wDWlXOfmrVILaxVsorVLxYU2ovmL1PDvxkdudbQRyGk/76l4emqgDAl/kPQeqyivxjOU6w1YfvQ== + dependencies: + "@azure/msal-common" "13.0.0" + +"@azure/msal-common@13.0.0": + version "13.0.0" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-13.0.0.tgz#9c39184903b5d0fd6e643ccc12193fae220e912b" + integrity sha512-GqCOg5H5bouvLij9NFXFkh+asRRxsPBRwnTDsfK7o0KcxYHJbuidKw8/VXpycahGXNxgtuhqtK/n5he+5NhyEA== + +"@azure/msal-react@^1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@azure/msal-react/-/msal-react-1.5.7.tgz#89ae61a557a5b3359d5e6b7280c013e1d6a0e0fe" + integrity sha512-Ub9XPAZCWdBEpTyCGdA1RPdmIAOgLCt344pdL54eCQl3sNVAJQo8DWtRj9UM/qu4tW1dK6HESmznjoBPhuqGdg== + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -1548,6 +1565,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.5": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" + integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.18.10", "@babel/template@^7.3.3": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" @@ -3476,6 +3500,14 @@ npmlog "^6.0.2" write-file-atomic "^4.0.1" +"@microsoft/microsoft-graph-client@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@microsoft/microsoft-graph-client/-/microsoft-graph-client-3.0.4.tgz#6fc409336574521734379f033787af153828bf5d" + integrity sha512-K7GIg/inDukZC2iBhFEvOSoq5ShnlIl8JSRUv8Ksw1iXTtu6kxLmBwF6xY8RZN7CTSJh+5N91aMKu5KeF0/9fA== + dependencies: + "@babel/runtime" "^7.12.5" + tslib "^2.2.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -3881,11 +3913,6 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== -"@react-oauth/google@^0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@react-oauth/google/-/google-0.5.1.tgz#fc5cf33bff5d59583c5b0ed387431350216dd907" - integrity sha512-XCMMke24klAHIVnrZAMibodyjSUsxBOJ+vO5yvRptWC2Vnq02uLUnydjtIdCzCUIAxbvbFbQWZxG0xF0Y8GtHA== - "@rebass/grid@^6.1.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@rebass/grid/-/grid-6.1.0.tgz#17827e13d9b461d86e3e5c6b47393b5aea857370" @@ -4563,9 +4590,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^17", "@types/react@^17.0.4", "@types/react@^17.0.9": - version "17.0.52" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.52.tgz#10d8b907b5c563ac014a541f289ae8eaa9bf2e9b" - integrity sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A== + version "17.0.53" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.53.tgz#10d4d5999b8af3d6bc6a9369d7eb953da82442ab" + integrity sha512-1yIpQR2zdYu1Z/dc1OxC+MA6GR240u3gcnP4l6mvj/PJiVaqHsQPmWttsvHsfnhfPbU2FuGmo0wSITPygjBmsw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -13427,7 +13454,7 @@ promzard@^0.3.0: dependencies: read "1" -prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -13635,14 +13662,6 @@ react-focus-lock@^2.9.0: use-callback-ref "^1.3.0" use-sidecar "^1.1.2" -react-google-login@^5.1.21: - version "5.2.2" - resolved "https://registry.yarnpkg.com/react-google-login/-/react-google-login-5.2.2.tgz#a20b46440c6c1610175ef75baf427118ff0e9859" - integrity sha512-JUngfvaSMcOuV0lFff7+SzJ2qviuNMQdqlsDJkUM145xkGPVIfqWXq9Ui+2Dr6jdJWH5KYdynz9+4CzKjI5u6g== - dependencies: - "@types/react" "*" - prop-types "^15.6.0" - react-hook-form@^7.28.1: version "7.37.0" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.37.0.tgz#4d1738f092d3d8a3ade34ee892d97350b1032b19" @@ -13847,6 +13866,11 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.13.4: version "0.13.10" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee"