diff --git a/sso.js b/sso.js index 3a60f57..90d41ed 100644 --- a/sso.js +++ b/sso.js @@ -1,6 +1,3 @@ -//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"); @@ -28,163 +25,164 @@ const urlKeycloakToken = `${process.env.KC_URL}/realms/${process.env.KC_REALMS}/ const app = express(); -// 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 -}; +// ตั้งค่าการป้องกัน Origin +const allowedOrigins = ['https://hrms.bangkok.go.th', 'https://hrms.chin.in.th']; // อนุญาตเฉพาะ domain ที่กำหนด //http://localhost:3002 -app.use(cors(corsOptions)); +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(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; - 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); - 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); + 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); - 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); + res.cookie(cookieName, token, { + maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond + path: "/", + httpOnly: true, + }); - res.cookie(cookieName, token, { - maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond - path: "/", - httpOnly: true, + 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.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); + } catch (error) { + res.status(500).send(error); + } + } else { + res.status(403).json({ error: 'Forbidden: Origin not allowed' }); } }); app.post("/api/v1/sso/kcauth", async (req, res) => { - 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 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; - const cookies = req.cookies; - const uid = req.body.uid; + // 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 tokenSSO = cookies[cookieName]; + // send uid from client + const uid = req.body.uid; + if (!uid) { + res.status(401).send("Unauthorized"); + return; + } - if (!uid) { - res.status(401).send("Unauthorized"); - return; - } - // else 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; - - // } else if (uid) { - let username = ""; - if (req.body.serve === 'sso') { + let username = ""; const bytes = CryptoJS.AES.decrypt(uid, secretKey); const decrypted = bytes.toString(CryptoJS.enc.Utf8); username = decrypted; - } else { - username = uid; + + // create body for admin token + let body = { + client_id: clientId, + client_secret: clientSecret, + grant_type: "client_credentials", + }; + + const postData = querystring.stringify(body); + + // get admin token + const response = await axios.post(urlKeycloakToken, postData, { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + + // console.log("==== admin token ===="); + const adminToken = response.data.access_token; + // console.log(adminToken); + + // create body for user token + let body2 = { + client_id: clientId, + client_secret: clientSecret, + grant_type: "urn:ietf:params:oauth:grant-type:token-exchange", + subject_token: adminToken, + requested_token_type: "urn:ietf:params:oauth:token-type:refresh_token", + audience: clientId, + requested_subject: username, + }; + + const postData2 = querystring.stringify(body2); + + // get token for user + const tokenResponse = await axios.post(urlKeycloakToken, postData2, { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + + // 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.status(200).send(tokenResponse.data); + + } catch (error) { + res.status(500).send(error); } - - // const oldssotoken = cookies['oldssotoken']; - // const olduid = cookies['olduid']; - - // if (username !== olduid) { - // create body for admin token - let body = { - client_id: clientId, - client_secret: clientSecret, - grant_type: "client_credentials", - }; - - const postData = querystring.stringify(body); - - // get admin token - const response = await axios.post(urlKeycloakToken, postData, { - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - }); - // console.log("==== admin token ===="); - const adminToken = response.data.access_token; - // console.log(adminToken); - - // create body for user token - let body2 = { - client_id: clientId, - client_secret: clientSecret, - grant_type: "urn:ietf:params:oauth:grant-type:token-exchange", - subject_token: adminToken, - requested_token_type: "urn:ietf:params:oauth:token-type:refresh_token", - audience: clientId, - requested_subject: username, - }; - - const postData2 = querystring.stringify(body2); - // console.log("==== postData2 ===="); - // console.log(body2); - - // get admin token - const tokenResponse = await axios.post(urlKeycloakToken, postData2, { - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - }); - - // 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('olduid', username, { - // maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond - // path: "/", - // httpOnly: true, - // }); - - res.status(200).send(tokenResponse.data); - // } else { - // res.status(200).send({ isLogin: true }); - // } - - } catch (error) { - // console.log("error===>", error); - - res.status(500).send(error); + } else { + res.status(403).json({ error: 'Forbidden: Origin not allowed' }); } })