diff --git a/apps/api/src/core/events/database.py b/apps/api/src/core/events/database.py index b38712b2..01318298 100644 --- a/apps/api/src/core/events/database.py +++ b/apps/api/src/core/events/database.py @@ -5,7 +5,7 @@ from sqlmodel import SQLModel, Session, create_engine learnhouse_config = get_learnhouse_config() engine = create_engine( - learnhouse_config.database_config.sql_connection_string, echo=False # type: ignore + learnhouse_config.database_config.sql_connection_string, echo=False, pool_pre_ping=True # type: ignore ) SQLModel.metadata.create_all(engine) @@ -16,8 +16,6 @@ async def connect_to_db(app: FastAPI): SQLModel.metadata.create_all(engine) - - def get_db_session(): with Session(engine) as session: yield session diff --git a/apps/api/src/services/orgs/users.py b/apps/api/src/services/orgs/users.py index 28422fb5..fa5e2099 100644 --- a/apps/api/src/services/orgs/users.py +++ b/apps/api/src/services/orgs/users.py @@ -234,6 +234,7 @@ async def invite_batch_users( request: Request, org_id: int, emails: str, + invite_code_uuid: str, db_session: Session, current_user: PublicUser | AnonymousUser, ): @@ -272,8 +273,8 @@ async def invite_batch_users( invite_list = emails.split(",") - # invitations expire after 30 days - ttl = int(timedelta(days=365).total_seconds()) + # invitations expire after 60 days + ttl = int(timedelta(days=60).total_seconds()) for email in invite_list: email = email.strip() @@ -289,6 +290,7 @@ async def invite_batch_users( invited_user_object = { "email": email, "org_id": org.id, + "invite_code_uuid": invite_code_uuid, "pending": True, "email_sent": False, "expires": ttl, diff --git a/apps/api/src/services/users/users.py b/apps/api/src/services/users/users.py index 8d208b32..279a9aec 100644 --- a/apps/api/src/services/users/users.py +++ b/apps/api/src/services/users/users.py @@ -104,6 +104,7 @@ async def create_user( return user + async def create_user_with_invite( request: Request, db_session: Session, @@ -112,20 +113,23 @@ async def create_user_with_invite( org_id: int, invite_code: str, ): - + # Check if invite code exists - isInviteCodeCorrect = await get_invite_code(request, org_id, invite_code, current_user, db_session) + isInviteCodeCorrect = await get_invite_code( + request, org_id, invite_code, current_user, db_session + ) if not isInviteCodeCorrect: raise HTTPException( status_code=400, detail="Invite code is incorrect", ) - + user = await create_user(request, db_session, current_user, user_object, org_id) return user + async def create_user_without_org( request: Request, db_session: Session, @@ -201,6 +205,32 @@ async def update_user( # RBAC check await rbac_check(request, current_user, "update", user.user_uuid, db_session) + # Verifications + + # Username + statement = select(User).where(User.username == user_object.username) + username_user = db_session.exec(statement).first() + + if username_user: + isSameUser = username_user.id == current_user.id + if not isSameUser: + raise HTTPException( + status_code=400, + detail="Username already exists", + ) + + # Email + statement = select(User).where(User.email == user_object.email) + email_user = db_session.exec(statement).first() + + if email_user: + isSameUser = email_user.id == current_user.id + if not isSameUser: + raise HTTPException( + status_code=400, + detail="Email already exists", + ) + # Update user user_data = user_object.dict(exclude_unset=True) for key, value in user_data.items(): @@ -239,7 +269,9 @@ async def update_user_avatar( # Upload thumbnail if avatar_file and avatar_file.filename: - name_in_disk = f"{user.user_uuid}_avatar_{uuid4()}.{avatar_file.filename.split('.')[-1]}" + name_in_disk = ( + f"{user.user_uuid}_avatar_{uuid4()}.{avatar_file.filename.split('.')[-1]}" + ) await upload_avatar(avatar_file, name_in_disk, user.user_uuid) # Update course diff --git a/apps/web/components/Dashboard/UserAccount/UserEditPassword/UserEditPassword.tsx b/apps/web/components/Dashboard/UserAccount/UserEditPassword/UserEditPassword.tsx index 510ff9de..de1ec79f 100644 --- a/apps/web/components/Dashboard/UserAccount/UserEditPassword/UserEditPassword.tsx +++ b/apps/web/components/Dashboard/UserAccount/UserEditPassword/UserEditPassword.tsx @@ -7,7 +7,7 @@ function UserEditPassword() { const session = useSession() as any const updatePasswordUI = async (values: any) => { - let user_id = session.user.user_id + let user_id = session.user.id await updatePassword(user_id, values) } diff --git a/apps/web/services/settings/password.ts b/apps/web/services/settings/password.ts index 8d2ba273..b5ff0331 100644 --- a/apps/web/services/settings/password.ts +++ b/apps/web/services/settings/password.ts @@ -8,7 +8,7 @@ import { RequestBody, errorHandling } from '@services/utils/ts/requests' export async function updatePassword(user_id: string, data: any) { const result: any = await fetch( - `${getAPIUrl()}users/password/user_id/` + user_id, + `${getAPIUrl()}users/change_password/` + user_id, RequestBody('PUT', data, null) ) const res = await errorHandling(result)