diff --git a/assets/style.css b/assets/style.css index 3784cd5c3..752a5f42a 100644 --- a/assets/style.css +++ b/assets/style.css @@ -596,9 +596,39 @@ dl { column-gap: var(--space-3xs-2xs); } } + + @nest main > & { + margin-block-start: var(--space-m); + max-inline-size: 64ch; + + & > div { + display: flex; + flex-wrap: wrap; + column-gap: var(--space-xs-m); + row-gap: var(--space-4xs); + margin-block-start: var(--space-2xs); + + & + div { + border-block-start: var(--width-divider-narrow) solid var(--color-divider-light); + padding-block-start: var(--space-2xs); + } + + @media screen { + @media (width < 30em) { + flex-direction: column; + } + } + } + + & dt { + min-inline-size: 20ch; + } + } } dt { + font-weight: 500; + @nest header & { font-weight: 700; -moz-osx-font-smoothing: grayscale; diff --git a/integration/log-in.spec.ts b/integration/log-in.spec.ts new file mode 100644 index 000000000..89b266e53 --- /dev/null +++ b/integration/log-in.spec.ts @@ -0,0 +1,20 @@ +import { areLoggedIn, canLogIn, expect, test } from './base' + +test.extend(canLogIn).extend(areLoggedIn)('can view my details', async ({ javaScriptEnabled, page }) => { + await page.goto('/my-details') + + await expect(page.getByRole('heading', { level: 1 })).toHaveText('My details') + await expect(page).toHaveScreenshot() + + await page.keyboard.press('Tab') + + await expect(page.getByRole('link', { name: 'Skip to main content' })).toBeFocused() + await expect(page).toHaveScreenshot() + + await page.keyboard.press('Enter') + + if (javaScriptEnabled) { + await expect(page.getByRole('main')).toBeFocused() + } + await expect(page).toHaveScreenshot() +}) diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-high-contrast--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-high-contrast--linux.png new file mode 100644 index 000000000..52f1c9a6a --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-high-contrast--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98b184aee24320e2a79bdaf65ca735a3d348b71653960f90fe9406aca20bb1b6 +size 48495 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-high-contrast-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-high-contrast-no-JavaScript--linux.png new file mode 100644 index 000000000..52f1c9a6a --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-high-contrast-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98b184aee24320e2a79bdaf65ca735a3d348b71653960f90fe9406aca20bb1b6 +size 48495 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-linux.png new file mode 100644 index 000000000..b757f4977 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:faf856953709816753007ddb65560b346e2d5cec01b2595988ec78274866c569 +size 54382 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-no-JavaScript--linux.png new file mode 100644 index 000000000..b757f4977 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Chrome-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:faf856953709816753007ddb65560b346e2d5cec01b2595988ec78274866c569 +size 54382 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Firefox-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Firefox-linux.png new file mode 100644 index 000000000..b2be7b74f --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Firefox-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d10f225ef95ae236987115e46aaa69a126cb7e3302f299eedae3a0e88f525690 +size 75834 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Firefox-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Firefox-no-JavaScript--linux.png new file mode 100644 index 000000000..b2be7b74f --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Desktop-Firefox-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d10f225ef95ae236987115e46aaa69a126cb7e3302f299eedae3a0e88f525690 +size 75834 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Mobile-Chrome-high-contrast--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Mobile-Chrome-high-contrast--linux.png new file mode 100644 index 000000000..97d6bf2fc --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Mobile-Chrome-high-contrast--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce1476e85314c6b9854abf196dfce7e7932813ad6fa852314f107544b8e9c29b +size 37839 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Mobile-Chrome-high-contrast-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Mobile-Chrome-high-contrast-no-JavaScript--linux.png new file mode 100644 index 000000000..97d6bf2fc --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-Mobile-Chrome-high-contrast-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce1476e85314c6b9854abf196dfce7e7932813ad6fa852314f107544b8e9c29b +size 37839 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-iPhone-11-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-iPhone-11-linux.png new file mode 100644 index 000000000..49f802466 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-iPhone-11-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4af3b140482a99229b6afbc61cdc7c3cbd22f1e91bca49c1cf932bfe260eb437 +size 37335 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-iPhone-11-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-iPhone-11-no-JavaScript--linux.png new file mode 100644 index 000000000..49f802466 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-1-iPhone-11-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4af3b140482a99229b6afbc61cdc7c3cbd22f1e91bca49c1cf932bfe260eb437 +size 37335 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-high-contrast--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-high-contrast--linux.png new file mode 100644 index 000000000..fb35e1206 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-high-contrast--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26f4a429e650febed68c9637a54842ac8a7383683b5ef49b8d891a5c9217e3cc +size 50355 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-high-contrast-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-high-contrast-no-JavaScript--linux.png new file mode 100644 index 000000000..fb35e1206 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-high-contrast-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26f4a429e650febed68c9637a54842ac8a7383683b5ef49b8d891a5c9217e3cc +size 50355 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-linux.png new file mode 100644 index 000000000..1842142bd --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7b3a256f3dd76eb4ad8e4f1ce8cd706e760e578d78e6fc901a21bd0f0a72f8f +size 56702 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-no-JavaScript--linux.png new file mode 100644 index 000000000..1842142bd --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Chrome-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7b3a256f3dd76eb4ad8e4f1ce8cd706e760e578d78e6fc901a21bd0f0a72f8f +size 56702 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Firefox-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Firefox-linux.png new file mode 100644 index 000000000..2a68a15f8 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Firefox-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:007002bf8b618c3261e8711d764892a44b23eeb3df25d6b4a7ea4f1aaec9512e +size 79473 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Firefox-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Firefox-no-JavaScript--linux.png new file mode 100644 index 000000000..2a68a15f8 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Desktop-Firefox-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:007002bf8b618c3261e8711d764892a44b23eeb3df25d6b4a7ea4f1aaec9512e +size 79473 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Mobile-Chrome-high-contrast--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Mobile-Chrome-high-contrast--linux.png new file mode 100644 index 000000000..1e639c819 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Mobile-Chrome-high-contrast--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:615a0ab6a42cab15471a95caee7fea16ff497343c64ee5226c1f8fb1ec31c6b0 +size 38877 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Mobile-Chrome-high-contrast-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Mobile-Chrome-high-contrast-no-JavaScript--linux.png new file mode 100644 index 000000000..1e639c819 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-Mobile-Chrome-high-contrast-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:615a0ab6a42cab15471a95caee7fea16ff497343c64ee5226c1f8fb1ec31c6b0 +size 38877 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-iPhone-11-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-iPhone-11-linux.png new file mode 100644 index 000000000..ddf646198 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-iPhone-11-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f350da8ae6eb5688720bba0ef9ad37d6baebdfde092368a5126de5b8f784b79 +size 38981 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-iPhone-11-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-iPhone-11-no-JavaScript--linux.png new file mode 100644 index 000000000..ddf646198 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-2-iPhone-11-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f350da8ae6eb5688720bba0ef9ad37d6baebdfde092368a5126de5b8f784b79 +size 38981 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-high-contrast--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-high-contrast--linux.png new file mode 100644 index 000000000..0bf51e2cf --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-high-contrast--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ded9efd0d27c98806908ba2db1c389df06e6c7ceaa4d20284fc4a6173401c2ed +size 48659 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-high-contrast-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-high-contrast-no-JavaScript--linux.png new file mode 100644 index 000000000..ae327acb1 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-high-contrast-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d181fff6af83ff506e5c997f4d2ec712409d58f6f4554259cdb8ed93f1ea318 +size 50277 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-linux.png new file mode 100644 index 000000000..28a9198d1 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f3b66ee413775dbc1fa17867a6ea73af98affbf93704e4f1038a91a7fea2056 +size 54502 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-no-JavaScript--linux.png new file mode 100644 index 000000000..084c83451 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Chrome-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffb149343dd7968669fec3fdb2845f2f81bfbc868aeb14f49b046c6b3776538e +size 54210 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Firefox-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Firefox-linux.png new file mode 100644 index 000000000..daa6e88da --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Firefox-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c13d0d25cd4a52ff1831b89c490b3c6441a9eb7612de7a0277fea8b2c6fa9b9b +size 76706 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Firefox-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Firefox-no-JavaScript--linux.png new file mode 100644 index 000000000..9062d46e9 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Desktop-Firefox-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea652ccd3524403ac175b1a69e7e2a2126ca5eb8c619d297fbbb3523198186d3 +size 76041 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Mobile-Chrome-high-contrast--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Mobile-Chrome-high-contrast--linux.png new file mode 100644 index 000000000..ac17f11b6 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Mobile-Chrome-high-contrast--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fd2d3201bb5a4563e37f0593493fbaea53f830abfef516314f9edbf70e674f2 +size 37852 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Mobile-Chrome-high-contrast-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Mobile-Chrome-high-contrast-no-JavaScript--linux.png new file mode 100644 index 000000000..97d6bf2fc --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-Mobile-Chrome-high-contrast-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce1476e85314c6b9854abf196dfce7e7932813ad6fa852314f107544b8e9c29b +size 37839 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-iPhone-11-linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-iPhone-11-linux.png new file mode 100644 index 000000000..9be9dc7ec --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-iPhone-11-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d603dc321be14b9da8dc98a5b41c9c4d026f6105308bbd35cc23fb036c3ab79 +size 37348 diff --git a/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-iPhone-11-no-JavaScript--linux.png b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-iPhone-11-no-JavaScript--linux.png new file mode 100644 index 000000000..49f802466 --- /dev/null +++ b/integration/snapshots/log-in.spec.ts-snapshots/can-view-my-details-3-iPhone-11-no-JavaScript--linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4af3b140482a99229b6afbc61cdc7c3cbd22f1e91bca49c1cf932bfe260eb437 +size 37335 diff --git a/src/app.ts b/src/app.ts index b5d68219e..161d5a360 100644 --- a/src/app.ts +++ b/src/app.ts @@ -46,6 +46,7 @@ import { import { getPreprintIdFromLegacyPreviewUuid, getProfileIdFromLegacyPreviewUuid } from './legacy-prereview' import { legacyRoutes } from './legacy-routes' import { authenticate, authenticateError, logIn, logOut } from './log-in' +import { myDetails } from './my-details' import { getNameFromOrcid } from './orcid' import type { FathomEnv, PhaseEnv } from './page' import { partners } from './partners' @@ -68,6 +69,7 @@ import { homeMatch, logInMatch, logOutMatch, + myDetailsMatch, orcidCodeMatch, orcidErrorMatch, partnersMatch, @@ -367,6 +369,28 @@ export const router: P.Parser myDetails), + P.map( + R.local((env: AppEnv) => ({ + ...env, + /*getName: flip(getNameFromOrcid)(env), + getPrereviews: flip(getPrereviewsForProfileFromZenodo)({ + ...env, + getPreprintTitle: flow( + flip(getPreprintTitle)(env), + TE.mapLeft(error => + match(error) + .with('not-a-preprint', () => 'not-found' as const) + .otherwise(identity), + ), + ), + }),*/ + getUser: () => pipe(getSession(), chainOptionKW(() => 'no-session' as const)(getUserFromSession))(env), + })), + ), + ), pipe( profileMatch.parser, P.map(({ profile: profileId }) => profile(profileId)), diff --git a/src/my-details.ts b/src/my-details.ts new file mode 100644 index 000000000..d009b56bd --- /dev/null +++ b/src/my-details.ts @@ -0,0 +1,76 @@ +import type { Reader } from 'fp-ts/Reader' +import { pipe } from 'fp-ts/function' +import { type ResponseEnded, Status, type StatusOpen } from 'hyper-ts' +import type { OAuthEnv } from 'hyper-ts-oauth' +import * as RM from 'hyper-ts/lib/ReaderMiddleware' +import { P, match } from 'ts-pattern' +import { html, plainText, sendHtml } from './html' +import { logInAndRedirect } from './log-in' +import { serviceUnavailable } from './middleware' +import { type FathomEnv, type PhaseEnv, page } from './page' +import type { PublicUrlEnv } from './public-url' +import { myDetailsMatch } from './routes' +import { getUser } from './user' +import type { GetUserEnv, User } from './user' + +export const myDetails = pipe( + getUser, + chainReaderKW(createPage), + RM.ichainFirst(() => RM.status(Status.OK)), + RM.ichainMiddlewareKW(sendHtml), + RM.orElseW(error => + match(error) + .with( + 'no-session', + () => + logInAndRedirect(myDetailsMatch.formatter, {}) as RM.ReaderMiddleware< + GetUserEnv & FathomEnv & PhaseEnv & PublicUrlEnv & OAuthEnv, + StatusOpen, + ResponseEnded, + never, + void + >, + ) + .with(P.instanceOf(Error), () => serviceUnavailable) + .exhaustive(), + ), +) + +function createPage(user: User) { + return page({ + title: plainText`My details`, + content: html` +
+

My details

+ +
+
+
ORCID iD
+
${user.orcid}
+
+ +
+
PREreview pseudonym
+
${user.pseudonym}
+
+
+
+ `, + skipLinks: [[html`Skip to main content`, '#main-content']], + user, + }) +} + +// https://github.com/DenisFrezzato/hyper-ts/pull/85 +function fromReaderK, B, I = StatusOpen, E = never>( + f: (...a: A) => Reader, +): (...a: A) => RM.ReaderMiddleware { + return (...a) => RM.rightReader(f(...a)) +} + +// https://github.com/DenisFrezzato/hyper-ts/pull/85 +function chainReaderKW( + f: (a: A) => Reader, +): (ma: RM.ReaderMiddleware) => RM.ReaderMiddleware { + return RM.chainW(fromReaderK(f)) +} diff --git a/src/page.ts b/src/page.ts index 982f0063c..1c3cc575e 100644 --- a/src/page.ts +++ b/src/page.ts @@ -72,18 +72,18 @@ export function page({ ${title} - ${scripts.map(file => html``)} + ${scripts.map(file => html` `)} ${scripts.flatMap( flow( file => assets[file].preload as ReadonlyArray, - RA.map(preload => html``), + RA.map(preload => html` `), ), )} ${fathomId - ? html`` + ? html` ` : ''} diff --git a/src/routes.ts b/src/routes.ts index 20827a4a4..a070c323e 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -146,6 +146,8 @@ export const orcidErrorMatch = pipe( P.then(P.end), ) +export const myDetailsMatch = pipe(P.lit('my-details'), P.then(P.end)) + export const profileMatch = pipe(P.lit('profiles'), P.then(type('profile', ProfileIdC)), P.then(P.end)) export const preprintReviewsMatch = pipe(P.lit('preprints'), P.then(type('id', PreprintIdC)), P.then(P.end)) diff --git a/test/my-details.test.ts b/test/my-details.test.ts new file mode 100644 index 000000000..6cf677b8f --- /dev/null +++ b/test/my-details.test.ts @@ -0,0 +1,115 @@ +import { test } from '@fast-check/jest' +import { describe, expect } from '@jest/globals' +import { format } from 'fp-ts-routing' +import * as E from 'fp-ts/Either' +import { MediaType, Status } from 'hyper-ts' +import * as M from 'hyper-ts/lib/Middleware' +import * as _ from '../src/my-details' +import { myDetailsMatch } from '../src/routes' +import * as fc from './fc' +import { runMiddleware } from './middleware' + +describe('myDetails', () => { + test.prop([ + fc.record({ + authorizeUrl: fc.url(), + clientId: fc.string(), + clientSecret: fc.string(), + redirectUri: fc.url(), + tokenUrl: fc.url(), + }), + fc.origin(), + fc.connection({ method: fc.requestMethod() }), + fc.user(), + ])('when the user is logged in', async (oauth, publicUrl, connection, user) => { + const actual = await runMiddleware( + _.myDetails({ + getUser: () => M.right(user), + oauth, + publicUrl, + }), + connection, + )() + + expect(actual).toStrictEqual( + E.right([ + { type: 'setStatus', status: Status.OK }, + { type: 'setHeader', name: 'Content-Type', value: MediaType.textHTML }, + { type: 'setBody', body: expect.anything() }, + ]), + ) + }) + + test.prop([ + fc.record({ + authorizeUrl: fc.url(), + clientId: fc.string(), + clientSecret: fc.string(), + redirectUri: fc.url(), + tokenUrl: fc.url(), + }), + fc.origin(), + fc.connection({ method: fc.requestMethod() }), + ])('when the user is not logged in', async (oauth, publicUrl, connection) => { + const actual = await runMiddleware( + _.myDetails({ + getUser: () => M.left('no-session'), + oauth, + publicUrl, + }), + connection, + )() + + expect(actual).toStrictEqual( + E.right([ + { type: 'setStatus', status: Status.Found }, + { + type: 'setHeader', + name: 'Location', + value: new URL( + `?${new URLSearchParams({ + client_id: oauth.clientId, + response_type: 'code', + redirect_uri: oauth.redirectUri.href, + scope: '/authenticate', + state: new URL(format(myDetailsMatch.formatter, {}), publicUrl).toString(), + }).toString()}`, + oauth.authorizeUrl, + ).href, + }, + { type: 'endResponse' }, + ]), + ) + }) + + test.prop([ + fc.record({ + authorizeUrl: fc.url(), + clientId: fc.string(), + clientSecret: fc.string(), + redirectUri: fc.url(), + tokenUrl: fc.url(), + }), + fc.origin(), + fc.connection({ method: fc.requestMethod() }), + fc.error(), + ])("when the user can't be loaded", async (oauth, publicUrl, connection, error) => { + const actual = await runMiddleware( + _.myDetails({ + getUser: () => M.left(error), + oauth, + publicUrl, + }), + connection, + )() + + expect(actual).toStrictEqual( + E.right([ + { type: 'setStatus', status: Status.ServiceUnavailable }, + { type: 'setHeader', name: 'Cache-Control', value: 'no-store, must-revalidate' }, + { type: 'setHeader', name: 'Content-Type', value: MediaType.textHTML }, + { type: 'setBody', body: expect.anything() }, + ]), + ) + }) +})