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"); const { codeMessage, APIError } = require("src/utils/response/index.js"); const config = require("src/config/index.js"); const { jwt } = require("src/utils/pkgs.js"); const controller = {}; module.exports = controller; controller.verifyCode = () => async (ctx) => { const { code, session_state: sessionState, state } = ctx.query; // logout flow redirect tot frontend if (state === "logout") { ctx.redirect(config.server.frontend_url); return; } // get back url from redis const cacheKey = `login-${state}`; const cache = getCacheInstance(); 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"); const u = new url.URL(backURL); try { const token = await sso.getToken(code, sessionState); // generate jwt token const jwtToken = jwt.sign( { user_id: token.user_id, sso: true, }, config.server.jwt_secret, { expiresIn: config.server.jwt_expire, issuer: "lawsnote", } ); u.searchParams.append( "success", Buffer.from(JSON.stringify({ token: jwtToken })).toString("base64") ); try { cache.del(cacheKey); } catch (err) { debug(`delete cache fail: ${util.inspect(err, false, null)}`); } } catch (err) { debug(`openid verify fail: ${util.inspect(err, false, null)}`); /** @type {object} */ const errObj = { ...codeMessage.CodeInternalError }; if (err instanceof APIError) { // @ts-ignore Object.assign(errObj, err.object.object); } errObj.errorStack = err.stack; errObj.errorMessage = err.message; u.searchParams.append( "error", Buffer.from(JSON.stringify(errObj)).toString("base64") ); } ctx.redirect(u.toString()); };