mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-23 03:40:14 +01:00
🔑 feat: SAML authentication (#6169)
* feat: add SAML authentication * refactor: change SAML icon * refactor: resolve SAML metadata paths using paths.js * test: add samlStrategy tests * fix: update setupSaml import * test: add SAML settings tests in config.spec.js * test: add client tests * refactor: improve SAML button label and fallback localization * feat: allow only one authentication method OpenID or SAML at a time * doc: add SAML configuration sample to docker-compose.override * fix: require SAML_SESSION_SECRET to enable SAML * feat: update samlStrategy * test: update samle tests * feat: add SAML login button label to translations and remove default value * fix: update SAML cert file binding * chore: update override example with SAML cert volume * fix: update SAML session handling with Redis backend --------- Co-authored-by: Ruben Talstra <RubenTalstra1211@outlook.com>
This commit is contained in:
parent
87255dac81
commit
939b4ce659
22 changed files with 1134 additions and 20 deletions
|
|
@ -24,6 +24,12 @@ afterEach(() => {
|
|||
delete process.env.GITHUB_CLIENT_SECRET;
|
||||
delete process.env.DISCORD_CLIENT_ID;
|
||||
delete process.env.DISCORD_CLIENT_SECRET;
|
||||
delete process.env.SAML_ENTRY_POINT;
|
||||
delete process.env.SAML_ISSUER;
|
||||
delete process.env.SAML_CERT;
|
||||
delete process.env.SAML_SESSION_SECRET;
|
||||
delete process.env.SAML_BUTTON_LABEL;
|
||||
delete process.env.SAML_IMAGE_URL;
|
||||
delete process.env.DOMAIN_SERVER;
|
||||
delete process.env.ALLOW_REGISTRATION;
|
||||
delete process.env.ALLOW_SOCIAL_LOGIN;
|
||||
|
|
@ -55,6 +61,12 @@ describe.skip('GET /', () => {
|
|||
process.env.GITHUB_CLIENT_SECRET = 'Test Github client Secret';
|
||||
process.env.DISCORD_CLIENT_ID = 'Test Discord client Id';
|
||||
process.env.DISCORD_CLIENT_SECRET = 'Test Discord client Secret';
|
||||
process.env.SAML_ENTRY_POINT = 'http://test-server.com';
|
||||
process.env.SAML_ISSUER = 'Test SAML Issuer';
|
||||
process.env.SAML_CERT = 'saml.pem';
|
||||
process.env.SAML_SESSION_SECRET = 'Test Secret';
|
||||
process.env.SAML_BUTTON_LABEL = 'Test SAML';
|
||||
process.env.SAML_IMAGE_URL = 'http://test-server.com';
|
||||
process.env.DOMAIN_SERVER = 'http://test-server.com';
|
||||
process.env.ALLOW_REGISTRATION = 'true';
|
||||
process.env.ALLOW_SOCIAL_LOGIN = 'true';
|
||||
|
|
@ -70,7 +82,7 @@ describe.skip('GET /', () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual({
|
||||
appTitle: 'Test Title',
|
||||
socialLogins: ['google', 'facebook', 'openid', 'github', 'discord'],
|
||||
socialLogins: ['google', 'facebook', 'openid', 'github', 'discord', 'saml'],
|
||||
discordLoginEnabled: true,
|
||||
facebookLoginEnabled: true,
|
||||
githubLoginEnabled: true,
|
||||
|
|
@ -78,6 +90,9 @@ describe.skip('GET /', () => {
|
|||
openidLoginEnabled: true,
|
||||
openidLabel: 'Test OpenID',
|
||||
openidImageUrl: 'http://test-server.com',
|
||||
samlLoginEnabled: true,
|
||||
samlLabel: 'Test SAML',
|
||||
samlImageUrl: 'http://test-server.com',
|
||||
ldap: {
|
||||
enabled: true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -37,6 +37,18 @@ router.get('/', async function (req, res) {
|
|||
const ldap = getLdapConfig();
|
||||
|
||||
try {
|
||||
const isOpenIdEnabled =
|
||||
!!process.env.OPENID_CLIENT_ID &&
|
||||
!!process.env.OPENID_CLIENT_SECRET &&
|
||||
!!process.env.OPENID_ISSUER &&
|
||||
!!process.env.OPENID_SESSION_SECRET;
|
||||
|
||||
const isSamlEnabled =
|
||||
!!process.env.SAML_ENTRY_POINT &&
|
||||
!!process.env.SAML_ISSUER &&
|
||||
!!process.env.SAML_CERT &&
|
||||
!!process.env.SAML_SESSION_SECRET;
|
||||
|
||||
/** @type {TStartupConfig} */
|
||||
const payload = {
|
||||
appTitle: process.env.APP_TITLE || 'LibreChat',
|
||||
|
|
@ -51,14 +63,13 @@ router.get('/', async function (req, res) {
|
|||
!!process.env.APPLE_TEAM_ID &&
|
||||
!!process.env.APPLE_KEY_ID &&
|
||||
!!process.env.APPLE_PRIVATE_KEY_PATH,
|
||||
openidLoginEnabled:
|
||||
!!process.env.OPENID_CLIENT_ID &&
|
||||
!!process.env.OPENID_CLIENT_SECRET &&
|
||||
!!process.env.OPENID_ISSUER &&
|
||||
!!process.env.OPENID_SESSION_SECRET,
|
||||
openidLoginEnabled: isOpenIdEnabled,
|
||||
openidLabel: process.env.OPENID_BUTTON_LABEL || 'Continue with OpenID',
|
||||
openidImageUrl: process.env.OPENID_IMAGE_URL,
|
||||
openidAutoRedirect: isEnabled(process.env.OPENID_AUTO_REDIRECT),
|
||||
samlLoginEnabled: !isOpenIdEnabled && isSamlEnabled,
|
||||
samlLabel: process.env.SAML_BUTTON_LABEL,
|
||||
samlImageUrl: process.env.SAML_IMAGE_URL,
|
||||
serverDomain: process.env.DOMAIN_SERVER || 'http://localhost:3080',
|
||||
emailLoginEnabled,
|
||||
registrationEnabled: !ldap?.enabled && isEnabled(process.env.ALLOW_REGISTRATION),
|
||||
|
|
|
|||
|
|
@ -189,4 +189,24 @@ router.post(
|
|||
oauthHandler,
|
||||
);
|
||||
|
||||
/**
|
||||
* SAML Routes
|
||||
*/
|
||||
router.get(
|
||||
'/saml',
|
||||
passport.authenticate('saml', {
|
||||
session: false,
|
||||
}),
|
||||
);
|
||||
|
||||
router.post(
|
||||
'/saml/callback',
|
||||
passport.authenticate('saml', {
|
||||
failureRedirect: `${domains.client}/oauth/error`,
|
||||
failureMessage: true,
|
||||
session: false,
|
||||
}),
|
||||
oauthHandler,
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue