🛂(frontend) button request access only on parent
The children reflect the parent access. So we can request access only on the parent document.
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
|||||||
randomName,
|
randomName,
|
||||||
verifyDocName,
|
verifyDocName,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
import { createRootSubPage } from './sub-pages-utils';
|
||||||
|
|
||||||
test.describe('Document create member', () => {
|
test.describe('Document create member', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
@@ -272,7 +273,9 @@ test.describe('Document create member: Multiple login', () => {
|
|||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('link', { name: 'Docs Logo Docs' }),
|
page.getByRole('link', { name: 'Docs Logo Docs' }),
|
||||||
).toBeVisible();
|
).toBeVisible({
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
await page.goto(urlDoc);
|
await page.goto(urlDoc);
|
||||||
|
|
||||||
@@ -294,4 +297,61 @@ test.describe('Document create member: Multiple login', () => {
|
|||||||
await expect(page.getByText('Share with 2 users')).toBeVisible();
|
await expect(page.getByText('Share with 2 users')).toBeVisible();
|
||||||
await expect(page.getByText(`E2E ${otherBrowser}`)).toBeVisible();
|
await expect(page.getByText(`E2E ${otherBrowser}`)).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('It cannot request member access on child doc on a 403 page', async ({
|
||||||
|
page,
|
||||||
|
browserName,
|
||||||
|
}) => {
|
||||||
|
test.slow();
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
await keyCloakSignIn(page, browserName);
|
||||||
|
|
||||||
|
const [docParent] = await createDoc(
|
||||||
|
page,
|
||||||
|
'Block Member access request on child doc - parent',
|
||||||
|
browserName,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
await verifyDocName(page, docParent);
|
||||||
|
|
||||||
|
await createRootSubPage(
|
||||||
|
page,
|
||||||
|
browserName,
|
||||||
|
'Block Member access request on child doc - child',
|
||||||
|
);
|
||||||
|
|
||||||
|
const urlDoc = page.url();
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'Logout',
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
|
const otherBrowser = BROWSERS.find((b) => b !== browserName);
|
||||||
|
|
||||||
|
await keyCloakSignIn(page, otherBrowser!);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('link', { name: 'Docs Logo Docs' }),
|
||||||
|
).toBeVisible({
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.goto(urlDoc);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByText(
|
||||||
|
"You're currently viewing a sub-document. To gain access, please request permission from the main document.",
|
||||||
|
),
|
||||||
|
).toBeVisible({
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Request access' }),
|
||||||
|
).toBeHidden();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
keyCloakSignIn,
|
keyCloakSignIn,
|
||||||
verifyDocName,
|
verifyDocName,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
import { createRootSubPage } from './sub-pages-utils';
|
||||||
|
|
||||||
test.describe('Doc Visibility', () => {
|
test.describe('Doc Visibility', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
@@ -271,7 +272,7 @@ test.describe('Doc Visibility: Public', () => {
|
|||||||
await page.getByRole('button', { name: 'Share' }).click();
|
await page.getByRole('button', { name: 'Share' }).click();
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(
|
page.getByText(
|
||||||
'You do not have permission to view users sharing this document or modify link settings.',
|
'You can view this document but need additional access to see its members or modify settings.',
|
||||||
),
|
),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|
||||||
@@ -398,6 +399,8 @@ test.describe('Doc Visibility: Authenticated', () => {
|
|||||||
page,
|
page,
|
||||||
browserName,
|
browserName,
|
||||||
}) => {
|
}) => {
|
||||||
|
test.slow();
|
||||||
|
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
await keyCloakSignIn(page, browserName);
|
await keyCloakSignIn(page, browserName);
|
||||||
|
|
||||||
@@ -435,6 +438,14 @@ test.describe('Doc Visibility: Authenticated', () => {
|
|||||||
|
|
||||||
const urlDoc = page.url();
|
const urlDoc = page.url();
|
||||||
|
|
||||||
|
const { name: childTitle } = await createRootSubPage(
|
||||||
|
page,
|
||||||
|
browserName,
|
||||||
|
'Authenticated read onlyc - child',
|
||||||
|
);
|
||||||
|
|
||||||
|
const urlChildDoc = page.url();
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Logout',
|
name: 'Logout',
|
||||||
@@ -446,7 +457,9 @@ test.describe('Doc Visibility: Authenticated', () => {
|
|||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('link', { name: 'Docs Logo Docs' }),
|
page.getByRole('link', { name: 'Docs Logo Docs' }),
|
||||||
).toBeVisible();
|
).toBeVisible({
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
await page.goto(urlDoc);
|
await page.goto(urlDoc);
|
||||||
|
|
||||||
@@ -457,7 +470,7 @@ test.describe('Doc Visibility: Authenticated', () => {
|
|||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(
|
page.getByText(
|
||||||
'You do not have permission to view users sharing this document or modify link settings.',
|
'You can view this document but need additional access to see its members or modify settings.',
|
||||||
),
|
),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|
||||||
@@ -466,6 +479,22 @@ test.describe('Doc Visibility: Authenticated', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Request access' }),
|
page.getByRole('button', { name: 'Request access' }),
|
||||||
).toBeDisabled();
|
).toBeDisabled();
|
||||||
|
|
||||||
|
await page.goto(urlChildDoc);
|
||||||
|
|
||||||
|
await expect(page.locator('h2').getByText(childTitle)).toBeVisible();
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Share' }).click();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByText(
|
||||||
|
'As this is a sub-document, please request access to the parent document to enable these features.',
|
||||||
|
),
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Request access' }),
|
||||||
|
).toBeHidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('It checks a authenticated doc in editable mode', async ({
|
test('It checks a authenticated doc in editable mode', async ({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Loader } from '@openfun/cunningham-react';
|
import { Loader } from '@openfun/cunningham-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { Box } from './Box';
|
import { Box, BoxProps } from './Box';
|
||||||
import { Icon } from './Icon';
|
import { Icon } from './Icon';
|
||||||
import { Text } from './Text';
|
import { Text } from './Text';
|
||||||
|
|
||||||
@@ -36,8 +36,8 @@ export const LoadMoreText = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Loading = () => (
|
export const Loading = (props: BoxProps) => (
|
||||||
<Box $align="center" $justify="center" $height="100%">
|
<Box $align="center" $justify="center" $height="100%" {...props}>
|
||||||
<Loader />
|
<Loader />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,7 +8,14 @@ import { useMemo, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { createGlobalStyle } from 'styled-components';
|
import { createGlobalStyle } from 'styled-components';
|
||||||
|
|
||||||
import { Box, BoxButton, Icon, LoadMoreText } from '@/components';
|
import {
|
||||||
|
Box,
|
||||||
|
BoxButton,
|
||||||
|
Icon,
|
||||||
|
LoadMoreText,
|
||||||
|
Loading,
|
||||||
|
Text,
|
||||||
|
} from '@/components';
|
||||||
import { QuickSearchData, QuickSearchGroup } from '@/components/quick-search';
|
import { QuickSearchData, QuickSearchGroup } from '@/components/quick-search';
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { AccessRequest, Doc } from '@/docs/doc-management/';
|
import { AccessRequest, Doc } from '@/docs/doc-management/';
|
||||||
@@ -161,7 +168,11 @@ export const ButtonAccessRequest = ({
|
|||||||
...buttonProps
|
...buttonProps
|
||||||
}: ButtonAccessRequestProps) => {
|
}: ButtonAccessRequestProps) => {
|
||||||
const { authenticated } = useAuth();
|
const { authenticated } = useAuth();
|
||||||
const { data: requests } = useDocAccessRequests({
|
const {
|
||||||
|
data: requests,
|
||||||
|
error: docAccessError,
|
||||||
|
isLoading,
|
||||||
|
} = useDocAccessRequests({
|
||||||
docId,
|
docId,
|
||||||
page: 1,
|
page: 1,
|
||||||
});
|
});
|
||||||
@@ -175,14 +186,28 @@ export const ButtonAccessRequest = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasRequested = !!(
|
|
||||||
requests && requests?.results.find((request) => request.document === docId)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (docAccessError?.status === 404) {
|
||||||
|
return (
|
||||||
|
<Text $maxWidth="320px" $textAlign="center" $variation="600" $size="sm">
|
||||||
|
{t(
|
||||||
|
'As this is a sub-document, please request access to the parent document to enable these features.',
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <Loading $height="auto" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasRequested = !!(
|
||||||
|
requests && requests?.results.find((request) => request.document === docId)
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => createRequest({ docId })}
|
onClick={() => createRequest({ docId })}
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ export const DocShareModal = ({ doc, onClose, isRootDoc = true }: Props) => {
|
|||||||
$size="sm"
|
$size="sm"
|
||||||
>
|
>
|
||||||
{t(
|
{t(
|
||||||
'You do not have permission to view users sharing this document or modify link settings.',
|
'You can view this document but need additional access to see its members or modify settings.',
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
<ButtonAccessRequest
|
<ButtonAccessRequest
|
||||||
|
|||||||
@@ -46,7 +46,11 @@ interface DocProps {
|
|||||||
|
|
||||||
const DocPage403 = ({ id }: DocProps) => {
|
const DocPage403 = ({ id }: DocProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { data: requests, isLoading: isLoadingRequest } = useDocAccessRequests({
|
const {
|
||||||
|
data: requests,
|
||||||
|
isLoading: isLoadingRequest,
|
||||||
|
error: docAccessError,
|
||||||
|
} = useDocAccessRequests({
|
||||||
docId: id,
|
docId: id,
|
||||||
page: 1,
|
page: 1,
|
||||||
});
|
});
|
||||||
@@ -56,7 +60,7 @@ const DocPage403 = ({ id }: DocProps) => {
|
|||||||
(request) => request.document === id,
|
(request) => request.document === id,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { error, isLoading: isLoadingDoc } = useDoc(
|
const { error: docError, isLoading: isLoadingDoc } = useDoc(
|
||||||
{ id },
|
{ id },
|
||||||
{
|
{
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
@@ -71,7 +75,7 @@ const DocPage403 = ({ id }: DocProps) => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isLoadingDoc && error?.status !== 403) {
|
if (!isLoadingDoc && docError?.status !== 403) {
|
||||||
void replace(`/docs/${id}`);
|
void replace(`/docs/${id}`);
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
}
|
}
|
||||||
@@ -115,6 +119,21 @@ const DocPage403 = ({ id }: DocProps) => {
|
|||||||
: t('Insufficient access rights to view the document.')}
|
: t('Insufficient access rights to view the document.')}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
{docAccessError?.status === 404 && (
|
||||||
|
<Text
|
||||||
|
as="p"
|
||||||
|
$maxWidth="320px"
|
||||||
|
$textAlign="center"
|
||||||
|
$variation="600"
|
||||||
|
$size="sm"
|
||||||
|
$margin={{ top: '0' }}
|
||||||
|
>
|
||||||
|
{t(
|
||||||
|
"You're currently viewing a sub-document. To gain access, please request permission from the main document.",
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box $direction="row" $gap="0.7rem">
|
<Box $direction="row" $gap="0.7rem">
|
||||||
<StyledLink href="/">
|
<StyledLink href="/">
|
||||||
<StyledButton
|
<StyledButton
|
||||||
@@ -124,7 +143,9 @@ const DocPage403 = ({ id }: DocProps) => {
|
|||||||
{t('Home')}
|
{t('Home')}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
<ButtonAccessRequest docId={id} />
|
{docAccessError?.status !== 404 && (
|
||||||
|
<ButtonAccessRequest docId={id} />
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user