From 38c49ff37071c86745a945330adabd92f5e37786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Rafael=20Siqueira?= Date: Wed, 3 Dec 2025 01:24:52 -0300 Subject: [PATCH] fix menu --- .../app/routes/orgs/users/__init__.py | 22 +++++++----- .../app/routes/users/__init__.py | 7 ++-- .../app/routes/_.$orgid.users.$id/route.tsx | 1 + .../app/routes/_.$orgid/route.tsx | 2 +- .../app/routes/index.tsx | 9 ++--- .../app/routes/register/index.tsx | 28 +++++++++++++-- apps/id.saladeaula.digital/tsconfig.json | 1 + .../app/routes/_app/route.tsx | 2 +- apps/saladeaula.digital/app/routes/index.tsx | 20 ++++++++--- apps/saladeaula.digital/app/routes/layout.tsx | 2 +- .../app/routes/layout.tsx | 2 +- id.saladeaula.digital/app/config.py | 6 ++++ id.saladeaula.digital/app/events/__init__.py | 0 id.saladeaula.digital/app/oauth2.py | 5 +-- id.saladeaula.digital/app/routes/authorize.py | 32 +++++++++-------- id.saladeaula.digital/app/routes/register.py | 6 +++- .../tests/routes/test_authorize.py | 6 ++-- id.saladeaula.digital/tests/seeds.jsonl | 1 + packages/ui/src/components/nav-user.tsx | 35 ++++++++++++------- packages/ui/tsconfig.json | 2 ++ .../app/events/batch/chunks_into_users.py | 17 +++++---- 21 files changed, 133 insertions(+), 73 deletions(-) create mode 100644 id.saladeaula.digital/app/events/__init__.py diff --git a/api.saladeaula.digital/app/routes/orgs/users/__init__.py b/api.saladeaula.digital/app/routes/orgs/users/__init__.py index 340579a..dea4cba 100644 --- a/api.saladeaula.digital/app/routes/orgs/users/__init__.py +++ b/api.saladeaula.digital/app/routes/orgs/users/__init__.py @@ -117,9 +117,10 @@ def _create_user(user: User, org: Org) -> bool: 'sk': '0', 'email_verified': email_verified, 'tenant_id': {org.id}, - # Post-migration: uncomment the folloing line + # Post-migration (users): uncomment the folloing line # 'org_id': {org.id}, - 'created_at': now_, + # 'created_at': now_, + 'createDate': now_, }, ) transact.put( @@ -157,9 +158,10 @@ def _create_user(user: User, org: Org) -> bool: transact.put( item={ - # Post-migration: rename `cpf` to `CPF` + # Post-migration (users): rename `cpf` to `CPF` 'id': 'cpf', 'sk': user.cpf, + 'user_id': user_id, 'created_at': now_, }, cond_expr='attribute_not_exists(sk)', @@ -167,9 +169,10 @@ def _create_user(user: User, org: Org) -> bool: ) transact.put( item={ - # Post-migration: rename `email` to `EMAIL` + # Post-migration (users): rename `email` to `EMAIL` 'id': 'email', 'sk': user.email, + 'user_id': user_id, 'created_at': now_, }, cond_expr='attribute_not_exists(sk)', @@ -179,7 +182,7 @@ def _create_user(user: User, org: Org) -> bool: item={ 'id': user_id, 'sk': f'orgs#{org.id}', - # Post-migration: uncomment the following line + # Post-migration (users): uncomment the following line # pk=f'ORG#{org.id}', 'name': org.name, 'cnpj': org.cnpj, @@ -189,7 +192,7 @@ def _create_user(user: User, org: Org) -> bool: transact.put( item={ 'id': f'orgmembers#{org.id}', - # Post-migration: uncomment the following line + # Post-migration (users): uncomment the following line # pk=f'MEMBER#ORG#{org_id}', 'sk': user_id, 'created_at': now_, @@ -212,7 +215,7 @@ def _add_member(user_id: str, org: Org) -> None: with dyn.transact_writer() as transact: transact.update( key=KeyPair(user_id, '0'), - # Post-migration: uncomment the following line + # Post-migration (users): uncomment the following line # update_expr='ADD tenant_id :org_id', update_expr='ADD tenant_id :org_id', expr_attr_values={ @@ -224,7 +227,7 @@ def _add_member(user_id: str, org: Org) -> None: transact.put( item={ 'id': user_id, - # Post-migration: rename `orgs` to `ORG` + # Post-migration (users): rename `orgs` to `ORG` 'sk': f'orgs#{org.id}', 'name': org.name, 'cnpj': org.cnpj, @@ -233,7 +236,8 @@ def _add_member(user_id: str, org: Org) -> None: ) transact.put( item={ - # Post-migration: rename `orgmembers` to `ORGMEMBER` + # Post-migration (users): uncomment the following line + # pk=f'MEMBER#ORG#{org_id}', 'id': f'orgmembers#{org.id}', 'sk': user_id, 'created_at': now_, diff --git a/api.saladeaula.digital/app/routes/users/__init__.py b/api.saladeaula.digital/app/routes/users/__init__.py index dfe4a0a..04cb750 100644 --- a/api.saladeaula.digital/app/routes/users/__init__.py +++ b/api.saladeaula.digital/app/routes/users/__init__.py @@ -59,7 +59,7 @@ def get_user(user_id: str): ) if not user: - return UserNotFoundError('User not found') + raise UserNotFoundError('User not found') return user @@ -74,10 +74,7 @@ def update( old_cpf = dyn.collection.get_item( KeyPair( pk=user_id, - sk=SortKey( - '0', - path_spec='cpf', - ), + sk=SortKey('0', path_spec='cpf'), ), ) diff --git a/apps/admin.saladeaula.digital/app/routes/_.$orgid.users.$id/route.tsx b/apps/admin.saladeaula.digital/app/routes/_.$orgid.users.$id/route.tsx index fab0996..51b881d 100644 --- a/apps/admin.saladeaula.digital/app/routes/_.$orgid.users.$id/route.tsx +++ b/apps/admin.saladeaula.digital/app/routes/_.$orgid.users.$id/route.tsx @@ -37,6 +37,7 @@ export async function loader({ params, request, context }: Route.LoaderArgs) { }) if (!r.ok) { + console.log(r.status) throw new Response(null, { status: r.status }) } diff --git a/apps/admin.saladeaula.digital/app/routes/_.$orgid/route.tsx b/apps/admin.saladeaula.digital/app/routes/_.$orgid/route.tsx index 0cca3e7..67573e1 100644 --- a/apps/admin.saladeaula.digital/app/routes/_.$orgid/route.tsx +++ b/apps/admin.saladeaula.digital/app/routes/_.$orgid/route.tsx @@ -81,7 +81,7 @@ export default function Route({ loaderData }: Route.ComponentProps) {
- +
diff --git a/apps/id.saladeaula.digital/app/routes/index.tsx b/apps/id.saladeaula.digital/app/routes/index.tsx index 8522093..3ce99bb 100644 --- a/apps/id.saladeaula.digital/app/routes/index.tsx +++ b/apps/id.saladeaula.digital/app/routes/index.tsx @@ -56,9 +56,7 @@ export async function action({ request, context }: Route.ActionArgs) { try { const r = await fetch(issuerUrl.toString(), { method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, + headers: new Headers({ 'Content-Type': 'application/json' }), body: JSON.stringify(formData) }) @@ -88,10 +86,7 @@ export async function action({ request, context }: Route.ActionArgs) { export default function Index({}: Route.ComponentProps) { const [show, setShow] = useState(false) const fetcher = useFetcher() - - const form = useForm({ - resolver: zodResolver(schema) - }) + const form = useForm({ resolver: zodResolver(schema) }) const { control, handleSubmit, formState, setError } = form const onSubmit = async (data: Schema) => { diff --git a/apps/id.saladeaula.digital/app/routes/register/index.tsx b/apps/id.saladeaula.digital/app/routes/register/index.tsx index 1875c07..491ccdd 100644 --- a/apps/id.saladeaula.digital/app/routes/register/index.tsx +++ b/apps/id.saladeaula.digital/app/routes/register/index.tsx @@ -1,5 +1,6 @@ import type { Route } from '../+types' +import { useRequest } from 'ahooks' import { PatternFormat } from 'react-number-format' import { zodResolver } from '@hookform/resolvers/zod' import { useState } from 'react' @@ -31,6 +32,19 @@ export function meta({}: Route.MetaArgs) { return [{ title: 'Criar conta · EDUSEG®' }] } +export async function action({ request, context }: Route.ActionArgs) { + const issuerUrl = new URL('/register', context.cloudflare.env.ISSUER_URL) + const body = await request.json() + + const r = await fetch(issuerUrl.toString(), { + method: 'POST', + headers: new Headers({ 'Content-Type': 'application/json' }), + body: JSON.stringify(body) + }) + + console.log(await r.json()) +} + export default function Signup({}: Route.ComponentProps) { const [show, setShow] = useState(false) const [user, setUser] = useState(null) @@ -38,13 +52,21 @@ export default function Signup({}: Route.ComponentProps) { resolver: zodResolver(formSchema) }) const { control, handleSubmit, formState } = form + const { runAsync } = useRequest( + async (user) => { + return await fetch(`/register`, { + method: 'POST', + headers: new Headers({ 'Content-Type': 'application/json' }), + body: JSON.stringify(user) + }) + }, + { manual: true } + ) const onSubmit = async (data: Schema) => { - console.log(data) + await runAsync({ ...user, ...data }) } - console.log(user) - return ( {user ? ( diff --git a/apps/id.saladeaula.digital/tsconfig.json b/apps/id.saladeaula.digital/tsconfig.json index 97b786f..41fd9b8 100644 --- a/apps/id.saladeaula.digital/tsconfig.json +++ b/apps/id.saladeaula.digital/tsconfig.json @@ -6,6 +6,7 @@ ], "compilerOptions": { "checkJs": true, + "moduleResolution": "bundler", "verbatimModuleSyntax": true, "skipLibCheck": true, "strict": true, diff --git a/apps/insights.saladeaula.digital/app/routes/_app/route.tsx b/apps/insights.saladeaula.digital/app/routes/_app/route.tsx index d9df58d..3127e27 100644 --- a/apps/insights.saladeaula.digital/app/routes/_app/route.tsx +++ b/apps/insights.saladeaula.digital/app/routes/_app/route.tsx @@ -48,7 +48,7 @@ export default function Route({ loaderData }: Route.ComponentProps) {
- +
diff --git a/apps/saladeaula.digital/app/routes/index.tsx b/apps/saladeaula.digital/app/routes/index.tsx index 2ad91ea..ab27cd7 100644 --- a/apps/saladeaula.digital/app/routes/index.tsx +++ b/apps/saladeaula.digital/app/routes/index.tsx @@ -176,10 +176,22 @@ function List({ s, hits = [] }: { s: string; hits: Enrollment[] }) { - Nada encontrado - - Nenhum resultado para {s}. - + {s ? ( + <> + Nada encontrado + + Nenhum resultado para {s}. + + + ) : ( + <> + Nenhum curso ainda + + Comece escolhendo um curso. Assim que você se matricular, ele + aparecerá aqui. + + + )} ) diff --git a/apps/saladeaula.digital/app/routes/layout.tsx b/apps/saladeaula.digital/app/routes/layout.tsx index ef14776..7f8eb58 100644 --- a/apps/saladeaula.digital/app/routes/layout.tsx +++ b/apps/saladeaula.digital/app/routes/layout.tsx @@ -141,7 +141,7 @@ export default function Component({
- +
diff --git a/apps/studio.saladeaula.digital/app/routes/layout.tsx b/apps/studio.saladeaula.digital/app/routes/layout.tsx index 623be93..3264b77 100644 --- a/apps/studio.saladeaula.digital/app/routes/layout.tsx +++ b/apps/studio.saladeaula.digital/app/routes/layout.tsx @@ -32,7 +32,7 @@ export default function Component({ loaderData }: Route.ComponentProps) {
- +
diff --git a/id.saladeaula.digital/app/config.py b/id.saladeaula.digital/app/config.py index 81c299e..13d7da2 100644 --- a/id.saladeaula.digital/app/config.py +++ b/id.saladeaula.digital/app/config.py @@ -13,5 +13,11 @@ OAUTH2_SCOPES_SUPPORTED: list[str] = [ 'apps:studio', 'apps:insights', ] +OAUTH2_DEFAULT_SCOPES = { + 'email', + 'offline_access', + 'openid', + 'profile', +} SESSION_EXPIRES_IN = 86_400 * 30 # 30 days diff --git a/id.saladeaula.digital/app/events/__init__.py b/id.saladeaula.digital/app/events/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/id.saladeaula.digital/app/oauth2.py b/id.saladeaula.digital/app/oauth2.py index 2e1bf42..39f5ad6 100644 --- a/id.saladeaula.digital/app/oauth2.py +++ b/id.saladeaula.digital/app/oauth2.py @@ -21,7 +21,7 @@ from layercake.dynamodb import ( from layercake.funcs import omit, pick from boto3clients import dynamodb_client -from config import ISSUER, OAUTH2_SCOPES_SUPPORTED, OAUTH2_TABLE +from config import ISSUER, OAUTH2_DEFAULT_SCOPES, OAUTH2_SCOPES_SUPPORTED, OAUTH2_TABLE from integrations.apigateway_oauth2.authorization_server import ( AuthorizationServer, ) @@ -191,10 +191,11 @@ class AuthorizationCodeGrant(grants.AuthorizationCodeGrant): rename_key='scope', ), ) + scope = set(user.get('scope', [])) | OAUTH2_DEFAULT_SCOPES return User( **pick(('id', 'name', 'email', 'email_verified'), user), - scope=' '.join(user['scope']) if 'scope' in user else None, + scope=' '.join(scope), ) diff --git a/id.saladeaula.digital/app/routes/authorize.py b/id.saladeaula.digital/app/routes/authorize.py index 7df328c..c11731a 100644 --- a/id.saladeaula.digital/app/routes/authorize.py +++ b/id.saladeaula.digital/app/routes/authorize.py @@ -5,13 +5,14 @@ from aws_lambda_powertools.event_handler.api_gateway import Router from aws_lambda_powertools.event_handler.exceptions import ( BadRequestError, ForbiddenError, + NotFoundError, ServiceError, ) from joserfc.errors import JoseError from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey from boto3clients import dynamodb_client -from config import OAUTH2_TABLE +from config import OAUTH2_DEFAULT_SCOPES, OAUTH2_TABLE from oauth2 import server from util import parse_cookies @@ -20,6 +21,9 @@ logger = Logger(__name__) dyn = DynamoDBPersistenceLayer(OAUTH2_TABLE, dynamodb_client) +class SessionNotFoundError(NotFoundError): ... + + @router.get('/authorize') def authorize(): current_event = router.current_event @@ -27,20 +31,20 @@ def authorize(): session = cookies.get('SID') if not session: - raise BadRequestError('Missing session') + raise BadRequestError('Session cookie (SID) is required') try: - sid, sub = session.split(':') + session_id, user_id = session.split(':') # Raise if session is not found dyn.collection.get_item( - KeyPair('SESSION', sid), - exc_cls=InvalidSession, + KeyPair('SESSION', session_id), + exc_cls=SessionNotFoundError, ) grant = server.get_consent_grant( request=router.current_event, - end_user=sub, + end_user=user_id, ) - user_scopes = _user_scopes(sub) + user_scopes = _user_scopes(user_id) client_scopes = set(scope_to_list(grant.client.scope)) # Deny authorization if user lacks scopes requested by client @@ -49,7 +53,7 @@ def authorize(): response = server.create_authorization_response( request=router.current_event, - grant_user=sub, + grant_user=user_id, grant=grant, ) except JoseError as err: @@ -65,18 +69,16 @@ def authorize(): return response -def _user_scopes(sub: str) -> set: - return set( +def _user_scopes(user_id: str) -> set: + return OAUTH2_DEFAULT_SCOPES | set( scope_to_list( dyn.collection.get_item( KeyPair( - pk=sub, + pk=user_id, sk=SortKey(sk='SCOPE', path_spec='scope'), ), - exc_cls=BadRequestError, + raise_on_error=False, + default='', ) ) ) - - -class InvalidSession(BadRequestError): ... diff --git a/id.saladeaula.digital/app/routes/register.py b/id.saladeaula.digital/app/routes/register.py index de0c568..d20961b 100644 --- a/id.saladeaula.digital/app/routes/register.py +++ b/id.saladeaula.digital/app/routes/register.py @@ -88,7 +88,9 @@ def _create_user(*, user: User, password: str): item={ 'sk': '0', 'email_verified': False, - 'created_at': now_, + 'createdDate': now_, + # Post-migration (users): uncomment the folloing line + # 'created_at': now_, } | asdict(user), ) @@ -116,6 +118,7 @@ def _create_user(*, user: User, password: str): # Post-migration (users): rename `cpf` to `CPF` 'id': 'cpf', 'sk': user.cpf, + 'user_id': user.id, 'created_at': now_, }, cond_expr='attribute_not_exists(sk)', @@ -126,6 +129,7 @@ def _create_user(*, user: User, password: str): # Post-migration (users): rename `email` to `EMAIL` 'id': 'email', 'sk': user.email, + 'user_id': user.id, 'created_at': now_, }, cond_expr='attribute_not_exists(sk)', diff --git a/id.saladeaula.digital/tests/routes/test_authorize.py b/id.saladeaula.digital/tests/routes/test_authorize.py index e444917..928afae 100644 --- a/id.saladeaula.digital/tests/routes/test_authorize.py +++ b/id.saladeaula.digital/tests/routes/test_authorize.py @@ -68,9 +68,9 @@ def test_forbidden( method=HTTPMethod.GET, query_string_parameters={ 'response_type': 'code', - 'client_id': '6ebe1709-0831-455c-84c0-d4c753bf33c6', + 'client_id': '5e90c38f-f058-4e16-91fa-952554a290c5', 'redirect_uri': 'https://localhost/callback', - 'scope': 'openid email offline_access', + 'scope': 'apps:admin', 'nonce': '123', 'state': '456', }, @@ -110,4 +110,4 @@ def test_invalid_session( lambda_context, ) - assert r['statusCode'] == HTTPStatus.BAD_REQUEST + assert r['statusCode'] == HTTPStatus.NOT_FOUND diff --git a/id.saladeaula.digital/tests/seeds.jsonl b/id.saladeaula.digital/tests/seeds.jsonl index ef18ea3..d05c740 100644 --- a/id.saladeaula.digital/tests/seeds.jsonl +++ b/id.saladeaula.digital/tests/seeds.jsonl @@ -3,6 +3,7 @@ {"id": "OAUTH2", "sk": "CLIENT_ID#8c5e92b0-9ed4-451e-8935-66084d8544b1", "client_secret": "1nFD8alDbGHgc3g1RLY960xyRJVee0SlMoIB0MUlSuiJy28W", "name": "pytest 1", "scope": "openid profile", "redirect_uris": ["https://localhost/callback"], "response_types": ["code"], "grant_types": ["authorization_code", "refresh_token"], "scope": "openid profile email offline_access apps:admin", "token_endpoint_auth_method": "none"} {"id": "OAUTH2", "sk": "CLIENT_ID#6ebe1709-0831-455c-84c0-d4c753bf33c6", "client_secret": "1nFD8alDbGHgc3g1RLY960xyRJVee0SlMoIB0MUlSuiJy28W", "name": "pytest 2", "scope": "openid profile", "redirect_uris": ["https://localhost/callback"], "response_types": ["code"], "grant_types": ["authorization_code", "refresh_token"], "scope": "openid profile email offline_access", "token_endpoint_auth_method": "none"} {"id": "OAUTH2", "sk": "CLIENT_ID#1db63660-063d-4280-b2ea-388aca4a9459", "client_secret": "1nFD8alDbGHgc3g1RLY960xyRJVee0SlMoIB0MUlSuiJy28W", "name": "pytest 3", "scope": "openid profile", "redirect_uris": ["https://localhost/callback"], "response_types": ["code"], "grant_types": ["authorization_code", "refresh_token"], "scope": "openid profile email offline_access apps:admin", "token_endpoint_auth_method": "client_secret_basic"} +{"id": "OAUTH2", "sk": "CLIENT_ID#5e90c38f-f058-4e16-91fa-952554a290c5", "client_secret": "1nFD8alDbGHgc3g1RLY960xyRJVee0SlMoIB0MUlSuiJy28W", "name": "pytest 2", "scope": "openid profile", "redirect_uris": ["https://localhost/callback"], "response_types": ["code"], "grant_types": ["authorization_code", "refresh_token"], "scope": "apps:studio", "token_endpoint_auth_method": "none"} {"id": "OAUTH2#CODE", "sk": "CODE#kyqp3oSuRFTfuBaCmq3XOgGWg67l42Kt3D6xPEj7Yd3MLdi9", "client_id": "d72d4005-1fa7-4430-9754-80d5e2487bb6", "redirect_uri": "https://localhost/callback", "user_id": "357db1c5-7442-4075-98a3-fbe5c938a419", "nonce": null, "scope": "openid profile email apps:admins", "response_type": "code", "code_challenge": "ejYEIGKQUgMnNh4eV0sftb0hXdLwkvKm6OHXRYvC--I", "code_challenge_method": "S256", "created_at": "2025-08-07T12:38:26.550431-03:00"} {"id": "OAUTH2#TOKEN", "sk": "REFRESH_TOKEN#CyF3Ik3b9hMIo3REVv27gZAHd7dvwZq6QrkhWr7qHEen4UVy", "client_id": "d72d4005-1fa7-4430-9754-80d5e2487bb6", "token_type": "Bearer", "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6IlRjT0VuV3JGSUFEYlZJNjJlY1pzU28ydEI1eW5mbkZZNTZ0Uy05b0stNW8ifQ.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0IiwiZXhwIjoxNzU5NTg2NzgzLCJjbGllbnRfaWQiOiJkNzJkNDAwNS0xZmE3LTQ0MzAtOTc1NC04MGQ1ZTI0ODdiYjYiLCJpYXQiOjE3NTg5ODE5ODMsImp0aSI6Ik9uVzRIZm1FdFl2a21CbE4iLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIHJlYWQ6dXNlcnMiLCJzdWIiOiIzNTdkYjFjNS03NDQyLTQwNzUtOThhMy1mYmU1YzkzOGE0MTkiLCJhdWQiOiJkNzJkNDAwNS0xZmE3LTQ0MzAtOTc1NC04MGQ1ZTI0ODdiYjYifQ.i0NVgvPuf5jvl8JcYNsVCzjVUTDLihgQO4LmLeNijx9Ed3p_EgtVtcHFWFvEebe_LwTuDDtIJveH22Piyp4zresNSc_YNumnuvoY1aNd0ic2RIEtXaklRroq0xHwL_IVT-Dt6P9xL5Hyygx47Pvmci4U3wWK32a6Sb1Mm7ZZgXA00xWI1bJ_zwxFLvDkHDp9nrAa_vEWN6zRBcWc7JYNsgiaPMC0DoL8it0k48_g44zfsjGAZLcWFMoPlYt3wIcQQDeCKMsSJI0VPnqKK0pq4OOVs-pjkMyAU5aEMPvVOwdAL3VZY16RXt3eTzsmMH1XoRdCMP6UAx4ZS10RLGUPeA", "scope": "openid profile email read:users", "user": {"id": "357db1c5-7442-4075-98a3-fbe5c938a419", "name": "S\u00e9rgio R Siqueira", "email": "sergio@somosbeta.com.br", "email_verified": false}, "expires_in": 180, "issued_at": 1758981984, "ttl": 1759586784} diff --git a/packages/ui/src/components/nav-user.tsx b/packages/ui/src/components/nav-user.tsx index 2ddeb45..c057e07 100644 --- a/packages/ui/src/components/nav-user.tsx +++ b/packages/ui/src/components/nav-user.tsx @@ -26,6 +26,7 @@ import { } from './ui/dropdown-menu' type NavItem = { + appId: string title: string url: string icon: LucideIcon @@ -34,23 +35,27 @@ type NavItem = { const apps: NavItem[] = [ { + appId: 'saladeaula', title: 'Sala de aula', url: '//scorm.eduseg.workers.dev', icon: GraduationCapIcon }, { + appId: 'admin', title: 'Administrador', url: '//admin.saladeaula.digital', icon: LayoutDashboardIcon, scope: ['apps:admin'] }, { + appId: 'studio', title: 'EDUSEG® Estúdio', url: '//studio.saladeaula.digital', icon: CirclePlayIcon, scope: ['apps:studio'] }, { + appId: 'insights', title: 'EDUSEG® Insights', url: '//insights.saladeaula.digital', icon: LightbulbIcon, @@ -59,13 +64,15 @@ const apps: NavItem[] = [ ] export function NavUser({ - user + user, + excludeApps }: { user: { name: string email: string scope: string } + excludeApps: string[] }) { const userScope = user.scope.split(' ') @@ -135,19 +142,21 @@ export function NavUser({ )} - {apps.map(({ title, url, scope = [], icon: Icon }, idx) => { - if (grantIfHas(scope, userScope)) { - return ( - - - {title} - - - ) - } + {apps + .filter(({ appId }) => !excludeApps.includes(appId)) + .map(({ appId, title, url, scope = [], icon: Icon }) => { + if (grantIfHas(scope, userScope)) { + return ( + + + {title} + + + ) + } - return <> - })} + return <> + })} diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json index 7cf3e44..5141d5a 100644 --- a/packages/ui/tsconfig.json +++ b/packages/ui/tsconfig.json @@ -1,6 +1,8 @@ { "compilerOptions": { "composite": true, + "declaration": true, + "declarationMap": true, "strict": true, "lib": ["DOM", "DOM.Iterable", "ES2022"], "types": ["vite/client"], diff --git a/users-events/app/events/batch/chunks_into_users.py b/users-events/app/events/batch/chunks_into_users.py index 482474f..c3fb1ff 100644 --- a/users-events/app/events/batch/chunks_into_users.py +++ b/users-events/app/events/batch/chunks_into_users.py @@ -132,9 +132,10 @@ def _create_user(rawuser: dict, context: dict) -> None: 'sk': '0', 'email_verified': False, 'tenant_id': {org.id}, - # Post-migration: uncomment the folloing line + # Post-migration (users): uncomment the folloing line # 'org_id': {org.id}, - 'created_at': now_, + # 'created_at': now_, + 'createDate': now_, }, ) transact.put( @@ -147,7 +148,7 @@ def _create_user(rawuser: dict, context: dict) -> None: transact.put( item={ 'id': user_id, - # Post-migration: rename `emails` to `EMAIL` + # Post-migration (users): rename `emails` to `EMAIL` 'sk': f'emails#{user.email}', 'email_verified': False, 'email_primary': True, @@ -169,9 +170,10 @@ def _create_user(rawuser: dict, context: dict) -> None: ) transact.put( item={ - # Post-migration: rename `cpf` to `CPF` + # Post-migration (users): rename `cpf` to `CPF` 'id': 'cpf', 'sk': user.cpf, + 'user_id': user_id, 'created_at': now_, }, cond_expr='attribute_not_exists(sk)', @@ -179,9 +181,10 @@ def _create_user(rawuser: dict, context: dict) -> None: ) transact.put( item={ - # Post-migration: rename `email` to `EMAIL` + # Post-migration (users): rename `email` to `EMAIL` 'id': 'email', 'sk': user.email, + 'user_id': user_id, 'created_at': now_, }, cond_expr='attribute_not_exists(sk)', @@ -191,7 +194,7 @@ def _create_user(rawuser: dict, context: dict) -> None: item={ 'id': user_id, 'sk': f'orgs#{org.id}', - # Post-migration: uncomment the following line + # Post-migration (users): uncomment the following line # pk=f'ORG#{org.id}', 'name': org.name, 'cnpj': org.cnpj, @@ -201,7 +204,7 @@ def _create_user(rawuser: dict, context: dict) -> None: transact.put( item={ 'id': f'orgmembers#{org.id}', - # Post-migration: uncomment the following line + # Post-migration (users): uncomment the following line # pk=f'MEMBER#ORG#{org_id}', 'sk': user_id, 'created_at': now_,