2017-08-23 20:13:45 +00:00
|
|
|
import token from './tokens'
|
|
|
|
import error from '../error'
|
|
|
|
import response from '../response'
|
2020-06-05 15:18:23 +00:00
|
|
|
import wrap from '../wrap'
|
2017-08-23 20:13:45 +00:00
|
|
|
|
|
|
|
module.exports = wrap(async (req, res) => {
|
|
|
|
let clientId = null
|
|
|
|
let clientSecret = null
|
|
|
|
let grantType = null
|
|
|
|
|
|
|
|
if (req.body.client_id && req.body.client_secret) {
|
|
|
|
clientId = req.body.client_id
|
|
|
|
clientSecret = req.body.client_secret
|
|
|
|
console.debug('Client credentials parsed from body parameters', clientId, clientSecret)
|
|
|
|
} else {
|
|
|
|
if (!req.headers || !req.headers.authorization) {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.InvalidRequest('No authorization header passed')
|
2017-08-23 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let pieces = req.headers.authorization.split(' ', 2)
|
|
|
|
if (!pieces || pieces.length !== 2) {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.InvalidRequest('Authorization header is corrupted')
|
2017-08-23 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pieces[0] !== 'Basic') {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.InvalidRequest('Unsupported authorization method:', pieces[0])
|
2017-08-23 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
2017-08-24 16:23:03 +00:00
|
|
|
pieces = Buffer.from(pieces[1], 'base64').toString('ascii').split(':', 2)
|
2017-08-23 20:13:45 +00:00
|
|
|
if (!pieces || pieces.length !== 2) {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.InvalidRequest('Authorization header has corrupted data')
|
2017-08-23 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
clientId = pieces[0]
|
|
|
|
clientSecret = pieces[1]
|
|
|
|
console.debug('Client credentials parsed from basic auth header:', clientId, clientSecret)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!req.body.grant_type) {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.InvalidRequest('Request body does not contain grant_type parameter')
|
2017-08-23 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
grantType = req.body.grant_type
|
|
|
|
console.debug('Parameter grant_type is', grantType)
|
|
|
|
|
2020-05-28 18:30:21 +00:00
|
|
|
const client = await req.oauth2.model.client.fetchById(clientId)
|
2017-08-24 16:23:03 +00:00
|
|
|
|
2017-08-23 20:13:45 +00:00
|
|
|
if (!client) {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.InvalidClient('Client not found')
|
2017-08-23 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-28 18:30:21 +00:00
|
|
|
const valid = req.oauth2.model.client.checkSecret(client, clientSecret)
|
2017-08-23 20:13:45 +00:00
|
|
|
if (!valid) {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.UnauthorizedClient('Invalid client secret')
|
2017-08-23 20:13:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!req.oauth2.model.client.checkGrantType(client, grantType) && grantType !== 'refresh_token') {
|
2020-06-05 15:18:23 +00:00
|
|
|
throw new error.UnauthorizedClient('Invalid grant type for the client')
|
2017-08-23 20:13:45 +00:00
|
|
|
} else {
|
|
|
|
console.debug('Grant type check passed')
|
|
|
|
}
|
|
|
|
|
|
|
|
let evt
|
|
|
|
try {
|
|
|
|
switch (grantType) {
|
|
|
|
case 'authorization_code':
|
|
|
|
evt = await token.authorizationCode(req.oauth2, client, req.body.code, req.body.redirect_uri)
|
|
|
|
break
|
|
|
|
case 'password':
|
|
|
|
evt = await token.password(req.oauth2, client, req.body.username, req.body.password, req.body.scope)
|
|
|
|
break
|
|
|
|
case 'client_credentials':
|
|
|
|
evt = await token.clientCredentials(req.oauth2, client, req.body.scope)
|
|
|
|
break
|
|
|
|
case 'refresh_token':
|
|
|
|
evt = await token.refreshToken(req.oauth2, client, req.body.refresh_token, req.body.scope)
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
throw new error.UnsupportedGrantType('Grant type does not match any supported type')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (evt) {
|
|
|
|
response.data(req, res, evt)
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
response.error(req, res, e)
|
|
|
|
}
|
|
|
|
})
|