fix error

This commit is contained in:
2025-12-04 10:56:36 -03:00
parent 2f76bd611c
commit c3917addfa
17 changed files with 127 additions and 52 deletions

View File

@@ -1,5 +1,5 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: 1aadef19c576560a2c23acd0e7ab9b2e)
// Generated by Wrangler by running `wrangler types` (hash: 58c6149f238624e8945df7f87e575516)
// Runtime types generated with workerd@1.20251118.0 2025-04-04
declare namespace Cloudflare {
interface GlobalProps {
@@ -9,12 +9,12 @@ declare namespace Cloudflare {
CLIENT_ID: "1db63660-063d-4280-b2ea-388aca4a9459";
SCOPE: "openid profile email offline_access apps:admin";
API_URL: "https://bcs7fgb9og.execute-api.sa-east-1.amazonaws.com";
ISSUER_URL: "https://id.saladeaula.digital";
MEILI_HOST: "https://search.saladeaula.digital";
CLIENT_SECRET: string;
REDIRECT_URI: string;
SESSION_SECRET: string;
MEILI_API_KEY: string;
REDIRECT_URI: string;
ISSUER_URL: string;
}
}
interface Env extends Cloudflare.Env {}

View File

@@ -109,7 +109,7 @@ export default function Index({}: Route.ComponentProps) {
type: 'manual'
})
}
}, [fetcher.data])
}, [fetcher.data, setError])
return (
<>

View File

@@ -2,7 +2,7 @@ import type { Route } from '../+types'
import { PatternFormat } from 'react-number-format'
import { zodResolver } from '@hookform/resolvers/zod'
import { useState } from 'react'
import { useEffect, useState } from 'react'
import { CheckCircle2Icon } from 'lucide-react'
import { useForm } from 'react-hook-form'
import { redirect, useFetcher } from 'react-router'
@@ -44,9 +44,13 @@ export async function action({ request, context }: Route.ActionArgs) {
signal: request.signal
})
if (r.ok) {
throw redirect('/authorize', { headers: r.headers })
}
return { ok: false, error: await r.json() }
}
export default function Signup({}: Route.ComponentProps) {
const fetcher = useFetcher()
const [show, setShow] = useState(false)
@@ -63,6 +67,16 @@ export default function Signup({}: Route.ComponentProps) {
})
}
useEffect(() => {
switch (fetcher.data?.error?.type) {
case 'EmailConflictError':
return setError('email', {
message: 'O endereço de email já está em uso',
type: 'manual'
})
}
}, [fetcher.data, setError])
return (
<RegisterContext value={{ user, setUser }}>
{user ? (

View File

@@ -1,5 +1,5 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: 20d12d2cb42a565d117b277533ca85a9)
// Generated by Wrangler by running `wrangler types` (hash: 7e2e7bff7e69c3350947dfc5bad66ee7)
// Runtime types generated with workerd@1.20251118.0 2025-04-04
declare namespace Cloudflare {
interface GlobalProps {
@@ -7,6 +7,7 @@ declare namespace Cloudflare {
}
interface Env {
ISSUER_URL: "https://58tkjsb308.execute-api.sa-east-1.amazonaws.com";
APP_URL: string;
}
}
interface Env extends Cloudflare.Env {}

View File

@@ -1,5 +1,5 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: 46c0a3878ceeb71c97bee6d456de6815)
// Generated by Wrangler by running `wrangler types` (hash: c05ef0b4d5ad34d62b7a9ac73fa403af)
// Runtime types generated with workerd@1.20251118.0 2025-04-04 nodejs_compat
declare namespace Cloudflare {
interface GlobalProps {
@@ -9,15 +9,15 @@ declare namespace Cloudflare {
CLIENT_ID: "1a5483ab-4521-4702-9115-5857ac676851";
SCOPE: "openid profile email offline_access";
API_URL: "https://bcs7fgb9og.execute-api.sa-east-1.amazonaws.com";
ISSUER_URL: "https://id.saladeaula.digital";
BUCKET_NAME: "saladeaula.digital";
BUCKET_ENDPOINT: "https://s3.sa-east-1.amazonaws.com";
MEILI_HOST: "https://search.saladeaula.digital";
CLIENT_SECRET: string;
REDIRECT_URI: string;
SESSION_SECRET: string;
MEILI_API_KEY: string;
KONVIVA_SECRET_KEY: string;
REDIRECT_URI: string;
ISSUER_URL: string;
}
}
interface Env extends Cloudflare.Env {}
@@ -25,7 +25,7 @@ type StringifyValues<EnvType extends Record<string, unknown>> = {
[Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
};
declare namespace NodeJS {
interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "CLIENT_ID" | "SCOPE" | "API_URL" | "ISSUER_URL" | "BUCKET_NAME" | "BUCKET_ENDPOINT" | "MEILI_HOST" | "CLIENT_SECRET" | "REDIRECT_URI" | "SESSION_SECRET" | "MEILI_API_KEY" | "KONVIVA_SECRET_KEY">> {}
interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "CLIENT_ID" | "SCOPE" | "API_URL" | "BUCKET_NAME" | "BUCKET_ENDPOINT" | "MEILI_HOST" | "CLIENT_SECRET" | "SESSION_SECRET" | "MEILI_API_KEY" | "KONVIVA_SECRET_KEY" | "REDIRECT_URI" | "ISSUER_URL">> {}
}
// Begin runtime types

View File

@@ -5,8 +5,8 @@ import boto3
if TYPE_CHECKING:
from mypy_boto3_dynamodb.client import DynamoDBClient
from mypy_boto3_s3 import S3Client
from mypy_boto3_sesv2 import SESV2Client
from mypy_boto3_s3.client import S3Client
from mypy_boto3_sesv2.client import SESV2Client
else:
DynamoDBClient = object
SESV2Client = object

View File

@@ -6,9 +6,11 @@ import boto3
if TYPE_CHECKING:
from mypy_boto3_cognito_idp import CognitoIdentityProviderClient
from mypy_boto3_dynamodb.client import DynamoDBClient
from mypy_boto3_sesv2.client import SESV2Client
else:
DynamoDBClient = object
CognitoIdentityProviderClient = object
SESV2Client = object
def get_dynamodb_client() -> DynamoDBClient:
@@ -20,3 +22,4 @@ def get_dynamodb_client() -> DynamoDBClient:
dynamodb_client: DynamoDBClient = get_dynamodb_client()
idp_client: CognitoIdentityProviderClient = boto3.client('cognito-idp')
sesv2_client: SESV2Client = boto3.client('sesv2')

View File

@@ -2,6 +2,8 @@ import os
ISSUER: str = os.getenv('ISSUER') # type: ignore
EMAIL_SENDER = ('EDUSEG®', 'noreply@eduseg.com.br')
OAUTH2_TABLE: str = os.getenv('OAUTH2_TABLE') # type: ignore
OAUTH2_REFRESH_TOKEN_EXPIRES_IN = 86_400 * 7 # 7 days
OAUTH2_SCOPES_SUPPORTED: list[str] = [

View File

@@ -0,0 +1,20 @@
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.data_classes import (
EventBridgeEvent,
event_source,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
from boto3clients import sesv2_client
from config import EMAIL_SENDER
logger = Logger(__name__)
@event_source(data_class=EventBridgeEvent)
def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
new_image = event.detail['new_image']
# Key pattern `PASSWORD_RESET#{code}`
*_, code = new_image['sk'].split('#')
return True

View File

@@ -2,11 +2,12 @@ from typing import Annotated
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.openapi.params import Body
from layercake.extra_types import CpfStr
from pydantic import EmailStr
router = Router()
@router.post('/forgot')
def forgot(email: Annotated[EmailStr, Body(embed=True)]):
def forgot(email: Annotated[EmailStr | CpfStr, Body(embed=True)]):
return {}

View File

@@ -12,7 +12,7 @@ dev = [
"pytest>=8.4.1",
"ruff>=0.12.1",
"pytest-cov>=6.2.1",
"boto3-stubs[cognito-idp,essential]>=1.40.44",
"boto3-stubs[cognito-idp,essential,sesv2]>=1.40.44",
]

View File

@@ -145,6 +145,9 @@ essential = [
{ name = "mypy-boto3-s3" },
{ name = "mypy-boto3-sqs" },
]
sesv2 = [
{ name = "mypy-boto3-sesv2" },
]
[[package]]
name = "botocore"
@@ -426,7 +429,7 @@ dependencies = [
[package.dev-dependencies]
dev = [
{ name = "boto3-stubs", extra = ["cognito-idp", "essential"] },
{ name = "boto3-stubs", extra = ["cognito-idp", "essential", "sesv2"] },
{ name = "jsonlines" },
{ name = "pytest" },
{ name = "pytest-cov" },
@@ -438,7 +441,7 @@ requires-dist = [{ name = "layercake", directory = "../layercake" }]
[package.metadata.requires-dev]
dev = [
{ name = "boto3-stubs", extras = ["cognito-idp", "essential"], specifier = ">=1.40.44" },
{ name = "boto3-stubs", extras = ["cognito-idp", "essential", "sesv2"], specifier = ">=1.40.44" },
{ name = "jsonlines", specifier = ">=4.0.0" },
{ name = "pytest", specifier = ">=8.4.1" },
{ name = "pytest-cov", specifier = ">=6.2.1" },
@@ -648,6 +651,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/85/a5/dba3384423834009bdd41c7021de5c663468a0e7bc4071cb301721e52a99/mypy_boto3_s3-1.40.26-py3-none-any.whl", hash = "sha256:6d055d16ef89a0133ade92f6b4f09603e4acc31a0f5e8f846edf4eb48f17b5a7", size = 82762, upload-time = "2025-09-08T20:12:19.338Z" },
]
[[package]]
name = "mypy-boto3-sesv2"
version = "1.40.58"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/eb/29/95a662122aa340cbf9a272639a20f3b77ef380e171c08d31da3cce0c46a3/mypy_boto3_sesv2-1.40.58.tar.gz", hash = "sha256:7b99f8df3821ec4a3408eea9de6de10bcea59397804fd8014bc6a5b8b1583913", size = 46559, upload-time = "2025-10-23T20:15:22.426Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/91/f2/79307d855d5c3f58806b27c6f41062f2e6985e31451d4ed690bbb357cec4/mypy_boto3_sesv2-1.40.58-py3-none-any.whl", hash = "sha256:c6cf7058e038553f3aa8f8111a6de067878462cbe22c9c8baf78cdd891a0e75f", size = 51779, upload-time = "2025-10-23T20:15:20.216Z" },
]
[[package]]
name = "mypy-boto3-sqs"
version = "1.40.35"

56
package-lock.json generated
View File

@@ -10,7 +10,7 @@
],
"devDependencies": {
"prettier": "^3.6.2",
"turbo": "^2.6.0",
"turbo": "^2.6.2",
"typescript": "5.9.2"
},
"engines": {
@@ -6404,27 +6404,27 @@
"license": "0BSD"
},
"node_modules/turbo": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo/-/turbo-2.6.1.tgz",
"integrity": "sha512-qBwXXuDT3rA53kbNafGbT5r++BrhRgx3sAo0cHoDAeG9g1ItTmUMgltz3Hy7Hazy1ODqNpR+C7QwqL6DYB52yA==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/turbo/-/turbo-2.6.2.tgz",
"integrity": "sha512-LiQAFS6iWvnY8ViGtoPgduWBeuGH9B32XR4p8H8jxU5PudwyHiiyf1jQW0fCC8gCCTz9itkIbqZLIyUu5AG33w==",
"dev": true,
"license": "MIT",
"bin": {
"turbo": "bin/turbo"
},
"optionalDependencies": {
"turbo-darwin-64": "2.6.1",
"turbo-darwin-arm64": "2.6.1",
"turbo-linux-64": "2.6.1",
"turbo-linux-arm64": "2.6.1",
"turbo-windows-64": "2.6.1",
"turbo-windows-arm64": "2.6.1"
"turbo-darwin-64": "2.6.2",
"turbo-darwin-arm64": "2.6.2",
"turbo-linux-64": "2.6.2",
"turbo-linux-arm64": "2.6.2",
"turbo-windows-64": "2.6.2",
"turbo-windows-arm64": "2.6.2"
}
},
"node_modules/turbo-darwin-64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.6.1.tgz",
"integrity": "sha512-Dm0HwhyZF4J0uLqkhUyCVJvKM9Rw7M03v3J9A7drHDQW0qAbIGBrUijQ8g4Q9Cciw/BXRRd8Uzkc3oue+qn+ZQ==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.6.2.tgz",
"integrity": "sha512-nF9d/YAyrNkyXn9lp3ZtgXPb7fZsik3cUNe/sBvUO0G5YezUS/kDYYw77IdjizDzairz8pL2ITCTUreG2d5iZQ==",
"cpu": [
"x64"
],
@@ -6436,9 +6436,9 @@
]
},
"node_modules/turbo-darwin-arm64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.6.1.tgz",
"integrity": "sha512-U0PIPTPyxdLsrC3jN7jaJUwgzX5sVUBsKLO7+6AL+OASaa1NbT1pPdiZoTkblBAALLP76FM0LlnsVQOnmjYhyw==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.6.2.tgz",
"integrity": "sha512-mmm0jFaVramST26XE1Lk2qjkjvLJHOe9f3TFjqY+aByjMK/ZmKE5WFPuCWo4L3xhwx+16T37rdPP//76loB3oA==",
"cpu": [
"arm64"
],
@@ -6450,9 +6450,9 @@
]
},
"node_modules/turbo-linux-64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.6.1.tgz",
"integrity": "sha512-eM1uLWgzv89bxlK29qwQEr9xYWBhmO/EGiH22UGfq+uXr+QW1OvNKKMogSN65Ry8lElMH4LZh0aX2DEc7eC0Mw==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.6.2.tgz",
"integrity": "sha512-IUMHjkVRJDUABGpi+iS1Le59aOl5DX88U5UT/mKaE7nNEjG465+a8UtYno56cZnLP+C6BkX4I93LFgYf9syjGQ==",
"cpu": [
"x64"
],
@@ -6464,9 +6464,9 @@
]
},
"node_modules/turbo-linux-arm64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.6.1.tgz",
"integrity": "sha512-MFFh7AxAQAycXKuZDrbeutfWM5Ep0CEZ9u7zs4Hn2FvOViTCzIfEhmuJou3/a5+q5VX1zTxQrKGy+4Lf5cdpsA==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.6.2.tgz",
"integrity": "sha512-0qQdZiimMUZj2Gfq87thYu0E02NaNcsB3lcEK/TD70Zzi7AxQoxye664Gis0Uao2j2L9/+05wC2btZ7SoFX3Gw==",
"cpu": [
"arm64"
],
@@ -6478,9 +6478,9 @@
]
},
"node_modules/turbo-windows-64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.6.1.tgz",
"integrity": "sha512-buq7/VAN7KOjMYi4tSZT5m+jpqyhbRU2EUTTvp6V0Ii8dAkY2tAAjQN1q5q2ByflYWKecbQNTqxmVploE0LVwQ==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.6.2.tgz",
"integrity": "sha512-BmMfFmt0VaoZL4NbtDq/dzGfjHsPoGU2+vFiZtkiYsttHY3fd/Dmgnu9PuRyJN1pv2M22q88rXO+dqYRHztLMw==",
"cpu": [
"x64"
],
@@ -6492,9 +6492,9 @@
]
},
"node_modules/turbo-windows-arm64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.6.1.tgz",
"integrity": "sha512-7w+AD5vJp3R+FB0YOj1YJcNcOOvBior7bcHTodqp90S3x3bLgpr7tE6xOea1e8JkP7GK6ciKVUpQvV7psiwU5Q==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.6.2.tgz",
"integrity": "sha512-0r4s4M/FgLxfjrdLPdqQUur8vZAtaWEi4jhkQ6wCIN2xzA9aee9IKwM53w7CQcjaLvWhT0AU7LTQHjFaHwxiKw==",
"cpu": [
"arm64"
],

View File

@@ -9,7 +9,7 @@
},
"devDependencies": {
"prettier": "^3.6.2",
"turbo": "^2.6.0",
"turbo": "^2.6.2",
"typescript": "5.9.2"
},
"optionalDependencies": {

View File

@@ -1,7 +1,17 @@
import os
from typing import TYPE_CHECKING
import boto3
if TYPE_CHECKING:
from mypy_boto3_dynamodb.client import DynamoDBClient
from mypy_boto3_s3.client import S3Client
from mypy_boto3_sesv2.client import SESV2Client
else:
DynamoDBClient = object
S3Client = object
SESV2Client = object
def get_dynamodb_client():
if os.getenv('AWS_LAMBDA_FUNCTION_NAME'):
@@ -10,6 +20,6 @@ def get_dynamodb_client():
return boto3.client('dynamodb', endpoint_url='http://127.0.0.1:8000')
dynamodb_client = get_dynamodb_client()
s3_client = boto3.client('s3')
sesv2_client = boto3.client('sesv2')
dynamodb_client: DynamoDBClient = get_dynamodb_client()
s3_client: S3Client = boto3.client('s3')
sesv2_client: SESV2Client = boto3.client('sesv2')

View File

@@ -8,7 +8,7 @@ dependencies = ["layercake"]
[dependency-groups]
dev = [
"boto3-stubs[essential]>=1.38.26",
"boto3-stubs[essential,sesv2]>=1.38.26",
"jsonlines>=4.0.0",
"pytest>=8.3.4",
"pytest-cov>=6.0.0",

16
users-events/uv.lock generated
View File

@@ -138,6 +138,9 @@ essential = [
{ name = "mypy-boto3-s3" },
{ name = "mypy-boto3-sqs" },
]
sesv2 = [
{ name = "mypy-boto3-sesv2" },
]
[[package]]
name = "botocore"
@@ -601,6 +604,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3b/fa/251b651c18341c7491909994bd459b12ad05e13059d65bfa65d3afabdf8d/mypy_boto3_s3-1.38.26-py3-none-any.whl", hash = "sha256:1129d64be1aee863e04f0c92ac8d315578f13ccae64fa199b20ad0950d2b9616", size = 80321, upload-time = "2025-05-29T19:42:59.199Z" },
]
[[package]]
name = "mypy-boto3-sesv2"
version = "1.38.46"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/08/02/7d6747098eebf2a8639f33a1cb963ddad4f320e823e6e626ec3e1aad4e5b/mypy_boto3_sesv2-1.38.46.tar.gz", hash = "sha256:efebb7e6495b6c38cf1549833b4f8f889b12b831206013d9d11f41aa1d495a45", size = 42715, upload-time = "2025-06-27T20:34:02.677Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/45/83/00e89c38eade7dd9915599eefea30bcbe259c2bbb4bb8c08a02e4af6486c/mypy_boto3_sesv2-1.38.46-py3-none-any.whl", hash = "sha256:a03e979b0a7489d877f9c7912ea82de863f59a76014715edbcdbc1ab69ce00d8", size = 47335, upload-time = "2025-06-27T20:33:57.211Z" },
]
[[package]]
name = "mypy-boto3-sqs"
version = "1.38.0"
@@ -1121,7 +1133,7 @@ dependencies = [
[package.dev-dependencies]
dev = [
{ name = "boto3-stubs", extra = ["essential"] },
{ name = "boto3-stubs", extra = ["essential", "sesv2"] },
{ name = "jsonlines" },
{ name = "pytest" },
{ name = "pytest-cov" },
@@ -1133,7 +1145,7 @@ requires-dist = [{ name = "layercake", directory = "../layercake" }]
[package.metadata.requires-dev]
dev = [
{ name = "boto3-stubs", extras = ["essential"], specifier = ">=1.38.26" },
{ name = "boto3-stubs", extras = ["essential", "sesv2"], specifier = ">=1.38.26" },
{ name = "jsonlines", specifier = ">=4.0.0" },
{ name = "pytest", specifier = ">=8.3.4" },
{ name = "pytest-cov", specifier = ">=6.0.0" },