diff --git a/controller/auth/kratos.py b/controller/auth/kratos.py index 178b29bb..a93c09ef 100644 --- a/controller/auth/kratos.py +++ b/controller/auth/kratos.py @@ -25,6 +25,18 @@ KRATOS_IDENTITY_CACHE: Dict[str, Any] = {} KRATOS_IDENTITY_CACHE_TIMEOUT = timedelta(minutes=30) +LANGUAGE_MESSAGES = { + "en": "Hello!\n\nClick the link to complete your account setup:\n\n", + "de": "Hallo!\n\nKlicken Sie auf den Link, um Ihre Kontoeinrichtung abzuschließen:\n\n", +} + +INVITATION_SUBJECT = "Sie sind zu unserer app eingeladen/You are invited to our app" + +LANGUAGE_EXPIRATION_INFO = { + "en": "This link can only be clicked once and is valid for 2 days. Contact your system admin if you have issues.", + "de": "Dieser Link kann nur einmal angeklickt werden und ist 2 Tage lang gültig. Kontaktieren Sie Ihren Systemadministrator, wenn Sie Probleme haben.", +} + def get_cached_values(update_db_users: bool = True) -> Dict[str, Dict[str, Any]]: global KRATOS_IDENTITY_CACHE @@ -239,9 +251,9 @@ def get_recovery_link(user_id: str) -> str: def email_with_link(to_email: str, recovery_link: str) -> None: msg = MIMEText( - f"Welcome! Click the link to complete your account setup:\n\n{recovery_link}" + f"{LANGUAGE_MESSAGES['de']}{recovery_link}\n\n{LANGUAGE_EXPIRATION_INFO['de']}\n\n\n------\n\n{LANGUAGE_MESSAGES['en']}{recovery_link}\n\n{LANGUAGE_EXPIRATION_INFO['en']}", ) - msg["Subject"] = "You're invited to our app!" + msg["Subject"] = INVITATION_SUBJECT msg["From"] = "no-reply@kern.ai" msg["To"] = to_email diff --git a/controller/auth/manager.py b/controller/auth/manager.py index f3bcca27..d75154f7 100644 --- a/controller/auth/manager.py +++ b/controller/auth/manager.py @@ -177,6 +177,7 @@ def invite_users( emails: List[str], organization_name: str, user_role: str, + language: str, provider: Optional[str] = None, ): user_ids = [] @@ -192,6 +193,9 @@ def invite_users( # Assign the user role user_manager.update_user_role(user["id"], user_role) + # Add the preferred language + user_manager.update_user_field(user["id"], "language_display", language) + # Get the recovery link for the email recovery_link = kratos.get_recovery_link(user["id"]) if not recovery_link: diff --git a/fast_api/models.py b/fast_api/models.py index ab44f950..62115d65 100644 --- a/fast_api/models.py +++ b/fast_api/models.py @@ -503,6 +503,7 @@ class InviteUsersBody(BaseModel): organization_name: StrictStr provider: Optional[StrictStr] = None user_role: StrictStr + language: StrictStr class CheckInviteUsersBody(BaseModel): diff --git a/fast_api/routes/misc.py b/fast_api/routes/misc.py index aae1f4a9..cd72f32d 100644 --- a/fast_api/routes/misc.py +++ b/fast_api/routes/misc.py @@ -294,7 +294,11 @@ def invite_users(request: Request, body: InviteUsersBody = Body(...)): if not auth.check_is_full_admin(request): raise AuthManagerError("Full admin access required") data = auth.invite_users( - body.emails, body.organization_name, body.user_role, body.provider + body.emails, + body.organization_name, + body.user_role, + body.language, + body.provider, ) return pack_json_result(data) diff --git a/tests/fast_api/routes/test_invite_users.py b/tests/fast_api/routes/test_invite_users.py index a7fddc9a..c8d7a802 100644 --- a/tests/fast_api/routes/test_invite_users.py +++ b/tests/fast_api/routes/test_invite_users.py @@ -57,6 +57,7 @@ def test_invite_users(client: TestClient, org: Organization): "organization_name": org.name, "emails": valid_emails_to_test, "user_role": UserRoles.ENGINEER.value, + "language": "en", }, ) assert response.status_code == 200