Skip to content

Commit

Permalink
feat: validate bridge_url (#232)
Browse files Browse the repository at this point in the history
* fix: normalize trailing slash

bridge_url param will now behave properly with or without trailing slash

* feat: validate bridge_url

performs validation of bridge_url in idkit-core

* allow localhost bridge_url with staging app for dev work

* Update packages/core/src/lib/validation.ts

Co-authored-by: pdtfh <149602456+pdtfh@users.noreply.github.com>

* fix: leading dot for domain check

---------

Co-authored-by: pdtfh <149602456+pdtfh@users.noreply.github.com>
  • Loading branch information
0xPenryn and pdtfh committed Jan 19, 2024
1 parent 9d7f66a commit 24686c7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
14 changes: 12 additions & 2 deletions packages/core/src/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type IDKitConfig } from '@/types/config'
import { VerificationState } from '@/types/bridge'
import type { ISuccessResult } from '@/types/result'
import type { CredentialType } from '@/types/config'
import { validate_bridge_url } from './lib/validation'
import { encodeAction, generateSignal } from '@/lib/hashing'
import { AppErrorCodes, ResponseStatus } from '@/types/bridge'
import { decryptResponse, encryptRequest, exportKey, generateKey } from '@/lib/crypto'
Expand Down Expand Up @@ -58,7 +59,16 @@ export const useWorldBridgeStore = create<WorldBridgeStore>((set, get) => ({
createClient: async ({ bridge_url, app_id, verification_level, action_description, action, signal }) => {
const { key, iv } = await generateKey()

const res = await fetch(`${bridge_url ?? DEFAULT_BRIDGE_URL}/request`, {
if (bridge_url) {
const validation = validate_bridge_url(bridge_url, app_id.includes('staging'))
if (!validation.valid) {
console.error(validation.errors.join('\n'))
set({ verificationState: VerificationState.Failed })
throw new Error('Invalid bridge_url. Please check the console for more details.')
}
}

const res = await fetch(new URL('/request', bridge_url ?? DEFAULT_BRIDGE_URL), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(
Expand Down Expand Up @@ -102,7 +112,7 @@ export const useWorldBridgeStore = create<WorldBridgeStore>((set, get) => ({
const key = get().key
if (!key) throw new Error('No keypair found. Please call `createClient` first.')

const res = await fetch(`${get().bridge_url}/response/${get().requestId}`)
const res = await fetch(new URL(`/response/${get().requestId}`, get().bridge_url))

if (!res.ok) {
return set({
Expand Down
46 changes: 46 additions & 0 deletions packages/core/src/lib/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
export type ValidationResponse = { valid: true } | { valid: false; errors: string[] }

export function validate_bridge_url(bridge_url: string, is_staging?: boolean): ValidationResponse {
try {
new URL(bridge_url)
} catch (e) {
return { valid: false, errors: ['Failed to parse Bridge URL.'] }
}

const test_url = new URL(bridge_url)
const errors: string[] = []

if (is_staging && ['localhost', '127.0.0.1'].includes(test_url.hostname)) {
console.log('Using staging app_id with localhost bridge_url. Skipping validation.')
return { valid: true }
}

if (test_url.protocol !== 'https:') {
errors.push('Bridge URL must use HTTPS.')
}
if (test_url.port) {
errors.push('Bridge URL must use the default port (443).')
}
if (test_url.pathname !== '/') {
errors.push('Bridge URL must not have a path.')
}
if (test_url.search) {
errors.push('Bridge URL must not have query parameters.')
}
if (test_url.hash) {
errors.push('Bridge URL must not have a fragment.')
}

// remove once restriction lifted in world app
if (!test_url.hostname.endsWith('.worldcoin.org') && !test_url.hostname.endsWith('.toolsforhumanity.com')) {
console.warn(
"Bridge URL should be a subdomain of worldcoin.org or toolsforhumanity.com. The user's identity wallet may refuse to connect. This is a temporary measure and may be removed in the future."
)
}

if (errors.length) {
return { valid: false, errors }
}

return { valid: true }
}

0 comments on commit 24686c7

Please sign in to comment.