mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-04 09:38:50 +01:00
Discord Login (#615)
* Add files via upload * Create linode-setup.md * Create cloudflare-setup.md * Update cloudflare-setup.md * Delete 4-linode.png * Delete 3-linode.png * Add files via upload * Add files via upload * Update cloudflare-setup.md * Update linode-setup.md * Rename cloudflare-setup.md to cloudflare.md * Rename linode-setup.md to linode.md * Update mkdocs.yml * Update cloudflare.md * Update linode.md * Update README.md * Update README.md * Update linode.md sentence in Italian * v1 The frontend has been completed, along with the .env variables. However, there is an issue of infinite loading thereafter. * Fix email and remove deprecated GitHub passport * Update user_auth_system.md add How to Set Up a Github Authentication * Update .env.example Improved the comment above the GitHub client ID and secret. * Update user_auth_system.md * Update package.json * Remove unnecessary passport GitHub package * fixed conflicts fixed conflicts between Berry-13:main and danny-avila:main in api/server/index.js 45:54 * Delete e -i HEAD~2 * (WIP) Discord Login * Fix duplicate githubLoginEnabled * .env.example restore * Update user_auth_system.md Discord Login * Fix and new Feature 1. Added Discord login to .env.example. 2. Created Google, Github, and Discord icons in client\src\components\svg. 3. Added the social login option in the .env file; it fixes the ---or---. Check Discord for more information. * fix Login.tsx and Registration.tsx * Update user_auth_system.md * Update .env.example * Added OpenID Icon * quick discord icon fix * discord strategy fix * remove comment
This commit is contained in:
parent
c17c1488ca
commit
747e087cf5
21 changed files with 328 additions and 144 deletions
|
|
@ -75,6 +75,11 @@ const userSchema = mongoose.Schema(
|
|||
unique: true,
|
||||
sparse: true
|
||||
},
|
||||
discordId: {
|
||||
type: String,
|
||||
unique: true,
|
||||
sparse: true
|
||||
},
|
||||
plugins: {
|
||||
type: Array,
|
||||
default: []
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ config.validate(); // Validate the config
|
|||
if (process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET) {
|
||||
require('../strategies/githubStrategy');
|
||||
}
|
||||
if (process.env.DISCORD_CLIENT_ID && process.env.DISCORD_CLIENT_SECRET) {
|
||||
require('../strategies/discordStrategy');
|
||||
}
|
||||
if (process.env.OPENID_CLIENT_ID && process.env.OPENID_CLIENT_SECRET &&
|
||||
process.env.OPENID_ISSUER && process.env.OPENID_SCOPE &&
|
||||
process.env.OPENID_SESSION_SECRET) {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,11 @@ afterEach(() => {
|
|||
delete process.env.OPENID_AUTH_URL;
|
||||
delete process.env.GITHUB_CLIENT_ID;
|
||||
delete process.env.GITHUB_CLIENT_SECRET;
|
||||
delete process.env.DISCORD_CLIENT_ID;
|
||||
delete process.env.DISCORD_CLIENT_SECRET;
|
||||
delete process.env.DOMAIN_SERVER;
|
||||
delete process.env.ALLOW_REGISTRATION;
|
||||
delete process.env.ALLOW_SOCIAL_LOGIN;
|
||||
});
|
||||
|
||||
//TODO: This works/passes locally but http request tests fail with 404 in CI. Need to figure out why.
|
||||
|
|
@ -36,8 +39,11 @@ describe.skip('GET /', () => {
|
|||
process.env.OPENID_AUTH_URL= 'http://test-server.com';
|
||||
process.env.GITHUB_CLIENT_ID = 'Test Github client Id';
|
||||
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.DOMAIN_SERVER = 'http://test-server.com';
|
||||
process.env.ALLOW_REGISTRATION = 'true';
|
||||
process.env.ALLOW_SOCIAL_LOGIN = 'true';
|
||||
|
||||
const response = await request(app).get('/');
|
||||
|
||||
|
|
@ -49,8 +55,10 @@ describe.skip('GET /', () => {
|
|||
openidLabel: 'Test OpenID',
|
||||
openidImageUrl: 'http://test-server.com',
|
||||
githubLoginEnabled: true,
|
||||
discordLoginEnabled: true,
|
||||
serverDomain: 'http://test-server.com',
|
||||
registrationEnabled: 'true',
|
||||
socialLoginEnabled: 'true',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,10 +12,24 @@ router.get('/', async function (req, res) {
|
|||
const openidLabel = process.env.OPENID_BUTTON_LABEL || 'Login with OpenID';
|
||||
const openidImageUrl = process.env.OPENID_IMAGE_URL;
|
||||
const githubLoginEnabled = !!process.env.GITHUB_CLIENT_ID && !!process.env.GITHUB_CLIENT_SECRET;
|
||||
const discordLoginEnabled = !!process.env.DISCORD_CLIENT_ID && !!process.env.DISCORD_CLIENT_SECRET;
|
||||
const serverDomain = process.env.DOMAIN_SERVER || 'http://localhost:3080';
|
||||
const registrationEnabled = process.env.ALLOW_REGISTRATION === 'true';
|
||||
const socialLoginEnabled = process.env.ALLOW_SOCIAL_LOGIN === 'true';
|
||||
|
||||
return res.status(200).send({
|
||||
appTitle,
|
||||
googleLoginEnabled,
|
||||
openidLoginEnabled,
|
||||
openidLabel,
|
||||
openidImageUrl,
|
||||
githubLoginEnabled,
|
||||
discordLoginEnabled,
|
||||
serverDomain,
|
||||
registrationEnabled,
|
||||
socialLoginEnabled
|
||||
});
|
||||
|
||||
return res.status(200).send({appTitle, googleLoginEnabled, openidLoginEnabled, openidLabel, openidImageUrl, githubLoginEnabled, serverDomain, registrationEnabled});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return res.status(500).send({error: err.message});
|
||||
|
|
|
|||
|
|
@ -115,4 +115,32 @@ router.get(
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
router.get(
|
||||
'/discord',
|
||||
passport.authenticate('discord', {
|
||||
scope: ['identify', 'email'],
|
||||
session: false
|
||||
})
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/discord/callback',
|
||||
passport.authenticate('discord', {
|
||||
failureRedirect: `${domains.client}/login`,
|
||||
failureMessage: true,
|
||||
session: false,
|
||||
scope: ['identify', 'email']
|
||||
}),
|
||||
(req, res) => {
|
||||
const token = req.user.generateToken();
|
||||
res.cookie('token', token, {
|
||||
expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)),
|
||||
httpOnly: false,
|
||||
secure: isProduction
|
||||
});
|
||||
res.redirect(domains.client);
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
|||
57
api/strategies/discordStrategy.js
Normal file
57
api/strategies/discordStrategy.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
const passport = require('passport');
|
||||
const { Strategy: DiscordStrategy } = require('passport-discord');
|
||||
const User = require('../models/User');
|
||||
const config = require('../../config/loader');
|
||||
const domains = config.domains;
|
||||
|
||||
const discordLogin = new DiscordStrategy(
|
||||
{
|
||||
clientID: process.env.DISCORD_CLIENT_ID,
|
||||
clientSecret: process.env.DISCORD_CLIENT_SECRET,
|
||||
callbackURL: `${domains.server}${process.env.DISCORD_CALLBACK_URL}`,
|
||||
scope: ['identify', 'email'] // Request scopes
|
||||
},
|
||||
async (accessToken, refreshToken, profile, cb) => {
|
||||
try {
|
||||
const discordId = profile.id;
|
||||
const email = profile.email;
|
||||
|
||||
const existingUser = await User.findOne({ discordId });
|
||||
if (existingUser) {
|
||||
return cb(null, existingUser);
|
||||
}
|
||||
|
||||
const userWithEmail = await User.findOne({ email });
|
||||
if (userWithEmail) {
|
||||
userWithEmail.discordId = discordId;
|
||||
await userWithEmail.save();
|
||||
return cb(null, userWithEmail);
|
||||
}
|
||||
|
||||
let avatarURL;
|
||||
if (profile.avatar) {
|
||||
const format = profile.avatar.startsWith('a_') ? 'gif' : 'png';
|
||||
avatarURL = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;
|
||||
} else {
|
||||
const defaultAvatarNum = Number(profile.discriminator) % 5;
|
||||
avatarURL = `https://cdn.discordapp.com/embed/avatars/${defaultAvatarNum}.png`;
|
||||
}
|
||||
|
||||
const newUser = await User.create({
|
||||
provider: 'discord',
|
||||
discordId,
|
||||
username: profile.username,
|
||||
email,
|
||||
name: profile.global_name,
|
||||
avatar: avatarURL
|
||||
});
|
||||
|
||||
cb(null, newUser);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
cb(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
passport.use(discordLogin);
|
||||
|
|
@ -33,7 +33,7 @@ const githubLogin = new GitHubStrategy(
|
|||
email,
|
||||
emailVerified: profile.emails[0].verified,
|
||||
name: profile.displayName,
|
||||
avatar: profile.photos[0].value
|
||||
avatar: profile.photos[0].value
|
||||
}).save();
|
||||
|
||||
cb(null, newUser);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue