diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index cda15218..f148d55b 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -47,6 +47,7 @@ jobs: VITE_GRAASP_BUILDER_HOST: ${{ vars.VITE_GRAASP_BUILDER_HOST }} VITE_SHOW_NOTIFICATIONS: ${{ vars.VITE_SHOW_NOTIFICATIONS }} VITE_RECAPTCHA_SITE_KEY: ${{ secrets.VITE_RECAPTCHA_SITE_KEY }} + VITE_DEFAULT_REDIRECTION_URL: ${{ vars.VITE_DEFAULT_REDIRECTION_URL }} # after the test run completes # store any screenshots diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index 7140a2ef..57d5a8fe 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -34,6 +34,7 @@ jobs: VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }} # VITE_GA_MEASUREMENT_ID: ${{ secrets.VITE_GA_MEASUREMENT_ID }} VITE_SHOW_NOTIFICATIONS: ${{ vars.VITE_SHOW_NOTIFICATIONS }} + VITE_DEFAULT_REDIRECTION_URL: ${{ vars.VITE_DEFAULT_REDIRECTION_URL }} run: yarn build shell: bash @@ -41,7 +42,7 @@ jobs: uses: graasp/graasp-deploy/.github/actions/deploy-s3@v1 # Replace input build-folder or version if needed with: - build-folder: 'build' + build-folder: "build" aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_DEV }} aws-region: ${{ secrets.AWS_REGION_DEV }} aws-s3-bucket-name: ${{ secrets.AWS_S3_BUCKET_NAME_GRAASP_AUTH_DEV }} diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 1f6fdc65..8abe8b01 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -37,6 +37,7 @@ jobs: VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }} VITE_GA_MEASUREMENT_ID: ${{ secrets.VITE_GA_MEASUREMENT_ID }} VITE_SHOW_NOTIFICATIONS: ${{ vars.VITE_SHOW_NOTIFICATIONS }} + VITE_DEFAULT_REDIRECTION_URL: ${{ vars.VITE_DEFAULT_REDIRECTION_URL }} run: yarn build shell: bash @@ -44,7 +45,7 @@ jobs: uses: graasp/graasp-deploy/.github/actions/deploy-s3@v1 # Replace input build-folder or version if needed with: - build-folder: 'build' + build-folder: "build" aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_PROD }} aws-region: ${{ secrets.AWS_REGION_PROD }} aws-s3-bucket-name: ${{ secrets.AWS_S3_BUCKET_NAME_GRAASP_AUTH_PROD }} diff --git a/.github/workflows/deploy-stage.yml b/.github/workflows/deploy-stage.yml index c5d424b0..ea183056 100644 --- a/.github/workflows/deploy-stage.yml +++ b/.github/workflows/deploy-stage.yml @@ -37,6 +37,7 @@ jobs: VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }} # VITE_GA_MEASUREMENT_ID: ${{ secrets.VITE_GA_MEASUREMENT_ID }} VITE_SHOW_NOTIFICATIONS: ${{ vars.VITE_SHOW_NOTIFICATIONS }} + VITE_DEFAULT_REDIRECTION_URL: ${{ vars.VITE_DEFAULT_REDIRECTION_URL }} run: yarn build shell: bash @@ -44,7 +45,7 @@ jobs: uses: graasp/graasp-deploy/.github/actions/deploy-s3@v1 # Replace input build-folder or version if needed with: - build-folder: 'build' + build-folder: "build" aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_STAGE }} aws-region: ${{ secrets.AWS_REGION_STAGE }} aws-s3-bucket-name: ${{ secrets.AWS_S3_BUCKET_NAME_GRAASP_AUTH_STAGE }} diff --git a/README.md b/README.md index eb586a5a..513d812b 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ VITE_GRAASP_LANDING_PAGE_ORIGIN=https://graasp.org VITE_SHOW_NOTIFICATIONS=true VITE_RECAPTCHA_SITE_KEY= +VITE_DEFAULT_REDIRECTION_URL=http://localhost:3111 ``` Generate your recaptcha key from [the reCAPTCHA admin console](https://www.google.com/recaptcha/admin/create) @@ -28,4 +29,5 @@ VITE_GRAASP_LANDING_PAGE_ORIGIN=https://graasp.org VITE_SHOW_NOTIFICATIONS=true VITE_RECAPTCHA_SITE_KEY= +VITE_DEFAULT_REDIRECTION_URL=http://localhost:4444 ``` diff --git a/cypress.config.ts b/cypress.config.ts index d27d6493..ba1acb10 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -14,11 +14,13 @@ export default defineConfig({ ...config, env: { VITE_GRAASP_API_HOST: process.env.VITE_GRAASP_API_HOST, + VITE_DEFAULT_REDIRECTION_URL: + process.env.VITE_DEFAULT_REDIRECTION_URL, }, }; setupEvents(on, newConfig); return newConfig; }, - baseUrl: 'http://localhost:3001', + baseUrl: `http://localhost:${process.env.VITE_PORT ?? '3002'}`, }, }); diff --git a/cypress/e2e/SignIn.cy.ts b/cypress/e2e/SignIn.cy.ts index 56e092a6..51e95ae9 100644 --- a/cypress/e2e/SignIn.cy.ts +++ b/cypress/e2e/SignIn.cy.ts @@ -1,6 +1,9 @@ import { SIGN_IN_PATH } from '../../src/config/paths'; +import { REDIRECTION_CONTENT_CONTAINER_ID } from '../../src/config/selectors'; import { MEMBERS } from '../fixtures/members'; +const DEFAULT_REDIRECTION_URL = Cypress.env('VITE_DEFAULT_REDIRECTION_URL'); + describe('Name and Email Validation', () => { beforeEach(() => { cy.setUpApi(); @@ -14,3 +17,17 @@ describe('Name and Email Validation', () => { cy.signInByMailAndCheck(GRAASP); }); }); + +describe('Already signed in', () => { + beforeEach(() => { + cy.setUpApi({ currentMember: MEMBERS.BOB }); + }); + + it('Should show logged in', () => { + cy.visit('/'); + cy.get(`#${REDIRECTION_CONTENT_CONTAINER_ID}`); + cy.get(`[role="button"]`).click(); + cy.url().should('contain', DEFAULT_REDIRECTION_URL); + cy.get('h1').should('contain', 'Content'); + }); +}); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 67a987da..be25f68d 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -28,6 +28,7 @@ import { import { mockGetCurrentMember, mockGetStatus, + mockRedirection, mockRequestPasswordReset, mockResetPassword, } from './server'; @@ -89,6 +90,7 @@ Cypress.Commands.add( mockGetStatus(); mockRequestPasswordReset(shouldFailRequestPasswordReset); mockResetPassword(shouldFailResetPassword); + mockRedirection(); }, ); diff --git a/cypress/support/server.ts b/cypress/support/server.ts index e703fa6a..aaaa11c3 100644 --- a/cypress/support/server.ts +++ b/cypress/support/server.ts @@ -6,6 +6,7 @@ import { CompleteMember, HttpMethod } from '@graasp/sdk'; const { buildGetCurrentMemberRoute } = API_ROUTES; const API_HOST = Cypress.env('VITE_GRAASP_API_HOST'); +const DEFAULT_REDIRECTION_URL = Cypress.env('VITE_DEFAULT_REDIRECTION_URL'); export const redirectionReply = { headers: { 'content-type': 'application/json' }, @@ -82,3 +83,17 @@ export const mockResetPassword = (shouldThrowServerError = false) => { }, ).as('resetPassword'); }; + +export const mockRedirection = () => { + cy.intercept( + { + method: HttpMethod.Get, + url: DEFAULT_REDIRECTION_URL, + }, + ({ reply }) => + reply({ + body: '

Content

', + headers: { 'content-type': 'text/html' }, + }), + ).as('redirectionContent'); +}; diff --git a/src/components/Redirection.tsx b/src/components/Redirection.tsx index 1e695dde..00b261b6 100644 --- a/src/components/Redirection.tsx +++ b/src/components/Redirection.tsx @@ -1,22 +1,68 @@ +import { ArrowRightIcon } from 'lucide-react'; import { ReactNode } from 'react'; +import { Link } from 'react-router-dom'; -import { getUrlForRedirection } from '@graasp/sdk'; -import { RedirectionContent } from '@graasp/ui'; +import { GraaspLogo } from '@graasp/ui'; +import { Button, Container, Stack, Typography, useTheme } from '@mui/material'; + +import { DEFAULT_REDIRECTION_URL } from '../config/env'; +import { useAuthTranslation } from '../config/i18n'; import { hooks } from '../config/queryClient'; +import { REDIRECTION_CONTENT_CONTAINER_ID } from '../config/selectors'; import { useRedirection } from '../hooks/searchParams'; +import { AUTH } from '../langs/constants'; type Props = { children: ReactNode; }; const Redirection = ({ children }: Props) => { + const theme = useTheme(); const { data: member } = hooks.useCurrentMember(); + const { t } = useAuthTranslation(); const redirect = useRedirection(); + // redirect.url is used when user comes from another part of the app + const targetLink = redirect.url || DEFAULT_REDIRECTION_URL; if (member) { return ( - + + + + + + {t(AUTH.REDIRECTION_TITLE, { name: member.name })} + + + {t(AUTH.REDIRECTION_DESCRIPTION)} + + + + + ); } diff --git a/src/config/env.ts b/src/config/env.ts index 1aa62119..e723e97d 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -1,8 +1,7 @@ export const DOMAIN = import.meta.env.VITE_GRAASP_DOMAIN; export const APP_VERSION = import.meta.env.VITE_VERSION; - export const API_HOST = - import.meta.env.VITE_GRAASP_API_HOST || 'http://localhost:3000'; + import.meta.env.VITE_GRAASP_API_HOST ?? 'http://localhost:3000'; export const RECAPTCHA_SITE_KEY = import.meta.env.VITE_RECAPTCHA_SITE_KEY; @@ -15,3 +14,6 @@ export const SHOW_NOTIFICATIONS = export const GRAASP_LANDING_PAGE_HOST = import.meta.env.VITE_GRAASP_LANDING_PAGE_ORIGIN || 'https://graasp.org'; + +export const DEFAULT_REDIRECTION_URL = import.meta.env + .VITE_DEFAULT_REDIRECTION_URL; diff --git a/src/config/selectors.ts b/src/config/selectors.ts index 0d7d296b..b28b0f86 100644 --- a/src/config/selectors.ts +++ b/src/config/selectors.ts @@ -45,3 +45,5 @@ export const PASSWORD_SUCCESS_ALERT = 'passwordSuccessAlert'; export const PLATFORM_ADVERTISEMENT_CONTAINER_ID = 'platformAdvertisementContainer'; + +export const REDIRECTION_CONTENT_CONTAINER_ID = 'redirectionContentContainer'; diff --git a/src/langs/constants.ts b/src/langs/constants.ts index 64f37c69..4faa4a89 100644 --- a/src/langs/constants.ts +++ b/src/langs/constants.ts @@ -90,4 +90,7 @@ export const AUTH = { SHOW_PASSWORD: 'SHOW_PASSWORD', INVALID_TOKEN_PROVIDED_TITLE: 'INVALID_TOKEN_PROVIDED_TITLE', INVALID_TOKEN_PROVIDED_DESCRIPTION: 'INVALID_TOKEN_PROVIDED_DESCRIPTION', + REDIRECTION_TITLE: 'REDIRECTION_TITLE', + REDIRECTION_DESCRIPTION: 'REDIRECTION_DESCRIPTION', + REDIRECTION_BUTTON: 'REDIRECTION_BUTTON', }; diff --git a/src/langs/en.json b/src/langs/en.json index cf79625a..b5148f38 100644 --- a/src/langs/en.json +++ b/src/langs/en.json @@ -82,5 +82,8 @@ "RESET_PASSWORD_REQUIREMENTS_NUMBER": "Contain at least {{count}} number", "SHOW_PASSWORD": "Show passwords", "INVALID_TOKEN_PROVIDED_TITLE": "Invalid token provided", - "INVALID_TOKEN_PROVIDED_DESCRIPTION": "No token was provided or the provided token is expired. Click the button below to generate a request to reset your password." + "INVALID_TOKEN_PROVIDED_DESCRIPTION": "No token was provided or the provided token is expired. Click the button below to generate a request to reset your password.", + "REDIRECTION_TITLE": "Welcome back, {{name}}", + "REDIRECTION_DESCRIPTION": "You are logged in.", + "REDIRECTION_BUTTON": "Go to Graasp" }