diff --git a/web/routes/evotor_webhooks.py b/web/routes/evotor_webhooks.py index 7bcf37f..b25d10a 100644 --- a/web/routes/evotor_webhooks.py +++ b/web/routes/evotor_webhooks.py @@ -17,7 +17,7 @@ from fastapi.responses import JSONResponse from sqlalchemy import or_ from sqlalchemy.orm import Session -from web.auth.password import verify_password +from web.auth.password import hash_password, verify_password from web.config import settings from web.database import get_db from web.models.connections import EvotorConnection @@ -108,6 +108,7 @@ async def user_create(request: Request, db: Session = Depends(get_db)): first_name = (body.get("first_name") or body.get("firstName") or custom.get("first_name") or custom.get("firstName") or "").strip() or None last_name = (body.get("second_name") or body.get("last_name") or body.get("lastName") or custom.get("second_name") or custom.get("last_name") or custom.get("lastName") or "").strip() or None middle_name = (body.get("middle_name") or custom.get("middle_name") or "").strip() or None + password = (body.get("password") or custom.get("password") or "").strip() or None # Try to find existing user user: User | None = None @@ -135,20 +136,22 @@ async def user_create(request: Request, db: Session = Depends(get_db)): user.last_name = last_name if middle_name: user.middle_name = middle_name + if password and not user.password_hash: + user.password_hash = hash_password(password) if user.status == UserStatusEnum.pending: user.status = UserStatusEnum.active db.flush() else: - # Create new pending user + # Create new user; active immediately if password provided, else pending user = User( first_name=first_name or "", last_name=last_name or "", middle_name=middle_name, email=email or f"{evotor_user_id}@evotor.invalid", phone=phone or None, - password_hash=None, + password_hash=hash_password(password) if password else None, role=UserRoleEnum.user, - status=UserStatusEnum.pending, + status=UserStatusEnum.active if password else UserStatusEnum.pending, evotor_user_id=evotor_user_id, evotor_meta=body, created_at=now, @@ -157,27 +160,28 @@ async def user_create(request: Request, db: Session = Depends(get_db)): db.add(user) db.flush() # get user.id - # Generate invite - invite_token = secrets.token_urlsafe(32) - user.invite_token = invite_token - user.invite_expires = now + timedelta(hours=settings.INVITE_EXPIRE_HOURS) - api_token = _upsert_evotor_connection(db, user.id, evotor_user_id) - db.commit() - # Send invite email if we have a real email address - if email: - invite_url = f"{settings.BASE_URL}/invite?token={invite_token}" - html = ( - f"

Здравствуйте!

" - f"

Вам открыт доступ к ЭВОСИНК. Завершите регистрацию по ссылке:

" - f'

{invite_url}

' - f"

Ссылка действительна {settings.INVITE_EXPIRE_HOURS} часов.

" - ) - send_email_task.delay(email, "Приглашение в ЭВОСИНК", html) + if not password: + # No password provided — send invite link so user can set one + invite_token = secrets.token_urlsafe(32) + user.invite_token = invite_token + user.invite_expires = now + timedelta(hours=settings.INVITE_EXPIRE_HOURS) + db.commit() + if email: + invite_url = f"{settings.BASE_URL}/invite?token={invite_token}" + html = ( + f"

Здравствуйте!

" + f"

Вам открыт доступ к ЭВОСИНК. Завершите регистрацию по ссылке:

" + f'

{invite_url}

' + f"

Ссылка действительна {settings.INVITE_EXPIRE_HOURS} часов.

" + ) + send_email_task.delay(email, "Приглашение в ЭВОСИНК", html) + else: + logger.info("No email for evotor_user_id=%s, invite URL: %s/invite?token=%s", + evotor_user_id, settings.BASE_URL, invite_token) else: - logger.info("No email for evotor_user_id=%s, invite URL: %s/invite?token=%s", - evotor_user_id, settings.BASE_URL, invite_token) + db.commit() return JSONResponse({"userId": evotor_user_id, "token": api_token})