commit 68c6bc7a620bdd043afbc493e85231996db6bc0c Author: waruneeauy Date: Mon Dec 16 20:09:22 2024 +0700 start project diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f02b3f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.env +node_modules +BMA* +package-lock.json \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..9694d76 --- /dev/null +++ b/Readme.md @@ -0,0 +1,13 @@ +# BMA HRMS SSO Simulator + +## install + +```bash +npm i +# สร้าง Public/Private key เกิดสามไฟล์ BMA BMA.pub BMA.pub.pem +ssh-keygen -t rsa -b 4096 -m PEM -f BMA +openssl rsa -in BMA -pubout > BMA.pub.pem + +# เรียกใช้โปรแกรม +node sso.js +``` diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..6ca5978 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,26 @@ +FROM node:lts-alpine AS build-stage + +ENV TZ=Asia/Bangkok + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN mkdir /app + +WORKDIR /app + +COPY package.json . + +ENV NODE_ENV production + +RUN npm install + +COPY . . + +# COPY sso.js . +# COPY index.html . +# COPY public-sso . +# COPY public-landing . + +EXPOSE 80 + +CMD ["node","sso.js"] \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..a5cb599 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "bma-sso-sim", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "axios": "^1.7.2", + "cookie-parser": "^1.4.6", + "dotenv": "^16.4.5", + "express": "^4.19.2", + "http-proxy-middleware": "^3.0.0", + "jsonwebtoken": "^9.0.2", + "querystring": "^0.2.1" + }, + "devDependencies": { + "concurrently": "^8.2.2" + } +} diff --git a/sso.js b/sso.js new file mode 100644 index 0000000..0f4f914 --- /dev/null +++ b/sso.js @@ -0,0 +1,78 @@ +//simulate BMA SSO behavior Authenticator and reverse proxy +//cookie with token is the final product of SSO + +require("dotenv").config(); +const port = Number(process.env.SSO_PORT) || 80; +const express = require("express"); +// const { createProxyMiddleware } = require("http-proxy-middleware"); +// const path = require("path"); +const jwt = require("jsonwebtoken"); +const fs = require("fs"); +const axios = require("axios"); + +const cookieName = process.env.SSO_COOKIE_NAME || "ssotoken"; +const privateKey = fs.readFileSync(`${process.cwd()}/BMA`, "utf8"); +const signOptions = { + issuer: "BMA corp", + subject: "sso@bangkok.go.th", + audience: "http://sso.bangkok.go.th", + expiresIn: "12h", + algorithm: "RS256", +}; + +const app = express(); +app.use(express.json()); +app.post("/signin", async (req, res) => { + + try { + const login_user = req.body; + const urlKeycloakToken = `${process.env.KC_URL}/realms/${process.env.KC_REALMS}/protocol/openid-connect/token`; + console.log("urlKeycloakToken===>", urlKeycloakToken); + + + 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); + + console.log("formdata===>", formdata); + + const response = await axios.post(urlKeycloakToken, formdata, { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + + if (response.data) { + console.log("response===>", response.data); + + const payload = { username: login_user.username }; + let token = jwt.sign(payload, privateKey, signOptions); + + console.log("token===>", token); + console.log("cookieName===>", cookieName); + + res.cookie(cookieName, token, { + maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond + path: "/", + httpOnly: false, + }); + + res.sendStatus(200); + } else { + res.status(401).send("Incorrect user or password"); + } + } catch (error) { + res.status(500).send("Incorrect user or password"); + } +}); + +// 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 diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..638ab76 --- /dev/null +++ b/start.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +ssh-keygen -t rsa -b 4096 -m PEM -f BMA -N "" +openssl rsa -in BMA -pubout > BMA.pub.pem + +# Start the first app +node ./sso.js & + +# Wait for all background processes to finish +wait