keycloak-demo/controllers/oauth/index.js

78 lines
2.2 KiB
JavaScript
Raw Normal View History

2021-09-01 12:46:41 +00:00
const debug = require('debug')('ctrl:common')
const util = require('util')
const url = require('url')
const sso = require('src/utils/sso/index.js')
const { get: getCacheInstance } = require('src/utils/cache.js')
2021-09-01 13:15:26 +00:00
const { resp, codeMessage, APIError } = require('src/utils/response/index.js')
2021-09-01 12:46:41 +00:00
const config = require('src/config/index.js')
2021-09-01 13:15:26 +00:00
const acl = require('src/utils/acl.js')
const { copyObject } = require('src/utils/index.js')
2021-08-31 10:24:42 +00:00
2021-09-01 12:46:41 +00:00
const controller = {}
module.exports = controller
2021-08-31 10:24:42 +00:00
2021-09-01 11:30:21 +00:00
controller.verifyCode = () => async (ctx) => {
2021-09-01 12:46:41 +00:00
const { code, session_state: sessionState, state } = ctx.query
2021-08-31 10:24:42 +00:00
// logout flow redirect tot frontend
2021-09-01 12:46:41 +00:00
if (state === 'logout') {
ctx.redirect(config.server.frontend_url)
return
2021-08-31 10:24:42 +00:00
}
// get back url from redis
2021-09-01 12:46:41 +00:00
const cacheKey = `login-${state}`
const cache = getCacheInstance()
2021-08-31 10:24:42 +00:00
2021-09-01 12:46:41 +00:00
const data = cache.get(cacheKey)
if (!data) ctx.throw('get login cache fail')
const stateObj = JSON.parse(data)
const { back_url: backURL } = stateObj
if (!backURL) ctx.throw('cache data missing')
2021-08-31 10:24:42 +00:00
2021-09-01 12:46:41 +00:00
const u = new url.URL(backURL)
2021-08-31 10:24:42 +00:00
try {
2021-09-01 12:46:41 +00:00
const token = await sso.getToken(code, sessionState)
2021-08-31 10:24:42 +00:00
2021-09-01 13:15:26 +00:00
if (!acl.checkAllow(token.groups)) {
const copy = copyObject(resp.Forbidden)
copy.object = codeMessage.CodeAccountNoPermission
throw new APIError('account no permission', copy)
}
2021-09-01 12:46:41 +00:00
// set accessToken/refreshToken cache
cache.set(token.access_token, token.refresh_token, false)
2021-08-31 10:24:42 +00:00
2021-09-01 11:30:21 +00:00
u.searchParams.append(
2021-09-01 12:46:41 +00:00
'success',
Buffer.from(JSON.stringify({ token: token.access_token })).toString('base64')
)
2021-08-31 10:24:42 +00:00
try {
2021-09-01 12:46:41 +00:00
cache.del(cacheKey)
2021-08-31 10:24:42 +00:00
} catch (err) {
2021-09-01 12:46:41 +00:00
debug(`delete cache fail: ${util.inspect(err, false, null)}`)
2021-08-31 10:24:42 +00:00
}
} catch (err) {
2021-09-01 12:46:41 +00:00
debug(`openid verify fail: ${util.inspect(err, false, null)}`)
2021-08-31 10:24:42 +00:00
/** @type {object} */
2021-09-01 12:46:41 +00:00
const errObj = { ...codeMessage.CodeInternalError }
2021-08-31 10:24:42 +00:00
if (err instanceof APIError) {
// @ts-ignore
2021-09-01 12:46:41 +00:00
Object.assign(errObj, err.object.object)
2021-08-31 10:24:42 +00:00
}
2021-09-01 12:46:41 +00:00
errObj.errorStack = err.stack
errObj.errorMessage = err.message
2021-09-01 11:30:21 +00:00
u.searchParams.append(
2021-09-01 12:46:41 +00:00
'error',
Buffer.from(JSON.stringify(errObj)).toString('base64')
)
2021-08-31 10:24:42 +00:00
}
2021-09-01 12:46:41 +00:00
ctx.redirect(u.toString())
}