diff --git a/backend/api/v1/modules/core/invites/routes.py b/backend/api/v1/modules/core/invites/routes.py index a134440..3ed0883 100644 --- a/backend/api/v1/modules/core/invites/routes.py +++ b/backend/api/v1/modules/core/invites/routes.py @@ -37,13 +37,33 @@ async def create_invite( required_permissions=["user.create"], ) + # tenant_slug: del token si viene; si el usuario es hub_admin (sin tenant en el + # token), se resuelve desde la compañía destino (a76.company → core.tenants). tenant_slug: str = current_user.get("tenant_slug") or "" + if not tenant_slug: + from sqlalchemy import text as _text + row = db.execute( + _text( + "SELECT t.slug FROM a76.company c " + "JOIN core.tenants t ON t.id = c.tenant_id WHERE c.id = :c" + ), + {"c": data.company_id}, + ).first() + if row and row[0]: + tenant_slug = row[0] + created_by: str = current_user.get("sub") or "" + # El invite se crea en el Hub: se necesita el token KC (la sesión local no la + # acepta el Hub). Se toma de la sesión (valkey) y se refresca si hace falta. + from core.hub_token import get_hub_access_token + + kc_token = await get_hub_access_token(request) + service = InviteService(db) return await service.create_invite( data=data, created_by=created_by, tenant_slug=tenant_slug, - user_access_token=credentials.credentials, + user_access_token=kc_token or credentials.credentials, ) diff --git a/frontend/src/routes/dashboard/users/+page.svelte b/frontend/src/routes/dashboard/users/+page.svelte index ec059e8..67f14a9 100644 --- a/frontend/src/routes/dashboard/users/+page.svelte +++ b/frontend/src/routes/dashboard/users/+page.svelte @@ -1,6 +1,7 @@