diff --git a/apps/dashboard/src/@/actions/billing.ts b/apps/dashboard/src/@/actions/billing.ts index 1eb0a9b78ba..540e7485804 100644 --- a/apps/dashboard/src/@/actions/billing.ts +++ b/apps/dashboard/src/@/actions/billing.ts @@ -18,7 +18,7 @@ export async function reSubscribePlan(options: { const res = await fetch( new URL( - `/v1/teams/${options.teamId}/checkout/resubscribe-plan`, + `/v1/teams/${encodeURIComponent(options.teamId)}/checkout/resubscribe-plan`, NEXT_PUBLIC_THIRDWEB_API_HOST, ), { @@ -59,7 +59,7 @@ export async function getChainInfraCheckoutURL(options: { const res = await fetch( new URL( - `/v1/teams/${options.teamSlug}/checkout/create-link`, + `/v1/teams/${encodeURIComponent(options.teamSlug)}/checkout/create-link`, NEXT_PUBLIC_THIRDWEB_API_HOST, ), { diff --git a/apps/dashboard/src/@/actions/team/acceptInvite.ts b/apps/dashboard/src/@/actions/team/acceptInvite.ts index 8621caee41c..83b85e2ec07 100644 --- a/apps/dashboard/src/@/actions/team/acceptInvite.ts +++ b/apps/dashboard/src/@/actions/team/acceptInvite.ts @@ -17,7 +17,7 @@ export async function acceptInvite(options: { } const res = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${options.teamId}/invites/${options.inviteId}/accept`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(options.teamId)}/invites/${encodeURIComponent(options.inviteId)}/accept`, { body: JSON.stringify({}), headers: { diff --git a/apps/dashboard/src/@/actions/team/deleteTeam.ts b/apps/dashboard/src/@/actions/team/deleteTeam.ts index 628a343fe6b..e87a59c96f6 100644 --- a/apps/dashboard/src/@/actions/team/deleteTeam.ts +++ b/apps/dashboard/src/@/actions/team/deleteTeam.ts @@ -13,7 +13,7 @@ export async function deleteTeam(options: { teamId: string }) { } const res = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${options.teamId}`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(options.teamId)}`, { headers: { Authorization: `Bearer ${token}`, diff --git a/apps/dashboard/src/@/actions/team/sendTeamInvite.ts b/apps/dashboard/src/@/actions/team/sendTeamInvite.ts index b9842587c49..7758e65c7d5 100644 --- a/apps/dashboard/src/@/actions/team/sendTeamInvite.ts +++ b/apps/dashboard/src/@/actions/team/sendTeamInvite.ts @@ -41,7 +41,7 @@ async function sendInvite( token: string, ) { const res = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamId}/invites`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(teamId)}/invites`, { body: JSON.stringify({ inviteEmail: invite.email, diff --git a/apps/dashboard/src/@/api/project/projects.ts b/apps/dashboard/src/@/api/project/projects.ts index 126ff06939e..4950f5f77ea 100644 --- a/apps/dashboard/src/@/api/project/projects.ts +++ b/apps/dashboard/src/@/api/project/projects.ts @@ -13,7 +13,7 @@ export async function getProjects(teamSlug: string) { } const teamsRes = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamSlug}/projects`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(teamSlug)}/projects`, { headers: { Authorization: `Bearer ${token}`, @@ -34,7 +34,7 @@ export async function getProject(teamSlug: string, projectSlug: string) { } const teamsRes = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamSlug}/projects/${projectSlug}`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(teamSlug)}/projects/${encodeURIComponent(projectSlug)}`, { headers: { Authorization: `Bearer ${token}`, diff --git a/apps/dashboard/src/@/api/team/audit-log.ts b/apps/dashboard/src/@/api/team/audit-log.ts index 3067f52e489..f1ed831f70f 100644 --- a/apps/dashboard/src/@/api/team/audit-log.ts +++ b/apps/dashboard/src/@/api/team/audit-log.ts @@ -48,7 +48,7 @@ export async function getAuditLogs(teamSlug: string, cursor?: string) { throw new Error("No auth token found"); } const url = new URL( - `/v1/teams/${teamSlug}/audit-log`, + `/v1/teams/${encodeURIComponent(teamSlug)}/audit-log`, NEXT_PUBLIC_THIRDWEB_API_HOST, ); if (cursor) { diff --git a/apps/dashboard/src/@/api/team/dedicated-support.ts b/apps/dashboard/src/@/api/team/dedicated-support.ts index 620e98b4c11..6360b0934fb 100644 --- a/apps/dashboard/src/@/api/team/dedicated-support.ts +++ b/apps/dashboard/src/@/api/team/dedicated-support.ts @@ -15,7 +15,7 @@ export async function createDedicatedSupportChannel( const res = await fetch( new URL( - `/v1/teams/${teamIdOrSlug}/dedicated-support-channel`, + `/v1/teams/${encodeURIComponent(teamIdOrSlug)}/dedicated-support-channel`, NEXT_PUBLIC_THIRDWEB_API_HOST, ), { diff --git a/apps/dashboard/src/@/api/team/verified-domain.ts b/apps/dashboard/src/@/api/team/verified-domain.ts index 241f2dde71b..26ff2ac1949 100644 --- a/apps/dashboard/src/@/api/team/verified-domain.ts +++ b/apps/dashboard/src/@/api/team/verified-domain.ts @@ -27,7 +27,7 @@ export async function checkDomainVerification( } const res = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamIdOrSlug}/verified-domain`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(teamIdOrSlug)}/verified-domain`, { headers: { Authorization: `Bearer ${token}`, @@ -54,7 +54,7 @@ export async function createDomainVerification( } const res = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamIdOrSlug}/verified-domain`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(teamIdOrSlug)}/verified-domain`, { body: JSON.stringify({ domain }), headers: { diff --git a/apps/dashboard/src/app/(app)/api/testnet-faucet/claim/route.ts b/apps/dashboard/src/app/(app)/api/testnet-faucet/claim/route.ts index 974678ab948..04e85b34960 100644 --- a/apps/dashboard/src/app/(app)/api/testnet-faucet/claim/route.ts +++ b/apps/dashboard/src/app/(app)/api/testnet-faucet/claim/route.ts @@ -59,8 +59,9 @@ export const POST = async (req: NextRequest) => { const requestBody = (await req.json()) as RequestTestnetFundsPayload; const { chainId, toAddress, turnstileToken } = requestBody; - if (Number.isNaN(chainId)) { - throw new Error("Invalid chain ID."); + const chainIdStr = String(chainId); + if (!/^[1-9]\d*$/.test(chainIdStr)) { + return NextResponse.json({ error: "Invalid chain ID." }, { status: 400 }); } if ( @@ -224,7 +225,7 @@ export const POST = async (req: NextRequest) => { cacheSet(addressCacheKey, "claimed", 24 * 60 * 60), ]); // then actually transfer the funds - const url = `${THIRDWEB_ENGINE_URL}/backend-wallet/${chainId}/transfer`; + const url = `${THIRDWEB_ENGINE_URL}/backend-wallet/${chainIdStr}/transfer`; const response = await fetch(url, { body: JSON.stringify({ amount: amountToClaim, diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/create/actions/create-ecosystem.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/create/actions/create-ecosystem.ts index f9b24629c5e..ca7ff40915c 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/create/actions/create-ecosystem.ts +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/create/actions/create-ecosystem.ts @@ -32,7 +32,7 @@ export async function createEcosystem(options: { }); const res = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamSlug}/checkout/create-link`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(teamSlug)}/checkout/create-link`, { body: JSON.stringify({ baseUrl: BASE_URL, diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/general/updateTeam.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/general/updateTeam.ts index 8d358fb26e2..67d82ffbecb 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/general/updateTeam.ts +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/general/updateTeam.ts @@ -15,7 +15,7 @@ export async function updateTeam(params: { } const res = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${params.teamId}`, + `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodeURIComponent(params.teamId)}`, { body: JSON.stringify(params.value), headers: { diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/fetchWithAuthToken.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/fetchWithAuthToken.ts index dcd8f156814..19bd7e17fa5 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/fetchWithAuthToken.ts +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/fetchWithAuthToken.ts @@ -1,5 +1,4 @@ -"use server"; - +import "server-only"; import { getAuthToken } from "@/api/auth-token"; import type { Project } from "@/api/project/projects"; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/session.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/session.ts index b9f958bc4f6..3c003c4c1f4 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/session.ts +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/api/session.ts @@ -58,7 +58,7 @@ export async function updateSession(params: { const res = await fetchWithAuthToken({ body: body, - endpoint: `${NEXT_PUBLIC_THIRDWEB_AI_HOST}/session/${params.sessionId}`, + endpoint: `${NEXT_PUBLIC_THIRDWEB_AI_HOST}/session/${encodeURIComponent(params.sessionId)}`, method: "PUT", project: params.project, }); @@ -76,7 +76,7 @@ export async function deleteSession(params: { sessionId: string; }) { const res = await fetchWithAuthToken({ - endpoint: `${NEXT_PUBLIC_THIRDWEB_AI_HOST}/session/${params.sessionId}`, + endpoint: `${NEXT_PUBLIC_THIRDWEB_AI_HOST}/session/${encodeURIComponent(params.sessionId)}`, method: "DELETE", project: params.project, }); @@ -109,7 +109,7 @@ export async function getSessionById(params: { sessionId: string; }) { const res = await fetchWithAuthToken({ - endpoint: `${NEXT_PUBLIC_THIRDWEB_AI_HOST}/session/${params.sessionId}`, + endpoint: `${NEXT_PUBLIC_THIRDWEB_AI_HOST}/session/${encodeURIComponent(params.sessionId)}`, method: "GET", project: params.project, }); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/chat/history/ChatHistoryPage.stories.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/chat/history/ChatHistoryPage.stories.tsx index 8714dc18fc8..b4c2e9950a0 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/chat/history/ChatHistoryPage.stories.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/chat/history/ChatHistoryPage.stories.tsx @@ -56,7 +56,7 @@ function createRandomSessions(length: number) { for (let i = 0; i < length; i++) { sessions.push({ created_at: new Date().toISOString(), - id: Math.random().toString(), + id: crypto.randomUUID(), title: randomLorem(Math.floor(5 + Math.random() * 15)), updated_at: subDays( new Date(), diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx index 5e014ee5af6..ddc7e62571d 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx @@ -269,7 +269,7 @@ export function LaunchTokenStatus(props: { } const contractLink = contractAddress - ? `/team/${props.teamSlug}/${props.projectSlug}/contract/${formValues.chain}/${contractAddress}` + ? `/team/${props.teamSlug}/${props.projectSlug}/contract/${encodeURIComponent(formValues.chain)}/${encodeURIComponent(contractAddress)}` : null; return ( diff --git a/apps/nebula/src/app/(app)/chat/history/ChatHistoryPage.stories.tsx b/apps/nebula/src/app/(app)/chat/history/ChatHistoryPage.stories.tsx index 7a29b517422..3033c1c23e8 100644 --- a/apps/nebula/src/app/(app)/chat/history/ChatHistoryPage.stories.tsx +++ b/apps/nebula/src/app/(app)/chat/history/ChatHistoryPage.stories.tsx @@ -55,7 +55,7 @@ function createRandomSessions(length: number) { for (let i = 0; i < length; i++) { sessions.push({ created_at: new Date().toISOString(), - id: Math.random().toString(), + id: crypto.randomUUID(), title: randomLorem(Math.floor(5 + Math.random() * 15)), updated_at: subDays( new Date(), diff --git a/apps/wallet-ui/src/lib/chains.ts b/apps/wallet-ui/src/lib/chains.ts index e8a19417c88..94b1f08a82e 100644 --- a/apps/wallet-ui/src/lib/chains.ts +++ b/apps/wallet-ui/src/lib/chains.ts @@ -20,7 +20,7 @@ export async function getChains() { export async function getChain(chainIdOrSlug: string): Promise { const res = await fetch( - `https://api.thirdweb.com/v1/chains/${chainIdOrSlug}`, + `https://api.thirdweb.com/v1/chains/${encodeURIComponent(chainIdOrSlug)}`, // revalidate every 15 minutes { next: { revalidate: 15 * 60 } }, );