fix set email verified

This commit is contained in:
2025-11-28 21:28:13 -03:00
parent c48f289514
commit b5f3648f44
8 changed files with 66 additions and 20 deletions

View File

@@ -139,7 +139,6 @@ def _create_user(user: User, org: Org) -> bool:
'fresh_user': True,
'name': user.name,
'email': user.email,
'email_primary': True,
'org_name': org.name,
'ttl': ttl(start_dt=now_, days=30),
'created_at': now_,

View File

@@ -8,8 +8,7 @@ from aws_lambda_powertools.event_handler.exceptions import (
)
from aws_lambda_powertools.event_handler.openapi.params import Body, Path, Query
from layercake.dateutils import now, ttl
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey
from layercake.funcs import pick
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey, TransactKey
from pydantic import EmailStr
from typing_extensions import Annotated
@@ -33,6 +32,9 @@ def get_emails(user_id: str, start_key: Annotated[str | None, Query] = None):
class UserNotFoundError(NotFoundError): ...
class EmailNotFoundError(NotFoundError): ...
class EmailConflictError(ServiceError):
def __init__(self, msg: str | dict):
super().__init__(HTTPStatus.CONFLICT, msg)
@@ -82,7 +84,6 @@ def add(
'sk': f'EMAIL_VERIFICATION#{uuid4()}',
'name': name,
'email': email,
'user_id': user_id,
'ttl': ttl(start_dt=now_, days=30),
'created_at': now_,
}
@@ -110,7 +111,6 @@ def request_verification(
'sk': f'EMAIL_VERIFICATION#{uuid4()}',
'name': name,
'email': email,
'user_id': user_id,
'ttl': ttl(start_dt=now_, days=30),
'created_at': now_,
}
@@ -121,20 +121,31 @@ def request_verification(
class EmailVerificationNotFoundError(NotFoundError): ...
@router.post('/<user_id>/emails/<hash>/verify')
def verify(user_id: str, hash: str):
verification = dyn.collection.get_item(
KeyPair(
pk=user_id,
sk=f'EMAIL_VERIFICATION#{hash}',
@router.post('/<user_id>/emails/<code>/verify')
def verify(user_id: str, code: str):
r = dyn.collection.get_items(
TransactKey(user_id)
+ SortKey(
sk='0',
rename_key='email_primary',
path_spec='email',
)
+ SortKey(
sk=f'EMAIL_VERIFICATION#{code}',
rename_key='email',
path_spec='email',
),
exc_cls=EmailVerificationNotFoundError,
flatten_top=False,
)
email, primary = pick(('email', 'email_primary'), verification, default=False)
if 'email' not in r:
raise EmailVerificationNotFoundError('Verification code not found')
email, email_primary = r['email'], r['email_primary']
with dyn.transact_writer() as transact:
transact.delete(
key=KeyPair(user_id, f'EMAIL_VERIFICATION#{hash}'),
key=KeyPair(user_id, f'EMAIL_VERIFICATION#{code}'),
)
transact.update(
# Post-migration (users): rename `emails` to `EMAIL`
@@ -144,15 +155,16 @@ def verify(user_id: str, hash: str):
':true': True,
':now': now(),
},
cond_expr='attribute_exists(sk)',
exc_cls=EmailNotFoundError,
)
if primary:
if email == email_primary:
transact.update(
key=KeyPair(user_id, '0'),
update_expr='SET email_verified = :true, \
updated_at = :now',
expr_attr_values={
':email': email,
':true': True,
':now': now(),
},