Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@
"filename": "press/auth.py",
"hashed_secret": "e9e1dcecdf9da58fdf07a40a711afbbe9bfe3697",
"is_verified": false,
"line_number": 10
"line_number": 11
}
],
"press/fixtures/press_method_permission.json": [
Expand Down Expand Up @@ -547,5 +547,5 @@
}
]
},
"generated_at": "2026-04-15T16:58:31Z"
"generated_at": "2026-04-16T11:06:58Z"
}
5 changes: 3 additions & 2 deletions press/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import frappe
import frappe.utils
import requests
from frappe import _
from frappe.utils.password import get_decrypted_password
from requests.exceptions import HTTPError

Expand Down Expand Up @@ -1807,7 +1808,7 @@ def backup_site_database_from_snapshot(
if offsite_config:
data.update({"offsite": offsite_config})
else:
frappe.throw("Offsite Backups aren't setup yet")
frappe.throw(_("Offsite Backups aren't setup yet"))

return self.create_agent_job(
"Backup Database From Snapshot",
Expand Down Expand Up @@ -1836,7 +1837,7 @@ def backup_site_files_from_snapshot(
if offsite_config:
data.update({"offsite": offsite_config})
else:
frappe.throw("Offsite Backups aren't setup yet")
frappe.throw(_("Offsite Backups aren't setup yet"))

return self.create_agent_job(
"Backup Files From Snapshot",
Expand Down
5 changes: 3 additions & 2 deletions press/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import frappe
from frappe import _

from press.api.client import dashboard_whitelist
from press.utils import get_full_chain_cert_of_domain, get_minified_script, get_minified_script_2, log_error
Expand Down Expand Up @@ -30,10 +31,10 @@ def download_ssl_cert(domain: str):
not (domain.endswith("frappe.cloud") or domain.endswith("frappecloud.com"))
and not frappe.conf.developer_mode
):
frappe.throw("Invalid domain provided")
frappe.throw(_("Invalid domain provided"))

try:
return get_full_chain_cert_of_domain(domain)
except Exception as e:
log_error("Error downloading SSL certificate", data=e)
frappe.throw("Failed to download SSL certificate. Please try again later.")
frappe.throw(_("Failed to download SSL certificate. Please try again later."))
8 changes: 6 additions & 2 deletions press/api/access.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
@typing_validations.validate_argument_types
def status(doctype: str, docname: str):
if not support_access.has_support_access(doctype, docname):
frappe.throw("You do not have support access to this document", frappe.PermissionError) # nosemgrep
frappe.throw(
frappe._("You do not have support access to this document"), frappe.PermissionError
) # nosemgrep

AccessRequest = frappe.qb.DocType("Support Access")
AccessRequestResource = frappe.qb.DocType("Support Access Resource")
Expand All @@ -30,7 +32,9 @@ def status(doctype: str, docname: str):
results = query.run(as_dict=True)

if len(results) == 0:
frappe.throw("You do not have support access to this document.", frappe.PermissionError) # nosemgrep
frappe.throw(
frappe._("You do not have support access to this document."), frappe.PermissionError
) # nosemgrep

until = results[0].access_allowed_till

Expand Down
80 changes: 43 additions & 37 deletions press/api/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ def verify_otp(account_request: str, otp: str) -> str:
and not account_request_doc.product_trial
):
ip_tracker and ip_tracker.add_failure_attempt()
frappe.throw("Invalid OTP. Please try again.")
frappe.throw(_("Invalid OTP. Please try again."))
if account_request_doc.otp != otp:
ip_tracker and ip_tracker.add_failure_attempt()
frappe.throw("Invalid OTP. Please try again.")
frappe.throw(_("Invalid OTP. Please try again."))

ip_tracker and ip_tracker.add_success_attempt()
account_request_doc.reset_otp()
Expand All @@ -114,14 +114,14 @@ def verify_otp_and_login(email: str, otp: str):
account_request = frappe.db.get_value("Account Request", {"email": email}, "name")

if not account_request:
frappe.throw("Please sign up first")
frappe.throw(_("Please sign up first"))

account_request_doc: "AccountRequest" = frappe.get_doc("Account Request", account_request)
ip_tracker = get_login_attempt_tracker(frappe.local.request_ip)

if account_request_doc.otp != otp:
ip_tracker and ip_tracker.add_failure_attempt()
frappe.throw("Invalid OTP. Please try again.")
frappe.throw(_("Invalid OTP. Please try again."))

ip_tracker and ip_tracker.add_success_attempt()
account_request_doc.reset_otp()
Expand All @@ -139,14 +139,14 @@ def resend_otp(account_request: str, for_2fa_keys: bool = False):
account_request_doc.otp_generated_at
and (frappe.utils.now_datetime() - account_request_doc.otp_generated_at).seconds < 30
):
frappe.throw("Please wait for 30 seconds before requesting a new OTP")
frappe.throw(_("Please wait for 30 seconds before requesting a new OTP"))

# ensure no team has been created with this email
if (
frappe.db.exists("Team", {"user": account_request_doc.email})
and not account_request_doc.product_trial
):
frappe.throw("Invalid Email")
frappe.throw(_("Invalid Email"))
account_request_doc.reset_otp()
account_request_doc.send_otp_mail(for_login=not for_2fa_keys)

Expand All @@ -157,7 +157,7 @@ def send_otp(email: str, for_2fa_keys: bool = False):
account_request = frappe.db.get_value("Account Request", {"email": email}, "name")

if not account_request or (account_request and not frappe.db.exists("User", email)):
frappe.throw("Please sign up first")
frappe.throw(_("Please sign up first"))

account_request_doc: "AccountRequest" = frappe.get_doc("Account Request", account_request)

Expand All @@ -166,7 +166,7 @@ def send_otp(email: str, for_2fa_keys: bool = False):
account_request_doc.otp_generated_at
and (frappe.utils.now_datetime() - account_request_doc.otp_generated_at).seconds < 30
):
frappe.throw("Please wait for 30 seconds before requesting a new OTP")
frappe.throw(_("Please wait for 30 seconds before requesting a new OTP"))

account_request_doc.reset_otp()
account_request_doc.send_otp_mail(for_login=not for_2fa_keys)
Expand All @@ -190,20 +190,20 @@ def setup_account( # noqa: C901
):
account_request = get_account_request_from_key(key)
if not account_request:
frappe.throw("Invalid or Expired Key")
frappe.throw(_("Invalid or Expired Key"))

if not user_exists:
if not first_name:
frappe.throw("First Name is required")
frappe.throw(_("First Name is required"))

if not is_invitation and not country:
frappe.throw("Country is required")
frappe.throw(_("Country is required"))

if not is_invitation and country:
all_countries = frappe.db.get_all("Country", pluck="name")
country = find(all_countries, lambda x: x.lower() == country.lower())
if not country:
frappe.throw("Please provide a valid country name")
frappe.throw(_("Please provide a valid country name"))

# if the request is authenticated, set the user to Administrator
frappe.set_user("Administrator")
Expand Down Expand Up @@ -263,14 +263,16 @@ def accept_team_invite(key: str):
account_request = get_account_request_from_key(key)

if not account_request:
frappe.throw("Invalid or Expired Key")
frappe.throw(_("Invalid or Expired Key"))

if not account_request.invited_by:
frappe.throw("You are not invited by any team")
frappe.throw(_("You are not invited by any team"))

if frappe.session.user != account_request.email:
frappe.throw(
"This invite can't be accepted with the current account. Please sign in with the invited account or request a new invite."
_(
"This invite can't be accepted with the current account. Please sign in with the invited account or request a new invite."
)
)

team = account_request.team
Expand All @@ -291,7 +293,7 @@ def accept_team_invite(key: str):
@rate_limit(limit=5, seconds=60 * 60)
def send_login_link(email):
if not frappe.db.exists("User", email):
frappe.throw("No registered account with this email address")
frappe.throw(_("No registered account with this email address"))

key = frappe.generate_hash("Login Link", 20)
minutes = 10
Expand Down Expand Up @@ -347,12 +349,12 @@ def disable_account(totp_code: str | None):

if is_2fa_enabled(user):
if not totp_code:
frappe.throw("2FA Code is required")
frappe.throw(_("2FA Code is required"))
if not verify_2fa(user, totp_code):
frappe.throw("Invalid 2FA Code")
frappe.throw(_("Invalid 2FA Code"))

if user != team.user:
frappe.throw("Only team owner can disable the account")
frappe.throw(_("Only team owner can disable the account"))

team.disable_account()

Expand All @@ -366,7 +368,7 @@ def has_active_servers(team):
def enable_account():
team = get_current_team(get_doc=True)
if frappe.session.user != team.user:
frappe.throw("Only team owner can enable the account")
frappe.throw(_("Only team owner can enable the account"))
team.enable_account()


Expand Down Expand Up @@ -632,9 +634,9 @@ def create_child_team(title):
if title in [
d.team_title for d in frappe.get_all("Team", {"parent_team": current_team.name}, ["team_title"])
]:
frappe.throw(f"Child Team {title} already exists.")
frappe.throw(_("Child Team {0} already exists.").format(title))
elif title == "Parent Team":
frappe.throw("Child team name cannot be same as parent team")
frappe.throw(_("Child team name cannot be same as parent team"))

doc = frappe.get_doc(
{
Expand Down Expand Up @@ -689,7 +691,7 @@ def update_profile(first_name=None, last_name=None, email=None):
frappe.utils.validate_email_address(email, True)
STR_FORMAT = re.compile("^[a-zA-Z']+$")
if (first_name and not STR_FORMAT.match(first_name)) or (last_name and not STR_FORMAT.match(last_name)):
frappe.throw("Names cannot contain invalid characters")
frappe.throw(_("Names cannot contain invalid characters"))
user = frappe.session.user
doc = frappe.get_doc("User", user)
doc.first_name = first_name
Expand Down Expand Up @@ -806,7 +808,7 @@ def remove_child_team(child_team):
team = frappe.get_doc("Team", child_team)
sites = frappe.get_all("Site", {"status": ("!=", "Archived"), "team": team.name}, pluck="name")
if sites:
frappe.throw("Child team has Active Sites")
frappe.throw(_("Child team has Active Sites"))

team.enabled = 0
team.parent_team = ""
Expand Down Expand Up @@ -844,7 +846,7 @@ def leave_team(team):
cur_team = frappe.session.user

if team_to_leave.user == cur_team:
frappe.throw("Cannot leave this team as you are the owner.")
frappe.throw(_("Cannot leave this team as you are the owner."))

team_to_leave.remove_team_member(cur_team)

Expand Down Expand Up @@ -874,7 +876,7 @@ def update_billing_information(billing_details):
if (team.country != billing_details.country) and (
team.country == "India" or billing_details.country == "India"
):
frappe.throw("Cannot change country after registration")
frappe.throw(_("Cannot change country after registration"))
team.update_billing_details(billing_details)


Expand All @@ -884,7 +886,7 @@ def validate_pincode(billing_details):
return
PINCODE_FORMAT = re.compile(r"^[1-9][0-9]{5}$")
if not PINCODE_FORMAT.match(billing_details.postal_code):
frappe.throw("Invalid Postal Code")
frappe.throw(_("Invalid Postal Code"))

if billing_details.state not in STATE_PINCODE_MAPPING:
return
Expand All @@ -899,7 +901,11 @@ def validate_pincode(billing_details):
if lower_limit <= int(first_three_digits) <= upper_limit:
return

frappe.throw(f"Postal Code {billing_details.postal_code} is not associated with {billing_details.state}")
frappe.throw(
_("Postal Code {0} is not associated with {1}").format(
billing_details.postal_code, billing_details.state
)
)


@frappe.whitelist(allow_guest=True)
Expand Down Expand Up @@ -1157,7 +1163,7 @@ def verify_2fa(user, totp_code):
if verified:
frappe.db.set_value("User 2FA", user, "last_verified_at", frappe.utils.now())
else:
frappe.throw("Invalid 2FA code", frappe.AuthenticationError)
frappe.throw(_("Invalid 2FA code"), frappe.AuthenticationError)

return verified

Expand Down Expand Up @@ -1192,7 +1198,7 @@ def enable_2fa(totp_code):
user_totp_secret = get_decrypted_password("User 2FA", frappe.session.user, "totp_secret")

if not pyotp.totp.TOTP(user_totp_secret).verify(totp_code):
frappe.throw("Invalid TOTP code")
frappe.throw(_("Invalid TOTP code"))

two_fa.enabled = 1

Expand Down Expand Up @@ -1232,12 +1238,12 @@ def disable_2fa(totp_code):
if frappe.db.exists("User 2FA", frappe.session.user):
user_totp_secret = get_decrypted_password("User 2FA", frappe.session.user, "totp_secret")
else:
frappe.throw(f"2FA is not enabled for {frappe.session.user}")
frappe.throw(_("2FA is not enabled for {0}").format(frappe.session.user))

if pyotp.totp.TOTP(user_totp_secret).verify(totp_code):
frappe.db.set_value("User 2FA", frappe.session.user, "enabled", 0)
else:
frappe.throw("Invalid TOTP code")
frappe.throw(_("Invalid TOTP code"))


@frappe.whitelist(allow_guest=True)
Expand All @@ -1249,7 +1255,7 @@ def recover_2fa(user: str, recovery_code: str):

# Check if the user has 2FA enabled.
if not two_fa.enabled:
frappe.throw(f"2FA is not enabled for {user}")
frappe.throw(_("2FA is not enabled for {0}").format(user))

# Get valid recovery code doc.
code: "User2FARecoveryCode" | None = None
Expand All @@ -1261,7 +1267,7 @@ def recover_2fa(user: str, recovery_code: str):

# If no valid recovery code found, throw an error.
if not code:
frappe.throw("Invalid or used recovery code")
frappe.throw(_("Invalid or used recovery code"))
assert code is not None
# Mark the recovery code as used.
code.used_at = frappe.utils.now_datetime()
Expand All @@ -1276,12 +1282,12 @@ def get_2fa_recovery_codes(verification_code: int):
"""Get the recovery codes for the user."""

if not frappe.db.exists("User 2FA", {"user": frappe.session.user, "enabled": 1}):
frappe.throw("2FA is not enabled for this user")
frappe.throw(_("2FA is not enabled for this user"))

account_request: "AccountRequest" = frappe.get_doc("Account Request", {"email": frappe.session.user})

if account_request.otp != verification_code:
frappe.throw("Invalid OTP. Please try again.")
frappe.throw(_("Invalid OTP. Please try again."))

account_request.reset_otp()

Expand Down Expand Up @@ -1309,7 +1315,7 @@ def reset_2fa_recovery_codes():

# Check if the user has 2FA enabled.
if not frappe.db.exists("User 2FA", frappe.session.user):
frappe.throw("2FA is not enabled for this user")
frappe.throw(_("2FA is not enabled for this user"))

# Get the User 2FA document.
two_fa = frappe.get_doc("User 2FA", frappe.session.user)
Expand Down
Loading