/home/techb158/balavpn.abdallabala.com
Edit: /home/techb158/balavpn.abdallabala.com/mock-oidc-provider.js (7016B)
const http = require("http");
const crypto = require("crypto");
const PORT = parseInt(process.env.MOCK_OIDC_PORT || "8093", 10);
const ISSUER = process.env.MOCK_OIDC_ISSUER || `http://localhost:${PORT}`;
const codes = new Map();
const accessTokens = new Map();
function base64Url(buf) {
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
function sha256(str) {
return crypto.createHash("sha256").update(str).digest("hex");
}
function encodeJwt(payload, secret = "mock-secret") {
const header = base64Url(Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })));
const body = base64Url(Buffer.from(JSON.stringify(payload)));
const sig = base64Url(Buffer.from(sha256(`${header}.${body}.${secret}`)));
return `${header}.${body}.${sig}`;
}
function parseQuery(url) {
const idx = url.indexOf("?");
if (idx === -1) return {};
return Object.fromEntries(new URLSearchParams(url.slice(idx + 1)));
}
function htmlPage(title, body) {
return `
${title}${body}`;
}
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
// Discovery
if (url === "/.well-known/openid-configuration" && method === "GET") {
res.writeHead(200, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" });
res.end(JSON.stringify({
issuer: ISSUER,
authorization_endpoint: `${ISSUER}/authorize`,
token_endpoint: `${ISSUER}/token`,
jwks_uri: `${ISSUER}/jwks`,
userinfo_endpoint: `${ISSUER}/userinfo`,
response_types_supported: ["code"],
subject_types_supported: ["public"],
id_token_signing_alg_values_supported: ["HS256"],
scopes_supported: ["openid", "email", "profile"],
}));
return;
}
// Consent (authorization callback) — must be before /authorize
if (url.startsWith("/authorize/consent") && method === "GET") {
const params = parseQuery(url);
const code = base64Url(crypto.randomBytes(32));
const email = params.email || "demo@cosmic.local";
const name = params.name || email.split("@")[0];
const redirectUri = params.redirect_uri;
const state = params.state || "";
codes.set(code, { email, name });
const redirectUrl = new URL(redirectUri);
redirectUrl.searchParams.set("code", code);
if (state) redirectUrl.searchParams.set("state", state);
res.writeHead(302, { Location: redirectUrl.toString() });
res.end();
return;
}
// Authorization
if (url.startsWith("/authorize") && method === "GET") {
const params = parseQuery(url);
const clientId = params.client_id;
const redirectUri = params.redirect_uri;
const state = params.state || "";
const scope = params.scope || "openid email profile";
const mockUser = params.mock_email || "demo@cosmic.local";
const mockName = params.mock_name || "Demo SSO User";
const body = htmlPage("Mock SSO Login",
`
Mock OIDC Provider
This is a simulated SSO login for development/demo purposes.
`
);
res.writeHead(200, { "Content-Type": "text/html" });
res.end(body);
return;
}
// Token
if (url === "/token" && method === "POST") {
let body = "";
req.on("data", chunk => body += chunk);
req.on("end", () => {
const params = new URLSearchParams(body);
const code = params.get("code");
const stored = codes.get(code);
if (!stored) {
res.writeHead(400, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: "invalid_grant", error_description: "Code not found" }));
return;
}
codes.delete(code);
const email = stored.email;
const name = stored.name;
const sub = base64Url(crypto.createHash("sha256").update(email).digest());
const now = Math.floor(Date.now() / 1000);
const accessToken = base64Url(crypto.randomBytes(32));
const idToken = encodeJwt({
iss: ISSUER,
sub,
aud: params.get("client_id") || "mock-client",
exp: now + 3600,
iat: now,
email,
email_verified: true,
name,
preferred_username: email.split("@")[0],
});
accessTokens.set(accessToken, { email, name, sub });
res.writeHead(200, { "Content-Type": "application/json", "Cache-Control": "no-store" });
res.end(JSON.stringify({
access_token: accessToken,
token_type: "Bearer",
expires_in: 3600,
id_token: idToken,
}));
});
return;
}
// JWKS
if (url === "/jwks" && method === "GET") {
res.writeHead(200, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" });
res.end(JSON.stringify({ keys: [] }));
return;
}
// Userinfo
if (url === "/userinfo" && method === "GET") {
const auth = req.headers.authorization || "";
const token = auth.replace("Bearer ", "");
const stored = accessTokens.get(token);
if (!stored) {
res.writeHead(401, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: "invalid_token" }));
return;
}
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ sub: stored.sub, email: stored.email, name: stored.name }));
return;
}
// 404
res.writeHead(404, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: "not_found", path: url }));
});
server.listen(PORT, () => {
console.log(`Mock OIDC provider listening on http://localhost:${PORT}`);
console.log(`Issuer: ${ISSUER}`);
});
module.exports = { server };