This repository was archived by the owner on Dec 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 55
/
Copy pathkeycloak-identity-provider.js
80 lines (73 loc) · 2.42 KB
/
keycloak-identity-provider.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
const {StatusCodeError} = require('request-promise-core/lib/errors')
module.exports =
class KeycloakIdentityProvider {
constructor ({request, apiUrl, clientId, clientSecret, realm}) {
this.request = request
this.apiUrl = apiUrl
this.clientId = clientId
this.clientSecret = clientSecret
this.realm = realm
}
make_base_auth(clientId, clientSecret) {
var token = clientId + ':' + clientSecret
var hash = Buffer.from(token).toString('base64')
return "Basic " + hash
}
async identityForToken (oauthToken) {
try {
var options = {
method: 'POST',
uri: `${this.apiUrl}/realms/${this.realm}/protocol/openid-connect/token/introspect`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'api.teletype.atom.io',
'Authorization': this.make_base_auth(this.clientId, this.clientSecret)
},
body: `token=${oauthToken}`
}
const response = await this.request(options)
const user = JSON.parse(response)
if (!user.active) {
const error = new Error('Token not provided.')
error.statusCode = 400
throw error
}
return {id: user.sub, login: user.username}
} catch (e) {
let errorMessage, statusCode
if (e instanceof StatusCodeError) {
const error = JSON.parse(e.error)
const description = (error.message != null) ? error.message : e.error
errorMessage = `${this.apiUrl} responded with ${e.statusCode}: ${description}`
statusCode = e.statusCode
} else if (e instanceof Error) {
errorMessage = `Failed to query ${this.apiUrl}: ${e.message}`
statusCode = 400
} else {
errorMessage = `Failed to query ${this.apiUrl}: ${e.message}`
statusCode = 500
}
const error = new Error(errorMessage)
error.statusCode = statusCode
throw error
}
}
async isOperational () {
try {
var options = {
method: 'POST',
uri: `${this.apiUrl}/realms/${this.realm}/protocol/openid-connect/token/introspect`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'api.teletype.atom.io',
'Authorization': this.make_base_auth(this.clientId, this.clientSecret)
},
body: `token=`
}
await this.request(options)
return true
} catch (e) {
return false
}
}
}