From 6f3d98ccc6a088981584231fb848e09047660d97 Mon Sep 17 00:00:00 2001 From: warunee Date: Fri, 12 Sep 2025 10:49:38 +0700 Subject: [PATCH] revert f3d6e6eb66ae3340839c1f637a02027d3ad74e77 revert Update sso.js --- sso.js | 180 +++++++++++++++++++++++++++------------------------------ 1 file changed, 84 insertions(+), 96 deletions(-) diff --git a/sso.js b/sso.js index 30c4fb9..eca0d34 100644 --- a/sso.js +++ b/sso.js @@ -1,3 +1,6 @@ +//simulate BMA SSO behavior Authenticator and reverse proxy +//cookie with token is the final product of SSO + require("dotenv").config(); const cookieParser = require('cookie-parser'); const querystring = require("querystring"); @@ -8,8 +11,6 @@ const cors = require('cors'); const jwt = require("jsonwebtoken"); const fs = require("fs"); const axios = require("axios"); -const CryptoJS = require("crypto-js"); -const secretKey = "uuidSecretKey2025"; // ใช้เป็นคีย์สำหรับเข้ารหัส const cookieName = process.env.SSO_COOKIE_NAME || "ssotoken"; const privateKey = fs.readFileSync(`./BMA`, "utf8"); @@ -25,107 +26,85 @@ const urlKeycloakToken = `${process.env.KC_URL}/realms/${process.env.KC_REALMS}/ const app = express(); -// ตั้งค่าการป้องกัน Origin -const allowedOrigins = ['http://localhost:3002', 'https://hrmsbkk.case-collection.com']; // อนุญาตเฉพาะ domain ที่กำหนด //http://localhost:3002 +// Allow a specific origin and enable credentials +const corsOptions = { + origin: 'http://localhost:3002', // Replace with your Vue app's URL + methods: 'GET,POST,PUT,DELETE', + credentials: true, // Enable cookies or Authorization headers +}; -app.use(cors({ - origin: function (origin, callback) { - if (allowedOrigins.includes(origin)) { - callback(null, true); // อนุญาต - } else { - callback(new Error('Origin not allowed by CORS')); // ปฏิเสธ - } - }, - methods: ['GET', 'POST'], // จำกัดเฉพาะ method ที่อนุญาต - credentials: true, -})); +app.use(cors(corsOptions)); app.use(express.urlencoded({ extended: true })); app.use(express.json()); app.use(cookieParser()); - -app.get("/api/v1/sso", async (req, res) => { - res.status(200).send("HRMS API SSO"); -}); - app.post("/api/v1/sso/signin", async (req, res) => { - const origin = req.headers.origin; - if (allowedOrigins.includes(origin)) { - try { - const login_user = req.body; - const formdata = new URLSearchParams(); - formdata.append("grant_type", "password"); - formdata.append("client_id", process.env.VITE_CLIENTID_KEYCLOAK); - formdata.append("username", login_user.username); - formdata.append("password", login_user.password); + try { + const login_user = req.body; - await axios.post(urlKeycloakToken, formdata, { - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - }).then(async () => { - const payload = { username: login_user.username }; - let token = jwt.sign(payload, privateKey, signOptions); + const formdata = new URLSearchParams(); + formdata.append("grant_type", "password"); + formdata.append("client_id", process.env.VITE_CLIENTID_KEYCLOAK); + formdata.append("username", login_user.username); + formdata.append("password", login_user.password); - res.cookie(cookieName, token, { - maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond - path: "/", - httpOnly: true, - }); + await axios.post(urlKeycloakToken, formdata, { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }).then(() => { + const payload = { username: login_user.username }; + let token = jwt.sign(payload, privateKey, signOptions); - const uid = await CryptoJS.AES.encrypt(login_user.username, secretKey).toString(); - res.status(200).send({ uid }); - - }).catch((err) => { - if (err.status) { - res.status(401).send("Incorrect user or password"); - } else - res.status(err.status).send(error); + res.cookie(cookieName, token, { + maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond + path: "/", + httpOnly: true, }); - } catch (error) { - res.status(500).send(error); - } - } else { - res.status(403).json({ error: 'Forbidden: Origin not allowed' }); + + res.sendStatus(200); + }).catch((err) => { + if (err.status) { + res.status(401).send("Incorrect user or password"); + } else + res.status(err.status).send(error); + }); + } catch (error) { + res.status(500).send(error); } }); app.post("/api/v1/sso/kcauth", async (req, res) => { - const origin = req.headers.origin; - if (allowedOrigins.includes(origin)) { - try { - // kcauth - // const useBMA = Boolean(process.env.USE_BMA) || false; - // const publicKeyLanding = fs.readFileSync(`./BMA.pub.pem`, "utf8"); - const clientSecret = process.env.KC_CLIENT_SECRET; - const clientId = process.env.KC_CLIENT_ID; + try { + // kcauth + const useBMA = Boolean(process.env.USE_BMA) || false; + const publicKeyLanding = fs.readFileSync(`./BMA.pub.pem`, "utf8"); + const clientSecret = process.env.KC_CLIENT_SECRET; + const clientId = process.env.KC_CLIENT_ID; - // const cookies = req.cookies; - // const tokenSSO = cookies[cookieName]; - //if (tokenSSO) { - // let decodedToken = ""; - // if (useBMA) { - // decodedToken = jwt.decode(tokenSSO); - // } else { - // decodedToken = jwt.verify(tokenSSO, publicKeyLanding); - // } - // let d = JSON.parse(JSON.stringify(decodedToken)); - // console.log("==== username from cookies ====", d); - // username = d.username; - // } + const cookies = req.cookies; + const tokenSSO = cookies[cookieName]; - // send uid from client - const uid = req.body.uid; - if (!uid) { - res.status(401).send("Unauthorized"); - return; + if (!tokenSSO) { + res.status(401).send("Unauthorized"); + return; + } + + const oldssotoken = cookies['oldssotoken']; + + if (tokenSSO !== oldssotoken) { + + let decodedToken = ""; + if (useBMA) { + decodedToken = jwt.decode(tokenSSO); + } else { + decodedToken = jwt.verify(tokenSSO, publicKeyLanding); } - let username = ""; - const bytes = CryptoJS.AES.decrypt(uid, secretKey); - const decrypted = bytes.toString(CryptoJS.enc.Utf8); - username = decrypted; + let d = JSON.parse(JSON.stringify(decodedToken)); + // console.log("==== username from cookies ====", d); + const username = d.username; // create body for admin token let body = { @@ -142,7 +121,6 @@ app.post("/api/v1/sso/kcauth", async (req, res) => { "Content-Type": "application/x-www-form-urlencoded", }, }); - // console.log("==== admin token ===="); const adminToken = response.data.access_token; // console.log(adminToken); @@ -159,8 +137,10 @@ app.post("/api/v1/sso/kcauth", async (req, res) => { }; const postData2 = querystring.stringify(body2); + // console.log("==== postData2 ===="); + // console.log(body2); - // get token for user + // get admin token const tokenResponse = await axios.post(urlKeycloakToken, postData2, { headers: { "Content-Type": "application/x-www-form-urlencoded", @@ -170,21 +150,29 @@ app.post("/api/v1/sso/kcauth", async (req, res) => { // console.log("==== user token ===="); // console.log(tokenResponse.data); // await postLog('เข้าสู่ระบบ', tokenResponse.data.access_token); - // res.cookie('oldssotoken', tokenSSO, { - // maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond - // path: "/", - // httpOnly: true, - // }); + res.cookie('oldssotoken', tokenSSO, { + maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond + path: "/", + httpOnly: true, + }); res.status(200).send(tokenResponse.data); - - } catch (error) { - res.status(500).send(error); + } else { + res.status(200).send({ isLogin: true }); } - } else { - res.status(403).json({ error: 'Forbidden: Origin not allowed' }); + + } catch (error) { + // console.log("error===>", error); + + res.status(500).send(error); } }) +// app.use(express.static(path.join(__dirname, "public-sso"))); + +// app.get("/", (_req, res) => { +// res.sendFile(`${process.cwd()}/sso.js`); +// }); + console.log("Start BMA SSO Simulator at port " + port); app.listen(port); \ No newline at end of file