Enforce recipient-bound single-use invites and fix issue card layout; clean release tooling
This commit is contained in:
+26
-1
@@ -1573,7 +1573,7 @@ def delete_user_profile(profile_id: int) -> bool:
|
||||
|
||||
|
||||
def _row_to_signup_invite(row: Any) -> Dict[str, Any]:
|
||||
max_uses = row[6]
|
||||
max_uses = 1 if row[10] else row[6]
|
||||
use_count = int(row[7] or 0)
|
||||
expires_at = row[9]
|
||||
is_expired = _is_datetime_in_past(expires_at)
|
||||
@@ -1657,6 +1657,8 @@ def create_signup_invite(
|
||||
recipient_email: Optional[str] = None,
|
||||
created_by: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
if recipient_email:
|
||||
max_uses = 1
|
||||
timestamp = datetime.now(timezone.utc).isoformat()
|
||||
with _connect() as conn:
|
||||
cursor = conn.execute(
|
||||
@@ -1714,6 +1716,11 @@ def update_signup_invite(
|
||||
expires_at: Optional[str],
|
||||
recipient_email: Optional[str],
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
existing = get_signup_invite_by_id(invite_id)
|
||||
if recipient_email or (existing and existing.get('recipient_email')):
|
||||
max_uses = 1
|
||||
if existing and existing.get('recipient_email') and int(existing.get('use_count') or 0) > 0 and recipient_email != existing.get('recipient_email'):
|
||||
raise ValueError('A used email invitation cannot be reassigned.')
|
||||
timestamp = datetime.now(timezone.utc).isoformat()
|
||||
with _connect() as conn:
|
||||
cursor = conn.execute(
|
||||
@@ -1751,6 +1758,24 @@ def delete_signup_invite(invite_id: int) -> bool:
|
||||
return cursor.rowcount > 0
|
||||
|
||||
|
||||
def reserve_signup_invite_use(invite_id: int) -> bool:
|
||||
"""Atomically reserve capacity before any remote account is provisioned."""
|
||||
with _connect() as conn:
|
||||
cursor = conn.execute('''
|
||||
UPDATE signup_invites SET use_count = use_count + 1
|
||||
WHERE id = ? AND enabled = 1
|
||||
AND (expires_at IS NULL OR julianday(expires_at) > julianday('now'))
|
||||
AND ((recipient_email IS NOT NULL AND recipient_email != '' AND use_count < 1)
|
||||
OR ((recipient_email IS NULL OR recipient_email = '') AND (max_uses IS NULL OR use_count < max_uses)))
|
||||
''', (invite_id,))
|
||||
return cursor.rowcount == 1
|
||||
|
||||
|
||||
def release_signup_invite_use(invite_id: int) -> None:
|
||||
with _connect() as conn:
|
||||
conn.execute('UPDATE signup_invites SET use_count = MAX(0, use_count - 1) WHERE id = ?', (invite_id,))
|
||||
|
||||
|
||||
def increment_signup_invite_use(invite_id: int) -> None:
|
||||
timestamp = datetime.now(timezone.utc).isoformat()
|
||||
with _connect() as conn:
|
||||
|
||||
Reference in New Issue
Block a user