|
1 | 1 | import { Router } from 'express';
|
2 | 2 | import type { Request, Response } from 'express';
|
3 | 3 | import fetch from 'node-fetch';
|
| 4 | +import { authorizationOrCookieHeader } from '../apiProxy'; |
4 | 5 | import { s3ConfigPromise } from '../awsIntegration';
|
| 6 | +import { conf } from '../config'; |
5 | 7 | import { log } from '../log';
|
6 | 8 | import { withIdentity } from '../middleware/identityMiddleware';
|
7 | 9 |
|
@@ -32,40 +34,80 @@ const router = Router();
|
32 | 34 | router.use(withIdentity(401));
|
33 | 35 |
|
34 | 36 | router.get('/auth', async (req: Request, res: Response) => {
|
35 |
| - const config = await newspaperArchiveConfigPromise; |
36 |
| - const authString = config?.authString; |
37 |
| - if (authString === undefined) { |
38 |
| - log.error(`Missing newspaper archive auth key`); |
39 |
| - res.status(500).send(); |
40 |
| - } |
| 37 | + try { |
| 38 | + const config = await newspaperArchiveConfigPromise; |
| 39 | + const authString = config?.authString; |
| 40 | + if (authString === undefined) { |
| 41 | + log.error(`Missing newspaper archive auth key`); |
| 42 | + return res.sendStatus(500); |
| 43 | + } |
| 44 | + |
| 45 | + const hasCorrectEntitlement = await checkSupporterEntitlement(req); |
41 | 46 |
|
42 |
| - const authHeader = base64(`${authString}`); |
43 |
| - const requestBody: NewspapersRequestBody = {}; |
| 47 | + if (!hasCorrectEntitlement) { |
| 48 | + // ToDo: show the user an error/info page |
| 49 | + return res.redirect('/'); |
| 50 | + } |
44 | 51 |
|
45 |
| - const response = await fetch( |
46 |
| - 'https://www.newspapers.com/api/userauth/public/get-tpa-token', |
47 |
| - { |
48 |
| - headers: { |
49 |
| - Authorization: `Basic ${authHeader}`, |
50 |
| - 'Content-Type': 'application/json', |
| 52 | + const authHeader = base64(`${authString}`); |
| 53 | + const requestBody: NewspapersRequestBody = {}; |
| 54 | + |
| 55 | + const response = await fetch( |
| 56 | + 'https://www.newspapers.com/api/userauth/public/get-tpa-token', |
| 57 | + { |
| 58 | + headers: { |
| 59 | + Authorization: `Basic ${authHeader}`, |
| 60 | + 'Content-Type': 'application/json', |
| 61 | + }, |
| 62 | + method: 'POST', |
| 63 | + body: JSON.stringify(requestBody), |
51 | 64 | },
|
52 |
| - method: 'POST', |
53 |
| - body: JSON.stringify(requestBody), |
54 |
| - }, |
55 |
| - ); |
| 65 | + ); |
56 | 66 |
|
57 |
| - const responseJson = (await response.json()) as NewspapersResponseBody; |
| 67 | + // ToDo: we have zod on the server, we could parse the responses with that |
| 68 | + const responseJson = (await response.json()) as NewspapersResponseBody; |
58 | 69 |
|
59 |
| - const archiveReturnUrlString = req.query['ncom-return-url']; |
60 |
| - if (archiveReturnUrlString && typeof archiveReturnUrlString === 'string') { |
61 |
| - const tpaToken = new URL(responseJson.url).searchParams.get('tpa'); |
| 70 | + const archiveReturnUrlString = req.query['ncom-return-url']; |
| 71 | + if ( |
| 72 | + archiveReturnUrlString && |
| 73 | + typeof archiveReturnUrlString === 'string' |
| 74 | + ) { |
| 75 | + const tpaToken = new URL(responseJson.url).searchParams.get('tpa'); |
62 | 76 |
|
63 |
| - const archiveReturnUrl = new URL(archiveReturnUrlString); |
64 |
| - archiveReturnUrl.searchParams.set('tpa', tpaToken ?? ''); |
65 |
| - return res.redirect(archiveReturnUrl.toString()); |
66 |
| - } |
| 77 | + const archiveReturnUrl = new URL(archiveReturnUrlString); |
| 78 | + archiveReturnUrl.searchParams.set('tpa', tpaToken ?? ''); |
| 79 | + return res.redirect(archiveReturnUrl.toString()); |
| 80 | + } |
67 | 81 |
|
68 |
| - return res.redirect(responseJson.url); |
| 82 | + return res.redirect(responseJson.url); |
| 83 | + } catch (e) { |
| 84 | + log.error( |
| 85 | + `Something went wrong authenticating with newspapers.com. ${e}`, |
| 86 | + ); |
| 87 | + return res.sendStatus(500); |
| 88 | + } |
69 | 89 | });
|
70 | 90 |
|
71 | 91 | export { router };
|
| 92 | + |
| 93 | +async function checkSupporterEntitlement(req: Request): Promise<boolean> { |
| 94 | + const supporterAttributesResponse = await getSupporterStatus(req); |
| 95 | + const supporterAttributes = await supporterAttributesResponse.json(); |
| 96 | + |
| 97 | + // ToDo: this should return a flag that represents either Tier 3 or a newspaperArchive specific entitlement |
| 98 | + return ( |
| 99 | + supporterAttributes.contentAccess['guardianWeeklySubscriber'] && |
| 100 | + supporterAttributes.contentAccess['supporterPlus'] |
| 101 | + ); |
| 102 | +} |
| 103 | + |
| 104 | +async function getSupporterStatus(req: Request) { |
| 105 | + const host = 'members-data-api.' + conf.DOMAIN; |
| 106 | + |
| 107 | + return fetch(`https://${host}/user-attributes/me`, { |
| 108 | + method: 'GET', |
| 109 | + headers: { |
| 110 | + ...(await authorizationOrCookieHeader({ req, host })), |
| 111 | + }, |
| 112 | + }); |
| 113 | +} |
0 commit comments