Skip to content

Commit

Permalink
OC-721: Require login before checking whether a user has permission t…
Browse files Browse the repository at this point in the history
…o view a draft (#530)

* redirect to login when anon user visits draft/locked publication

* formatting

* capture error code in catch block
  • Loading branch information
finlay-jisc authored Nov 13, 2023
1 parent d617e7e commit ba65198
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 42 deletions.
5 changes: 2 additions & 3 deletions api/src/components/publicationVersion/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ export const get = async (
return response.json(200, publicationVersion);
}

return response.json(404, {
message:
'Publication version is either not found, or you do not have permissions to view it in its current state.'
return response.json(403, {
message: 'You do not have permission to view this publication version.'
});
} catch (err) {
console.log(err);
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/LoggedIn/publish.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,7 @@ test.describe('Publication flow + co-authors', () => {
page.waitForResponse(
(response) =>
response.request().method() === 'GET' &&
response.url().includes(`/publication-versions/latest`) &&
response.url().includes(`/publication-versions/`) &&
response.ok()
)
]);
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export const clickFirstPublication = async (page: Page): Promise<void> => {
await firstPublication.click();

// expect URL to contain publication path
await expect(page).toHaveURL(`${UI_BASE}${firstPublicationPath}`);
await expect(page).toHaveURL(`${UI_BASE}${firstPublicationPath}/versions/latest`);
};

export const testDateInput = async (page: Page, dateFromInput: Locator, dateToInput: Locator): Promise<void> => {
Expand Down
63 changes: 44 additions & 19 deletions ui/src/pages/publications/[id]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useMemo } from 'react';
import parse from 'html-react-parser';
import Head from 'next/head';
import useSWR from 'swr';
import axios from 'axios';
import axios, { AxiosResponse } from 'axios';

import * as OutlineIcons from '@heroicons/react/24/outline';
import * as api from '@api';
Expand Down Expand Up @@ -58,16 +58,25 @@ export const getServerSideProps: Types.GetServerSideProps = async (context) => {

// fetch data concurrently
const promises: [
Promise<Interfaces.PublicationVersion | void>,
Promise<
| { publicationVersion: Interfaces.PublicationVersion; versionRequestError: null }
| { publicationVersion: null; versionRequestError: { status: number; message: string } }
>,
Promise<Interfaces.BookmarkedEntityData[] | void>,
Promise<Interfaces.PublicationWithLinks | void>,
Promise<Interfaces.Flag[] | void>,
Promise<Interfaces.BaseTopic[] | void>
] = [
api
.get(`${Config.endpoints.publications}/${requestedId}/publication-versions/latest`, token)
.then((res) => res.data)
.catch((error) => console.log(error)),
.then((res) => ({ publicationVersion: res.data, versionRequestError: null }))
.catch((error) => {
console.log(error);
const status = error.response.status;
const message = error.response.data.message;

return { publicationVersion: null, versionRequestError: { status, message } };
}),
api
.get(`${Config.endpoints.bookmarks}?type=PUBLICATION&entityId=${requestedId}`, token)
.then((res) => res.data)
Expand All @@ -87,31 +96,47 @@ export const getServerSideProps: Types.GetServerSideProps = async (context) => {
];

const [
publicationVersion,
{ publicationVersion, versionRequestError },
bookmarks = [],
directLinks = { publication: null, linkedTo: [], linkedFrom: [] },
flags = [],
topics = []
] = await Promise.all(promises);

if (!publicationVersion) {
if (versionRequestError) {
const status = versionRequestError.status;
if (status === 404 || (token && status === 403)) {
return {
notFound: true
};
} else if (status === 403) {
return {
redirect: {
destination: `${Config.urls.orcidLogin.path}&state=${encodeURIComponent(context.resolvedUrl)}`,
permanent: false
}
};
}
}

if (publicationVersion) {
return {
props: {
publicationVersion,
userToken: token || '',
bookmarkId: bookmarks.length ? bookmarks[0].id : null,
publicationId: publicationVersion.publication.id,
protectedPage: ['LOCKED', 'DRAFT'].includes(publicationVersion.currentStatus),
directLinks,
flags,
topics
}
};
} else {
return {
notFound: true
};
}

return {
props: {
publicationVersion,
userToken: token || '',
bookmarkId: bookmarks.length ? bookmarks[0].id : null,
publicationId: publicationVersion.publication.id,
protectedPage: ['LOCKED', 'DRAFT'].includes(publicationVersion.currentStatus),
directLinks,
flags,
topics
}
};
};

type Props = {
Expand Down
61 changes: 43 additions & 18 deletions ui/src/pages/publications/[id]/versions/[versionId].tsx
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,25 @@ export const getServerSideProps: Types.GetServerSideProps = async (context) => {

// fetch data concurrently
const promises: [
Promise<Interfaces.PublicationVersion | void>,
Promise<
| { publicationVersion: Interfaces.PublicationVersion; versionRequestError: null }
| { publicationVersion: null; versionRequestError: { status: number; message: string } }
>,
Promise<Interfaces.BookmarkedEntityData[] | void>,
Promise<Interfaces.PublicationWithLinks | void>,
Promise<Interfaces.Flag[] | void>,
Promise<Interfaces.BaseTopic[] | void>
] = [
api
.get(`${Config.endpoints.publications}/${requestedId}/publication-versions/${versionId}`, token)
.then((res) => res.data)
.catch((error) => console.log(error)),
.then((res) => ({ publicationVersion: res.data, versionRequestError: null }))
.catch((error) => {
console.log(error);
const status = error.response.status;
const message = error.response.data.message;

return { publicationVersion: null, versionRequestError: { status, message } };
}),
api
.get(`${Config.endpoints.bookmarks}?type=PUBLICATION&entityId=${requestedId}`, token)
.then((res) => res.data)
Expand All @@ -93,31 +102,47 @@ export const getServerSideProps: Types.GetServerSideProps = async (context) => {
];

const [
publicationVersion,
{ publicationVersion, versionRequestError },
bookmarks = [],
directLinks = { publication: null, linkedTo: [], linkedFrom: [] },
flags = [],
topics = []
] = await Promise.all(promises);

if (!publicationVersion) {
if (versionRequestError) {
const status = versionRequestError.status;
if (status === 404 || (token && status === 403)) {
return {
notFound: true
};
} else if (status === 403) {
return {
redirect: {
destination: `${Config.urls.orcidLogin.path}&state=${encodeURIComponent(context.resolvedUrl)}`,
permanent: false
}
};
}
}

if (publicationVersion) {
return {
props: {
publicationVersion,
userToken: token || '',
bookmarkId: bookmarks.length ? bookmarks[0].id : null,
publicationId: publicationVersion.publication.id,
protectedPage: ['LOCKED', 'DRAFT'].includes(publicationVersion.currentStatus),
directLinks,
flags,
topics
}
};
} else {
return {
notFound: true
};
}

return {
props: {
publicationVersion,
userToken: token || '',
bookmarkId: bookmarks.length ? bookmarks[0].id : null,
publicationId: publicationVersion.publication.id,
protectedPage: ['LOCKED', 'DRAFT'].includes(publicationVersion.currentStatus),
directLinks,
flags,
topics
}
};
};

type Props = {
Expand Down

0 comments on commit ba65198

Please sign in to comment.