Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ updates:
- dependency-name: '@next/*'
- dependency-name: '@babel/*'
- dependency-name: 'openseadragon'
- dependency-name: '@auth0/nextjs-auth0'
- dependency-name: 'react-window'
- dependency-name: 'undici'
groups:
Expand Down
1 change: 0 additions & 1 deletion docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

- [Introduction](README.md)
- [How does library membership work?](library-membership.md)
- [Manual test script: identity user flows](../playwright/user-stories/identity.md)
- [How does item requesting work?](item-requesting.md)
- [How to turn off item requesting](turn-off-requesting.md)
- [Testing the site on dates that aren't "right now"](testing-the-site-on-dates-that-arent-right-now.md)
Expand Down
17 changes: 13 additions & 4 deletions identity/webapp/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ const port = Number(process.env.PORT) || 3000;

// Defaults (ie "build") need to be set here so that there's something available
// at build time - it never gets used
//
// The Auth0 SDK and session configuration lives in utils/auth0.ts, which
// reads the environment directly: it's also loaded by middleware.ts, where
// next/config isn't available.
const getConfig = () => {
return {
// Random values used for encrypting cookies used for the session. Can be comma separated list.
sessionKeys: process.env.SESSION_KEYS
? process.env.SESSION_KEYS.split(',')
: ['build_keys'],

// Versioning the session means that we can invalidate all users' sessions if we need to
// eg if we change the claims on the identity token
sessionVersion: 'v1',

// The base URL of the whole website (eg https://wellcomecollection.org)
siteBaseUrl: process.env.SITE_BASE_URL ?? `http://localhost:${port}`,
identityBasePath: '/account',

// Auth0 configuration.
auth0: {
domain: process.env.AUTH0_DOMAIN || 'build',
Expand Down
83 changes: 0 additions & 83 deletions identity/webapp/middleware.ts

This file was deleted.

9 changes: 0 additions & 9 deletions identity/webapp/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ const config = function () {
const prodSubdomain = process.env.PROD_SUBDOMAIN || '';
const basePath = '/account';

// The auth0 SDK reads NEXT_PUBLIC_BASE_PATH to build URLs under the
// basePath (eg the OAuth callback URL). Setting it here keeps it in sync
// with basePath without requiring it in every environment's config: the
// assignment covers code that reads it at runtime (the SDK is unbundled in
// the server build), and the `env` key below covers code where it gets
// inlined at build time (the middleware bundle).
process.env.NEXT_PUBLIC_BASE_PATH = basePath;

const withBundleAnalyzerConfig = withBundleAnalyzer({
analyzeServer: ['server', 'both'].includes(process.env.BUNDLE_ANALYZE),
analyzeBrowser: ['browser', 'both'].includes(process.env.BUNDLE_ANALYZE),
Expand Down Expand Up @@ -45,7 +37,6 @@ const config = function () {
? `https://${prodSubdomain}.wellcomecollection.org${basePath}`
: undefined,
basePath,
env: { NEXT_PUBLIC_BASE_PATH: basePath },
// We handle compression in the nginx sidecar
// Are you having problems with this? Make sure CloudFront is forwarding Accept-Encoding headers to our apps!
compress: false,
Expand Down
2 changes: 1 addition & 1 deletion identity/webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"lint:next": "next lint"
},
"dependencies": {
"@auth0/nextjs-auth0": "^4.22.0",
"@auth0/nextjs-auth0": "^3.5.0",
"@hookform/error-message": "^2.0.1",
"@koa/router": "^15.6.0",
"@weco/common": "1.0.0",
Expand Down
40 changes: 40 additions & 0 deletions identity/webapp/pages/api/auth/[...auth0].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import auth0 from '@weco/identity/utils/auth0';

export default auth0.handleAuth({
callback: async (req, res) => {
const { error } = req.query;

if (error) {
const query = new URLSearchParams(req.url);
res.redirect(`/account/error?${query.toString()}`);
return;
}
Comment on lines +7 to +11

// We have to `try … catch` here so we don't raise an Internal Server Error
// when the Auth0 callback fails for explicable reasons, e.g. somebody sending
// a deliberately malformed token or code.
//
// We deliberately omit the error message from the user-facing response.
// I don't think anybody will encounter this in normal running, and I'm not
// sure if that message could leak sensitive info.
try {
return await auth0.handleCallback(req, res);
} catch (error) {
console.warn(`Error in the Auth0 callback: ${error.message}`);
res
.status(error.status || 500)
.end('Something went wrong in the Auth0 callback');
}
Comment thread
gestchild marked this conversation as resolved.
},
logout: async (req, res) => {
// A given returnTo value must be in the client's `allowed_logout_urls`
// See https://github.com/auth0/nextjs-auth0/issues/532
const { returnTo } = req.query;
return auth0.handleLogout(req, res, {
returnTo: Array.isArray(returnTo) ? returnTo[0] : returnTo,
});
},
profile: async (req, res) => {
return auth0.handleProfile(req, res, { refetch: 'refetch' in req.query });
},
Comment thread
gestchild marked this conversation as resolved.
});
55 changes: 0 additions & 55 deletions identity/webapp/pages/api/auth/me.ts

This file was deleted.

28 changes: 7 additions & 21 deletions identity/webapp/pages/api/auth/signup.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
import { NextApiRequest, NextApiResponse } from 'next';
import auth0 from '@weco/identity/utils/auth0';

import { identityBasePath } from '@weco/identity/utils/auth0';

// This will redirect the user directly to the sign-up page: the SDK's login
// handler forwards arbitrary authorization params from the query string.
// This will redirect the user directly to the sign-up page.
//
// See
// https://community.auth0.com/t/how-do-i-redirect-users-directly-to-the-hosted-signup-page/42520
export default async (
req: NextApiRequest,
res: NextApiResponse
): Promise<void> => {
// Forward any query params (eg returnTo) to the login handler, as the v3
// signup handler did, but always force the signup screen.
const params = new URLSearchParams();
for (const [key, value] of Object.entries(req.query)) {
for (const v of Array.isArray(value) ? value : [value]) {
if (typeof v === 'string') params.append(key, v);
}
}
params.set('screen_hint', 'signup');

res.redirect(`${identityBasePath}/api/auth/login?${params.toString()}`);
};
// https://github.com/auth0/nextjs-auth0/issues/16#issuecomment-898565337
export default async (req, res) =>
auth0.handleLogin(req, res, {
authorizationParams: { screen_hint: 'signup' },
});
Comment on lines +1 to +11
8 changes: 4 additions & 4 deletions identity/webapp/pages/api/users/[[...users]].ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AccessTokenError } from '@auth0/nextjs-auth0/errors';
import { NextApiRequest, NextApiResponse } from 'next';
import { AccessTokenError } from '@auth0/nextjs-auth0';
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
import getConfig from 'next/config';

import auth0 from '@weco/identity/utils/auth0';
Expand All @@ -14,10 +14,10 @@ export const identityFetchClient: FetchClient = new FetchClient({
},
});

const handleIdentityApiRequest = auth0.withApiAuthRequired(
const handleIdentityApiRequest: NextApiHandler = auth0.withApiAuthRequired(
async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { token: accessToken } = await auth0.getAccessToken(req, res);
const { accessToken } = await auth0.getAccessToken(req, res);
const path = '/users/' + (req.query.users as string[]).join('/');

// GET and HEAD requests cannot have a body
Expand Down
6 changes: 3 additions & 3 deletions identity/webapp/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const Page: NextPage<AccountPageProps> = props => {
type Props = ServerSideProps<AccountPageProps>;

export const getServerSideProps: ServerSidePropsOrAppError<Props> =
withPageAuthRequiredSSR<Props>({
withPageAuthRequiredSSR({
getServerSideProps: async context => {
const serverData = await getServerData(context);

Expand Down Expand Up @@ -48,7 +48,7 @@ export const getServerSideProps: ServerSidePropsOrAppError<Props> =
// [1]: https://wellcome.slack.com/archives/CUA669WHH/p1656325929053499?thread_ts=1656322401.443269&cid=CUA669WHH
// [2]: https://auth0.com/docs/manage-users/user-accounts/user-profiles#caching-user-profiles
//
const session = await auth0.getSession(context.req);
const session = await auth0.getSession(context.req, context.res);

if (!session)
return {
Expand All @@ -59,7 +59,7 @@ export const getServerSideProps: ServerSidePropsOrAppError<Props> =

if (session.user.family_name === 'Auth0_Registration_tempLastName') {
const successParams = new URLSearchParams();
successParams.append('email', session.user.email ?? '');
successParams.append('email', session.user.email);

Comment thread
gestchild marked this conversation as resolved.
const params = new URLSearchParams();
params.append('returnTo', `/success?${successParams}`);
Expand Down
1 change: 1 addition & 0 deletions identity/webapp/pages/validated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const getServerSideProps: ServerSidePropsOrAppError<
// refresh after fetching a new access token.
try {
await auth0.getAccessToken(req, res, { refresh: true });
await auth0.getSession(req, res);
} catch {
// It doesn't matter if this fails; it means the user doesn't currently have a session
}
Expand Down
Loading