-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathAuthorize.ts
More file actions
110 lines (91 loc) · 4.54 KB
/
Authorize.ts
File metadata and controls
110 lines (91 loc) · 4.54 KB
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
import { Router, Request, Response } from 'express';
import AuthorizationToken from '../entities/AuthorizationToken';
import Settings from '../entities/Settings';
import db from '../utils/db';
import { getAccessToken, generateAuthorizeUrl } from '../utils/bb2';
import { getExplanationOfBenefitData, getPatientJSON, getCoverageJSON } from './Data';
import logger from '@shared/Logger';
import { clearBB2Data, getLoggedInUser } from 'src/utils/user';
const BENE_DENIED_ACCESS = 'access_denied';
export async function authorizationCallback(req: Request, res: Response) {
try {
if (req.query.error === BENE_DENIED_ACCESS) {
const loggedInUser = getLoggedInUser(db);
// clear all saved claims data since the bene has denied access for the application
clearBB2Data(loggedInUser);
loggedInUser.errors.push(BENE_DENIED_ACCESS);
throw new Error('Beneficiary denied application access to their data');
}
if (!req.query.code) {
throw new Error('Response was missing access code');
}
if (db.settings.pkce && !req.query.state) {
throw new Error('State is required when using PKCE');
}
// this gets the token from Medicare.gov once the 'user' authenticates their Medicare.gov account
const response = await getAccessToken(req.query.code?.toString(), req.query.state?.toString());
const loggedInUser = getLoggedInUser(db);
if (response.status === 200) {
const authToken = new AuthorizationToken(response.data);
/* DEVELOPER NOTES:
* This is where you would most likely place some type of
* persistence service/functionality to store the token along with
* the application user identifiers
*/
// Here we are grabbing the mocked 'user' for our application
// to be able to store the access token for that user
// thereby linking the 'user' of our sample applicaiton with their Medicare.gov account
// providing access to their Medicare data to our sample application
loggedInUser.authToken = authToken;
/* DEVELOPER NOTES:
* Here we will use the token to get the EoB data for the mocked 'user' of the sample application
* then to save trips to the BB2 API we will store it in the mocked db with the mocked 'user'
*
* You could also request data for the Patient endpoint and/or the Coverage endpoint here
* using similar functionality
*/
loggedInUser.eobData = await getExplanationOfBenefitData( req, res);
loggedInUser.patient = await getPatientJSON( req, res);
loggedInUser.coverage = await getCoverageJSON( req, res);
}
else {
// send generic error message to FE
loggedInUser.eobData = JSON.parse('{"message": "Unable to load EOB Data - authorization failed."}');
loggedInUser.patient = JSON.parse('{"message": "Unable to load Patient Data - authorization failed."}');
loggedInUser.coverage = JSON.parse('{"message": "Unable to load Coverage Data - authorization failed."}');
}
} catch (e) {
/* DEVELOPER NOTES:
* This is where you could also use a data service or other exception handling
* to display or store the error
*/
logger.err(e)
}
/* DEVELOPER NOTE:
* This is a hardcoded redirect, but this should be used from settings stored in a conf file
* or other mechanism
*/
res.redirect(`http://localhost:3000`);
}
export async function getAuthUrl(req: Request, res: Response) {
/* DEVELOPER NOTE:
* to utilize the latest security features/best practices
* it is recommended to utilize pkce
*/
const pkce = req.params.pkce === 'true';
db.settings = new Settings({
version: req.query?.version?.toString() || db.settings.version,
env: req.query?.env?.toString() || db.settings.env,
pkce: req.query?.pkce?.toString() ? pkce : db.settings.pkce
});
res.send(generateAuthorizeUrl());
}
export async function getCurrentAuthToken(req: Request, res: Response) {
const loggedInUser = getLoggedInUser(db);
res.send(loggedInUser.authToken);
}
const router = Router();
router.get('/bluebutton/callback', authorizationCallback);
router.get('/authorize/authurl', getAuthUrl);
router.get('/authorize/currentAuthToken', getCurrentAuthToken);
export default router;