Add LDAP and OpenID Connect authentication

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/f53b9394-0261-478c-aa14-813efc485813.jpg
This commit is contained in:
alphaeusmote
2025-04-10 02:01:11 +00:00
parent 0699f5acfa
commit 0dc4a0b8cc
5 changed files with 173 additions and 5 deletions
+38 -4
View File
@@ -3,7 +3,7 @@ import { Strategy as LocalStrategy } from "passport-local";
import { Strategy as JwtStrategy, ExtractJwt } from "passport-jwt";
import LdapStrategy from "passport-ldapauth";
import { Strategy as OpenIDStrategy } from "passport-openidconnect";
import { Express } from "express";
import { Express, Request, Response, NextFunction } from "express";
import session from "express-session";
import { scrypt, randomBytes, timingSafeEqual } from "crypto";
import { promisify } from "util";
@@ -140,7 +140,7 @@ export function setupAuth(app: Express) {
// OpenID Connect authentication strategy
if (process.env.OIDC_ENABLED === "true") {
passport.use(
new OpenIDConnectStrategy(
new OpenIDStrategy(
{
issuer: process.env.OIDC_ISSUER,
authorizationURL: process.env.OIDC_AUTHORIZATION_URL,
@@ -151,7 +151,7 @@ export function setupAuth(app: Express) {
callbackURL: process.env.OIDC_CALLBACK_URL || "http://localhost:3000/api/auth/oidc/callback",
scope: ["openid", "profile", "email"],
},
async (issuer, profile, done) => {
async (issuer: string, profile: any, done: any) => {
try {
const { id, displayName, emails } = profile;
@@ -236,7 +236,7 @@ export function setupAuth(app: Express) {
}
});
// Login endpoint
// Login endpoint (local strategy)
app.post("/api/login", (req, res, next) => {
passport.authenticate("local", (err: any, user: any, info: any) => {
if (err) return next(err);
@@ -251,6 +251,40 @@ export function setupAuth(app: Express) {
});
})(req, res, next);
});
// LDAP authentication routes
if (process.env.LDAP_ENABLED === "true") {
// LDAP login endpoint
app.post("/api/auth/ldap", (req, res, next) => {
passport.authenticate("ldapauth", (err: any, user: any, info: any) => {
if (err) return next(err);
if (!user) {
return res.status(401).json({ message: info?.message || "LDAP authentication failed" });
}
req.login(user, (loginErr) => {
if (loginErr) return next(loginErr);
// Remove password from response
const userResponse = { ...user, password: undefined };
res.json(userResponse);
});
})(req, res, next);
});
}
// OpenID Connect authentication routes
if (process.env.OIDC_ENABLED === "true") {
// OIDC login initiation
app.get("/api/auth/oidc", passport.authenticate("openidconnect"));
// OIDC callback
app.get("/api/auth/oidc/callback",
passport.authenticate("openidconnect", { failureRedirect: "/auth" }),
(req: Request, res: Response) => {
// Successful authentication, redirect to the main application
res.redirect("/");
}
);
}
// Logout endpoint
app.post("/api/logout", (req, res, next) => {
+10
View File
@@ -168,6 +168,16 @@ export class DatabaseStorage implements IStorage {
const result = await db.select().from(users).where(eq(users.username, username));
return result.length > 0 ? result[0] : undefined;
}
async getUserByProviderUserId(provider: string, providerUserId: string): Promise<User | undefined> {
const result = await db.select().from(users).where(
and(
eq(users.authProvider, provider),
eq(users.providerUserId, providerUserId)
)
);
return result.length > 0 ? result[0] : undefined;
}
async createUser(insertUser: InsertUser): Promise<User> {
const result = await db.insert(users).values(insertUser).returning();