forked from hotello/meteor-keycloak-oauth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
keycloak_server.js
114 lines (94 loc) · 3.39 KB
/
keycloak_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
var GrantManager = Npm.require('keycloak-connect/middleware/auth-utils/grant-manager');
var Config = Npm.require('keycloak-connect/middleware/auth-utils/config');
Keycloak = {};
Keycloak.handleAuthFromAccessToken = function handleAuthFromAccessToken(accessToken, idToken, expiresAt) {
var whitelisted = ['email', 'name', 'given_name', 'family_name', 'picture', 'preferred_username', 'roles'];
var identity = getIdentity(accessToken);
var serviceData = {
accessToken: accessToken,
idToken: idToken,
expiresAt: expiresAt,
id: identity.sub,
};
var fields = _.pick(identity, whitelisted);
_.extend(serviceData, fields);
return {
serviceData: serviceData,
options: { profile: { name: identity.name } },
};
};
OAuth.registerService('keycloak', 2, null, function (query) {
var response = getTokenResponse(query);
var accessToken = response.accessToken;
var expiresIn = response.expiresIn;
var idToken = response.idToken;
return Keycloak.handleAuthFromAccessToken(accessToken, idToken, +new Date() + 1000 * expiresIn);
});
// checks whether a string parses as JSON
var isJSON = function (str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
};
// returns an object containing:
// - accessToken
// - expiresIn: lifetime of token in seconds
var getTokenResponse = function (query) {
var config = ServiceConfiguration.configurations.findOne({ service: 'keycloak' });
if (!config) throw new ServiceConfiguration.ConfigError();
var grantConfig = new Config(config);
var grantManager = new GrantManager(grantConfig);
var responseContent;
try {
// Request an access token
var getResponseContent = Meteor.wrapAsync(function (callback) {
grantManager
.obtainFromCode({ session: { auth_redirect_uri: OAuth._redirectUri('keycloak', config) } }, query.code)
.then((result) => callback(null, result))
.catch((err) => callback(err));
});
responseContent = getResponseContent();
} catch (err) {
throw _.extend(new Error('Failed to complete OAuth handshake with Keycloak. ' + err.message), {
response: err.response,
});
}
var kcAccessToken = responseContent.access_token.token;
var kcExpires = responseContent.expires_in;
var kcIdToken = responseContent.id_token.token;
if (!kcAccessToken) {
throw new Error(
'Failed to complete OAuth handshake with keycloak ' +
"-- can't find access token in HTTP response. " +
responseContent,
);
}
return {
accessToken: kcAccessToken,
expiresIn: kcExpires,
idToken: kcIdToken,
};
};
var getIdentity = function (accessToken) {
var config = ServiceConfiguration.configurations.findOne({ service: 'keycloak' });
if (!config) throw new ServiceConfiguration.ConfigError();
var grantConfig = new Config(config);
var grantManager = new GrantManager(grantConfig);
try {
var getKeycloakIdentity = Meteor.wrapAsync(function (callback) {
grantManager
.userInfo(accessToken)
.then((result) => callback(null, result))
.catch((err) => callback(err));
});
return getKeycloakIdentity();
} catch (err) {
throw _.extend(new Error('Failed to fetch identity from Keycloak. ' + err.message), { response: err.response });
}
};
Keycloak.retrieveCredential = function (credentialToken, credentialSecret) {
return OAuth.retrieveCredential(credentialToken, credentialSecret);
};