From 5fd32f9d0168c1bcd21a79dbe9d7c938510459e9 Mon Sep 17 00:00:00 2001 From: Winston Yeo Date: Thu, 6 Jun 2024 15:23:23 +0800 Subject: [PATCH 1/2] chore: expose domain and bundle ID validation --- .../src/core/authorize/client.ts | 95 +++++++++++-------- packages/service-utils/src/node/index.ts | 14 ++- 2 files changed, 68 insertions(+), 41 deletions(-) diff --git a/packages/service-utils/src/core/authorize/client.ts b/packages/service-utils/src/core/authorize/client.ts index 5171f5f47cc..30966fabde1 100644 --- a/packages/service-utils/src/core/authorize/client.ts +++ b/packages/service-utils/src/core/authorize/client.ts @@ -51,36 +51,9 @@ export function authorizeClient( // validate domains if (origin) { if ( - // find matching domain, or if all domains allowed - // embedded-wallet.thirdweb(-dev).com is automatically allowed - // because the rpc is passed from user's domain to embedded-wallet.thirdweb.com iframe for use. - // Note this doesn't allow embedded-wallets from being used if it's disabled. The service check that runs after enforces that. - [ - ...domains, - "embedded-wallet.thirdweb.com", - "embedded-wallet.thirdweb-dev.com", - ].find((d) => { - // if any domain is allowed, we'll return true - if (d === "*") { - return true; - } - - // special rule for `localhost` - // if the domain is localhost, we'll allow any origin that starts with localhost - if (d === "localhost" && origin.startsWith("localhost")) { - return true; - } - - // If the allowedDomain has a wildcard, - // we'll check that the ending of our domain matches the wildcard - if (d.startsWith("*.")) { - // get rid of the * and check if it ends with the `..` - const domainRoot = d.slice(1); - return origin.endsWith(domainRoot); - } - - // If there's no wildcard, we'll check for an exact match - return d === origin; + authorizeDomains({ + domains, + origin, }) ) { return authResult; @@ -97,13 +70,9 @@ export function authorizeClient( // validate bundleId if (bundleId) { if ( - // find matching bundle id, or if all bundles allowed - bundleIds.find((b) => { - if (b === "*") { - return true; - } - - return b === bundleId; + authorizeBundleIds({ + bundleIds, + bundleId, }) ) { return authResult; @@ -125,3 +94,55 @@ export function authorizeClient( status: 401, }; } + +// Exposed for use in validating ecosystem partners settings +export function authorizeDomains({ + domains, + origin, +}: { domains: string[]; origin: string }): boolean { + // find matching domain, or if all domains allowed + // embedded-wallet.thirdweb(-dev).com is automatically allowed + // because the rpc is passed from user's domain to embedded-wallet.thirdweb.com iframe for use. + // Note this doesn't allow embedded-wallets from being used if it's disabled. The service check that runs after enforces that. + return !![ + ...domains, + "embedded-wallet.thirdweb.com", + "embedded-wallet.thirdweb-dev.com", + ].find((d) => { + // if any domain is allowed, we'll return true + if (d === "*") { + return true; + } + + // special rule for `localhost` + // if the domain is localhost, we'll allow any origin that starts with localhost + if (d === "localhost" && origin.startsWith("localhost")) { + return true; + } + + // If the allowedDomain has a wildcard, + // we'll check that the ending of our domain matches the wildcard + if (d.startsWith("*.")) { + // get rid of the * and check if it ends with the `..` + const domainRoot = d.slice(1); + return origin.endsWith(domainRoot); + } + + // If there's no wildcard, we'll check for an exact match + return d === origin; + }); +} + +export function authorizeBundleIds({ + bundleIds, + bundleId, +}: { bundleIds: string[]; bundleId: string }): boolean { + // find matching bundle id, or if all bundles allowed + return !!bundleIds.find((b) => { + if (b === "*") { + return true; + } + + return b === bundleId; + }); +} diff --git a/packages/service-utils/src/node/index.ts b/packages/service-utils/src/node/index.ts index 7e0a2306235..26133623987 100644 --- a/packages/service-utils/src/node/index.ts +++ b/packages/service-utils/src/node/index.ts @@ -1,17 +1,23 @@ import { createHash } from "node:crypto"; import { authorize } from "../core/authorize"; -import type { ServerResponse } from "node:http"; -import type { IncomingHttpHeaders, IncomingMessage } from "node:http"; +import type { + IncomingHttpHeaders, + IncomingMessage, + ServerResponse, +} from "node:http"; import type { CoreServiceConfig } from "../core/api"; import type { AuthorizationInput } from "../core/authorize"; import type { AuthorizationResult } from "../core/authorize/types"; import type { CoreAuthInput } from "../core/types"; -export * from "../core/services"; +export { + authorizeBundleIds, + authorizeDomains, +} from "../core/authorize/client"; export * from "../core/rateLimit"; +export * from "../core/services"; export * from "../core/usageLimit"; - type NodeServiceConfig = CoreServiceConfig; export type AuthInput = CoreAuthInput & { From ea89f087a060e3c5f467975d14b25430a25bb797 Mon Sep 17 00:00:00 2001 From: Winston Yeo Date: Thu, 6 Jun 2024 15:28:31 +0800 Subject: [PATCH 2/2] chore: update export path chore: add changeset --- .changeset/twelve-scissors-share.md | 11 +++++++++++ packages/service-utils/src/core/authorize/client.ts | 8 ++++---- packages/service-utils/src/index.ts | 5 +++++ packages/service-utils/src/node/index.ts | 4 ---- 4 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 .changeset/twelve-scissors-share.md diff --git a/.changeset/twelve-scissors-share.md b/.changeset/twelve-scissors-share.md new file mode 100644 index 00000000000..dae7e75c54d --- /dev/null +++ b/.changeset/twelve-scissors-share.md @@ -0,0 +1,11 @@ +--- +"@thirdweb-dev/service-utils": patch +--- + +expose domain and bundle Id validation logic + +```typescript +import { authorizeDomain, authorizeBundleId } from "@thirdweb-dev/service-utils +const isValidDomain = authorizeDomain({ domains, origin }); +const isValidBundleId = authorizeBundleId({ bundleId, bundleIds }); +``` diff --git a/packages/service-utils/src/core/authorize/client.ts b/packages/service-utils/src/core/authorize/client.ts index 30966fabde1..aa3bafe5829 100644 --- a/packages/service-utils/src/core/authorize/client.ts +++ b/packages/service-utils/src/core/authorize/client.ts @@ -51,7 +51,7 @@ export function authorizeClient( // validate domains if (origin) { if ( - authorizeDomains({ + authorizeDomain({ domains, origin, }) @@ -70,7 +70,7 @@ export function authorizeClient( // validate bundleId if (bundleId) { if ( - authorizeBundleIds({ + authorizeBundleId({ bundleIds, bundleId, }) @@ -96,7 +96,7 @@ export function authorizeClient( } // Exposed for use in validating ecosystem partners settings -export function authorizeDomains({ +export function authorizeDomain({ domains, origin, }: { domains: string[]; origin: string }): boolean { @@ -133,7 +133,7 @@ export function authorizeDomains({ }); } -export function authorizeBundleIds({ +export function authorizeBundleId({ bundleIds, bundleId, }: { bundleIds: string[]; bundleId: string }): boolean { diff --git a/packages/service-utils/src/index.ts b/packages/service-utils/src/index.ts index 65bc814591b..c697f8dc8b4 100644 --- a/packages/service-utils/src/index.ts +++ b/packages/service-utils/src/index.ts @@ -1,2 +1,7 @@ // Exports the public service definitions. export * from "./core/services"; + +export { + authorizeBundleId, + authorizeDomain, +} from "./core/authorize/client"; diff --git a/packages/service-utils/src/node/index.ts b/packages/service-utils/src/node/index.ts index 26133623987..e00d1eb9198 100644 --- a/packages/service-utils/src/node/index.ts +++ b/packages/service-utils/src/node/index.ts @@ -11,10 +11,6 @@ import type { AuthorizationInput } from "../core/authorize"; import type { AuthorizationResult } from "../core/authorize/types"; import type { CoreAuthInput } from "../core/types"; -export { - authorizeBundleIds, - authorizeDomains, -} from "../core/authorize/client"; export * from "../core/rateLimit"; export * from "../core/services"; export * from "../core/usageLimit";