Compare commits

...

1 Commits

Author SHA1 Message Date
be810ba475 Scaffolding for OIDC 2024-02-29 09:38:50 -08:00
3 changed files with 170 additions and 0 deletions

View File

@ -53,6 +53,7 @@
"passport-github": "^1.1.0",
"passport-gitlab2": "^5.0.0",
"passport-google-oauth20": "^2.0.0",
"passport-openidconnect": "^0.1.2",
"pg": "^8.11.3",
"picomatch": "^3.0.1",
"pino": "^8.16.2",
@ -76,6 +77,7 @@
"@types/nodemailer": "^6.4.14",
"@types/passport-github": "^1.1.12",
"@types/passport-google-oauth20": "^2.0.14",
"@types/passport-openidconnect": "^0.1.3",
"@types/pg": "^8.10.9",
"@types/picomatch": "^2.3.3",
"@types/prompt-sync": "^4.2.3",
@ -4072,6 +4074,18 @@
"@types/passport": "*"
}
},
"node_modules/@types/passport-openidconnect": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@types/passport-openidconnect/-/passport-openidconnect-0.1.3.tgz",
"integrity": "sha512-k1Ni7bG/9OZNo2Qpjg2W6GajL+pww6ZPaNWMXfpteCX4dXf4QgaZLt2hjR5IiPrqwBT9+W8KjCTJ/uhGIoBx/g==",
"dev": true,
"dependencies": {
"@types/express": "*",
"@types/oauth": "*",
"@types/passport": "*",
"@types/passport-strategy": "*"
}
},
"node_modules/@types/passport-strategy": {
"version": "0.2.38",
"resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
@ -9794,6 +9808,27 @@
"url": "https://github.com/sponsors/jaredhanson"
}
},
"node_modules/passport-openidconnect": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/passport-openidconnect/-/passport-openidconnect-0.1.2.tgz",
"integrity": "sha512-JX3rTyW+KFZ/E9OF/IpXJPbyLO9vGzcmXB5FgSP2jfL3LGKJPdV7zUE8rWeKeeI/iueQggOeFa3onrCmhxXZTg==",
"dependencies": {
"oauth": "0.10.x",
"passport-strategy": "1.x.x"
},
"engines": {
"node": ">= 0.6.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/jaredhanson"
}
},
"node_modules/passport-openidconnect/node_modules/oauth": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.0.tgz",
"integrity": "sha512-1orQ9MT1vHFGQxhuy7E/0gECD3fd2fCC+PIX+/jgmU/gI3EpRocXtmtvxCO5x3WZ443FLTLFWNDjl5MPJf9u+Q=="
},
"node_modules/passport-strategy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",

View File

@ -41,6 +41,7 @@
"@types/nodemailer": "^6.4.14",
"@types/passport-github": "^1.1.12",
"@types/passport-google-oauth20": "^2.0.14",
"@types/passport-openidconnect": "^0.1.3",
"@types/pg": "^8.10.9",
"@types/picomatch": "^2.3.3",
"@types/prompt-sync": "^4.2.3",
@ -114,6 +115,7 @@
"passport-github": "^1.1.0",
"passport-gitlab2": "^5.0.0",
"passport-google-oauth20": "^2.0.0",
"passport-openidconnect": "^0.1.2",
"pg": "^8.11.3",
"picomatch": "^3.0.1",
"pino": "^8.16.2",

View File

@ -8,9 +8,12 @@
import { Authenticator } from "@fastify/passport";
import fastifySession from "@fastify/session";
// import { FastifyRequest } from "fastify";
import { Strategy as GitHubStrategy } from "passport-github";
import { Strategy as GitLabStrategy } from "passport-gitlab2";
import { Strategy as GoogleStrategy } from "passport-google-oauth20";
import { Strategy as OpenIDConnectStrategy } from "passport-openidconnect";
// const OpenIDConnectStrategy = require('passport-openidconnect');
import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
@ -133,6 +136,136 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
);
}
/**
* TODO:
* 1. Test w static config
* 2. Fetch config from db
*/
// const getOIDCConfiguration = (req: FastifyRequest, callback: any) => {
// // Fetching things from database or whatever
// const { username } = req.body as { username: string };
// process.nextTick(() => {
// const opts = {
// issuer: "",
// authorizationURL: "",
// tokenURL: "",
// userInfoURL: "",
// clientID: "",
// clientSecret: "",
// callbackURL: `${'test'}/api/sso/oidc`,
// // issuer: ISSUER_URL_OIDC_LOGIN,
// // authorizationURL: AUTHORIZATION_URL_OIDC_LOGIN,
// // tokenURL: TOKEN_URL_OIDC_LOGIN,
// // userInfoURL: USER_INFO_URL_OIDC_LOGIN,
// // clientID: CLIENT_ID_OIDC_LOGIN,
// // clientSecret: CLIENT_SECRET_OIDC_LOGIN,
// // callbackURL: `${SITE_URL}/api/sso/oidc`,
// scope: ['profile', 'email'],
// passReqToCallback: true
// }
// callback(null, opts);
// });
// };
const ISSUER_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/";
const AUTHORIZATION_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/oauth2/auth";
const TOKEN_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/oauth2/token";
const USER_INFO_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/userinfo";
const CLIENT_ID_OIDC_LOGIN = "";
const CLIENT_SECRET_OIDC_LOGIN = "";
const SITE_URL = "";
const config = {
issuer: ISSUER_URL_OIDC_LOGIN,
authorizationURL: AUTHORIZATION_URL_OIDC_LOGIN,
tokenURL: TOKEN_URL_OIDC_LOGIN,
userInfoURL: USER_INFO_URL_OIDC_LOGIN,
clientID: CLIENT_ID_OIDC_LOGIN,
clientSecret: CLIENT_SECRET_OIDC_LOGIN,
callbackURL: `${SITE_URL}/api/v1/sso/oidc`,
scope: ["profile", "email"],
passReqToCallback: true
};
if (config) {
passport.use(
new OpenIDConnectStrategy(config, (req: any, issuer: any, profile: any, done: any) => {
try {
console.log("oidc");
console.log("oidc issuer: ", issuer);
console.log("oidc profile: ", profile);
// const { name: { familyName, givenName }, emails } = profile;
done(null, profile);
} catch (err) {
console.log("oidc err: ", err);
done(null, false);
}
})
);
}
server.route({
url: "/login/oidc",
method: "GET",
preValidation: (req, res) => {
console.log("oidc login");
return (
passport.authenticate("openidconnect", {
session: false,
scope: ["profile", "email"]
}) as any
)(req, res);
},
handler: async (req, res) => {
console.log("oidc login 2");
if (req.passportUser) {
return res.code(200).send({ message: "Authentication successful", user: req.passportUser });
}
return res.code(401).send({ error: "Authentication failed" });
}
});
server.route({
url: "/oidc",
method: "GET",
preValidation: (req, res) => {
console.log("oidcx req: ", req); // code, state
return (
passport.authenticate("openidconnect", {
session: false,
failureRedirect: "/api/v1/sso/login/provider/error",
failureMessage: true
}) as any
)(req, res);
},
handler: (req, res) => {
console.log("oidc 3");
if (req.passportUser.isUserCompleted) {
// login
return res.redirect(`${SITE_URL}/login/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}`);
}
// signup
return res.redirect(`${SITE_URL}/signup/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}`);
}
});
server.route({
url: "/login/provider/error",
method: "GET",
handler: (req, res) => {
console.log("reqyx: ", req);
console.log("resyx: ", res);
return res.status(500).send({
error: "Authentication error",
details: req.query
});
}
});
server.route({
url: "/redirect/google",
method: "GET",