📩 feat: invite user (#3012)

* feat: basic invite-user script

* feat: add invite user functionality and registration validation middleware

* fix: invite user fixes

* refactor: consolidate direct model access to a central place of functions

* style(Registration): add spinner to continue button

* refactor: import ordrer

* feat: improve invite user script and error handling

* fix: merge conflict

* refactor: remove `console.log` and use `logger`

* fix: token operation and checkinvite issues

* bring back comment and remove console log

* fix: return invalid token when token is not found

* fix: getInvite fix

* refactor: Update Token.js to use async/await syntax for update and delete operations

* feat: Refactor Token.js to use async/await syntax for createToken and findToken functions

* refactor(inviteUser): define functions outside of module.exports

* Update AuthService.js

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
Marco Beretta 2024-08-18 06:23:38 +02:00 committed by GitHub
parent a45b384bbc
commit bbb9324447
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 695 additions and 61 deletions

View file

@ -10,12 +10,11 @@ const {
generateToken,
deleteUserById,
} = require('~/models/userMethods');
const { createToken, findToken, deleteTokens, Session } = require('~/models');
const { sendEmail, checkEmailConfig } = require('~/server/utils');
const { registerSchema } = require('~/strategies/validators');
const { hashToken } = require('~/server/utils/crypto');
const isDomainAllowed = require('./isDomainAllowed');
const Token = require('~/models/schema/tokenSchema');
const Session = require('~/models/Session');
const { logger } = require('~/config');
const domains = {
@ -87,12 +86,13 @@ const sendVerificationEmail = async (user) => {
template: 'verifyEmail.handlebars',
});
await new Token({
await createToken({
userId: user._id,
email: user.email,
token: hash,
createdAt: Date.now(),
}).save();
expiresIn: 900,
});
logger.info(`[sendVerificationEmail] Verification link issued. [Email: ${user.email}]`);
};
@ -103,7 +103,7 @@ const sendVerificationEmail = async (user) => {
*/
const verifyEmail = async (req) => {
const { email, token } = req.body;
let emailVerificationData = await Token.findOne({ email: decodeURIComponent(email) });
let emailVerificationData = await findToken({ email: decodeURIComponent(email) });
if (!emailVerificationData) {
logger.warn(`[verifyEmail] [No email verification data found] [Email: ${email}]`);
@ -123,7 +123,7 @@ const verifyEmail = async (req) => {
return new Error('User not found');
}
await emailVerificationData.deleteOne();
await deleteTokens({ token: emailVerificationData.token });
logger.info(`[verifyEmail] Email verification successful. [Email: ${email}]`);
return { message: 'Email verification was successful' };
};
@ -231,18 +231,16 @@ const requestPasswordReset = async (req) => {
};
}
let token = await Token.findOne({ userId: user._id });
if (token) {
await token.deleteOne();
}
await deleteTokens({ userId: user._id });
const [resetToken, hash] = createTokenHash();
await new Token({
await createToken({
userId: user._id,
token: hash,
createdAt: Date.now(),
}).save();
expiresIn: 900,
});
const link = `${domains.client}/reset-password?token=${resetToken}&userId=${user._id}`;
@ -282,7 +280,10 @@ const requestPasswordReset = async (req) => {
* @returns
*/
const resetPassword = async (userId, token, password) => {
let passwordResetToken = await Token.findOne({ userId });
let passwordResetToken = await createToken({
userId,
expiresIn: 900,
});
if (!passwordResetToken) {
return new Error('Invalid or expired password reset token');
@ -366,7 +367,7 @@ const setAuthTokens = async (userId, res, sessionId = null) => {
const resendVerificationEmail = async (req) => {
try {
const { email } = req.body;
await Token.deleteMany({ email });
await deleteTokens(email);
const user = await findUser({ email }, 'email _id name');
if (!user) {
@ -392,12 +393,13 @@ const resendVerificationEmail = async (req) => {
template: 'verifyEmail.handlebars',
});
await new Token({
await createToken({
userId: user._id,
email: user.email,
token: hash,
createdAt: Date.now(),
}).save();
expiresIn: 900,
});
logger.info(`[resendVerificationEmail] Verification link issued. [Email: ${user.email}]`);