forked from postalsys/emailengine
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathauth-server.js
More file actions
105 lines (89 loc) · 3.04 KB
/
auth-server.js
File metadata and controls
105 lines (89 loc) · 3.04 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
'use strict';
// This is an example authentication server
// It provides fixed credentials foir an account called "example" and generates OAuth2 access tokens for an account called "oauth-user"
const Hapi = require('@hapi/hapi');
const hapiPino = require('hapi-pino');
const XOAuth2 = require('nodemailer/lib/xoauth2');
// Gmail oauth app credentials. Must have https://mail.google.com scope set
const OAUTH2_CLIENT_ID = process.env.OAUTH2_CLIENT_ID;
const OAUTH2_CLIENT_SECRET = process.env.OAUTH2_CLIENT_SECRET;
// Single user specific credentials as our demo only provides tokens for a single user
const USER_ADDRESS = process.env.USER_ADDRESS;
const USER_REFRESH_TOKEN = process.env.USER_REFRESH_TOKEN;
const init = async () => {
const server = Hapi.server({
port: 3080,
host: 'localhost'
});
await server.register({
plugin: hapiPino,
options: {
level: 'trace'
}
});
server.route({
method: 'GET',
path: '/credentials',
async handler(request) {
switch (request.query.account) {
case 'example':
return {
user: 'myuser2',
pass: 'verysecret'
};
}
switch (request.query.account) {
case 'oauth-user':
case 'ouath-user':
return {
user: USER_ADDRESS,
accessToken: await getAccessToken(USER_ADDRESS, USER_REFRESH_TOKEN)
};
}
return false;
}
});
await server.start();
console.log('Authentication Server URL: %s/credentials', server.info.uri);
};
// The following crux re-uses OAuth2 token generation from the Nodemailer package.
// Normally you'd probably use something like this instead: https://www.npmjs.com/package/google-auth-library
const tokens = new Map();
async function getAccessToken(user, refreshToken) {
// check cache first
if (tokens.has(user)) {
let token = tokens.get(user);
if (token.expires > new Date()) {
// use cached token
return token.accessToken;
}
// clear expired token
tokens.delete(user);
}
// generate new token
let token = await new Promise((resolve, reject) => {
let xoauth = new XOAuth2({
user,
clientId: OAUTH2_CLIENT_ID,
clientSecret: OAUTH2_CLIENT_SECRET,
refreshToken,
accessUrl: 'https://accounts.google.com/o/oauth2/token'
});
xoauth.generateToken(err => {
if (err) {
return reject(err);
}
if (!xoauth.accessToken) {
return reject(new Error('Could not generate new access token'));
}
resolve({
accessToken: xoauth.accessToken,
expires: xoauth.expires
});
});
});
// update cache
tokens.set(user, token);
return token.accessToken;
}
init();