generated from kevin-powell/JAMStack-blog-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth.js
120 lines (101 loc) · 3.21 KB
/
auth.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
116
117
118
119
120
const { AuthorizationCode } = require('simple-oauth2');
const cookie = require("cookie");
const fetch = require('node-fetch')
// Warning: process.env.DEPLOY_PRIME_URL won’t work in a Netlify function here.
const SITE_URL = process.env.URL || 'http://localhost:8080/';
const providers = require('./providers.js');
class OAuth {
constructor(provider) {
this.provider = provider;
let config = this.config;
this.authorizationCode = new AuthorizationCode({
client: {
id: config.clientId,
secret: config.clientSecret
},
auth: {
tokenHost: config.tokenHost,
tokenPath: config.tokenPath,
authorizePath: config.authorizePath
}
});
}
get config() {
const cfg = {
secureHost: SITE_URL,
sessionExpiration: 60 * 60 * 8, // in seconds, this is 8 hours
/* redirect_uri is the callback url after successful signin */
redirect_uri: `${SITE_URL}/.netlify/functions/auth-callback`,
}
if(this.provider === "netlify") {
Object.assign(cfg, providers.netlify);
} else if(this.provider === "github") {
Object.assign(cfg, providers.github);
} else if(this.provider === "gitlab") {
Object.assign(cfg, providers.gitlab);
} else if(this.provider === "slack") {
Object.assign(cfg, providers.slack);
} else if(this.provider === "linkedin") {
Object.assign(cfg, providers.linkedin);
} else {
throw new Error("Invalid provider passed to OAuth. Currently only `netlify`, `github`, `gitlab`, `slack` or `linkedin` are supported.")
}
cfg.clientId = process.env[cfg.clientIdKey];
cfg.clientSecret = process.env[cfg.clientSecretKey];
if (!cfg.clientId || !cfg.clientSecret) {
throw new Error(`MISSING REQUIRED ENV VARS. ${cfg.clientIdKey} and ${cfg.clientSecretKey} are required.`)
}
return cfg;
}
async getUser(token) {
if(!token) {
throw new Error("Missing authorization token.");
}
const response = await fetch(this.config.userApi, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
}
})
console.log( "[auth] getUser response status", response.status );
if (response.status !== 200) {
throw new Error(`Error ${await response.text()}`)
}
const data = await response.json()
return data
}
}
function getCookie(name, value, expiration) {
let options = {
httpOnly: true,
secure: true,
sameSite: "Lax",
path: '/',
maxAge: expiration,
};
// no strict cookies on localhost for local dev
if(SITE_URL.startsWith("http://localhost:8080/")) {
delete options.sameSite;
}
return cookie.serialize(name, value, options)
}
function generateCsrfToken() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8) // eslint-disable-line
return v.toString(16)
})
}
module.exports = {
OAuth,
tokens: {
encode: function(token) {
return Buffer.from(token, "utf8").toString("base64");
},
decode: function(token) {
return Buffer.from(token, "base64").toString("utf8");
}
},
getCookie,
generateCsrfToken,
}