-
Notifications
You must be signed in to change notification settings - Fork 113
/
validate-authenticated-session.ts
112 lines (94 loc) · 3.19 KB
/
validate-authenticated-session.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import {Session, InvalidJwtError} from '@shopify/shopify-api';
import {Request, Response, NextFunction} from 'express';
import {redirectToAuth} from '../redirect-to-auth';
import {returnTopLevelRedirection} from '../return-top-level-redirection';
import {ApiAndConfigParams} from '../types';
import {ValidateAuthenticatedSessionMiddleware} from './types';
import {hasValidAccessToken} from './has-valid-access-token';
interface validateAuthenticatedSessionParams extends ApiAndConfigParams {}
export function validateAuthenticatedSession({
api,
config,
}: validateAuthenticatedSessionParams): ValidateAuthenticatedSessionMiddleware {
return function validateAuthenticatedSession() {
return async (req: Request, res: Response, next: NextFunction) => {
config.logger.info('Running validateAuthenticatedSession');
let sessionId: string | undefined;
try {
sessionId = await api.session.getCurrentId({
isOnline: config.useOnlineTokens,
rawRequest: req,
rawResponse: res,
});
} catch (error) {
await config.logger.error(
`Error when loading session from storage: ${error}`,
);
await handleSessionError(req, res, error);
return undefined;
}
let session: Session | undefined;
if (sessionId) {
try {
session = await config.sessionStorage.loadSession(sessionId);
} catch (error) {
await config.logger.error(
`Error when loading session from storage: ${error}`,
);
res.status(500);
res.send(error.message);
return undefined;
}
}
const shop = req.query.shop || session?.shop;
if (session && shop && session.shop !== shop) {
config.logger.debug(
'Found a session for a different shop in the request',
{currentShop: session.shop, requestShop: shop},
);
return redirectToAuth({req, res, api, config});
}
config.logger.debug('Request session found and loaded', {
shop: session?.shop,
});
if (session?.isActive(api.config.scopes)) {
config.logger.debug('Request session exists and is active', {
shop: session.shop,
});
if (await hasValidAccessToken(api, session)) {
config.logger.info('Request session has a valid access token', {
shop: session.shop,
});
res.locals.shopify = {
...res.locals.shopify,
session,
};
return next();
}
}
const redirectUrl = `${config.auth.path}?shop=${shop}`;
config.logger.info(
`Session was not valid. Redirecting to ${redirectUrl}`,
{shop},
);
return returnTopLevelRedirection({
res,
config,
bearerPresent: Boolean(req.headers.authorization?.match(/Bearer (.*)/)),
redirectUrl,
});
};
};
}
async function handleSessionError(_req: Request, res: Response, error: Error) {
switch (true) {
case error instanceof InvalidJwtError:
res.status(401);
res.send(error.message);
break;
default:
res.status(500);
res.send(error.message);
break;
}
}