-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
executable file
·115 lines (91 loc) · 2.25 KB
/
server.js
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
113
114
115
require("@ehealth/env/load");
const url = require("url");
const express = require("express");
require("express-async-errors");
const fetch = require("node-fetch");
const {
NODE_ENV,
PORT = 4000,
API_URL,
CLIENT_ID,
CLIENT_SECRET,
COOKIE_DOMAIN,
AUTH_COOKIE_NAME = "authorization",
META_COOKIE_NAME = "meta",
REDIRECT_URL = "/"
} = process.env;
const app = express();
app.set("trust proxy", true);
app.get("/auth/redirect", async (req, res) => {
const {
protocol,
path: pathname,
headers: { host },
query: { code }
} = req;
const redirect_uri = url.format({ protocol, host, pathname });
const {
value,
user_id,
expires_at,
details: { scope }
} = await authenticate({ code, redirect_uri });
const expires = new Date(expires_at * 1000);
const secure = NODE_ENV !== "development";
res.cookie(AUTH_COOKIE_NAME, value, {
domain: COOKIE_DOMAIN,
expires,
secure,
httpOnly: true
});
const metadata = { scope, userId: user_id };
res.cookie(META_COOKIE_NAME, JSON.stringify(metadata), {
domain: COOKIE_DOMAIN,
expires,
secure
});
res.redirect(REDIRECT_URL);
});
app.get("/auth/logout", async (req, res) => {
const secure = NODE_ENV !== "development";
res.clearCookie(AUTH_COOKIE_NAME, {
domain: COOKIE_DOMAIN,
secure,
httpOnly: true
});
res.clearCookie(META_COOKIE_NAME, {
domain: COOKIE_DOMAIN,
secure
});
res.redirect(REDIRECT_URL);
});
const authenticate = async ({ code, redirect_uri }) => {
const token = {
grant_type: "authorization_code",
code,
redirect_uri,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET
};
const response = await fetch(`${API_URL}/oauth/tokens`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token })
});
const { meta, error, data } = await response.json();
if (error) throw { meta, error };
return data;
};
const errorHandler = (error, req, res, next) => {
console.error(error);
if (error instanceof Error) {
next(error);
} else {
const { code = 500 } = error.meta || {};
res.status(code).json(error);
}
};
app.use(errorHandler);
app.listen(PORT, () => {
console.log(`Listening on http://0.0.0.0:${PORT}`);
});