Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: World ID Face auth support #290

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/with-html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ <h1 id="heading">idkit-js</h1>
app_id: 'app_ce4cb73cb75fc3b73b71ffb4de178410',
action: 'test-action',
action_description: 'Test action description',
disable_face_auth: true,
handleVerify: response => {
// verify the IDKIt proof, throw an error to show the error screen
},
Expand Down
1 change: 1 addition & 0 deletions examples/with-next/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const Home = ({ app_id, action, signal }: InferGetServerSidePropsType<typeof get
handleVerify={proof => verify(proof, app_id, action, signal)}
app_id={app_id}
verification_level={VerificationLevel.Device}
disable_face_auth={true}
>
{({ open }) => <button onClick={open}>Open IDKit</button>}
</IDKitWidget>
Expand Down
17 changes: 15 additions & 2 deletions packages/core/src/bridge.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { create } from 'zustand'
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 { VerificationLevel, type IDKitConfig } from '@/types/config'
import { decryptResponse, encryptRequest, exportKey, generateKey } from '@/lib/crypto'
import {
DEFAULT_VERIFICATION_LEVEL,
Expand Down Expand Up @@ -56,7 +56,15 @@ export const useWorldBridgeStore = create<WorldBridgeStore>((set, get) => ({
bridge_url: DEFAULT_BRIDGE_URL,
verificationState: VerificationState.PreparingClient,

createClient: async ({ bridge_url, app_id, verification_level, action_description, action, signal }) => {
createClient: async ({
bridge_url,
app_id,
verification_level,
action_description,
action,
signal,
disable_face_auth,
}) => {
const { key, iv } = await generateKey()

if (bridge_url) {
Expand All @@ -68,6 +76,10 @@ export const useWorldBridgeStore = create<WorldBridgeStore>((set, get) => ({
}
}

if (disable_face_auth && verification_level === VerificationLevel.Device) {
throw new Error('Face auth is not supported for device verification')
}

const res = await fetch(new URL('/request', bridge_url ?? DEFAULT_BRIDGE_URL), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
Expand All @@ -84,6 +96,7 @@ export const useWorldBridgeStore = create<WorldBridgeStore>((set, get) => ({
verification_level ?? DEFAULT_VERIFICATION_LEVEL
),
verification_level: verification_level ?? DEFAULT_VERIFICATION_LEVEL,
disable_face_auth,
})
)
),
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ export type IDKitConfig = {
bridge_url?: string
/** The minimum required level of verification. Defaults to "orb". */
verification_level?: VerificationLevel
/** Whether to require face authentication for the action. Defaults to false. */
disable_face_auth?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const getOptions = (store: IDKitStore) => ({
setErrorState: store.setErrorState,
verification_level: store.verification_level,
action_description: store.action_description,
disable_face_auth: store.disable_face_auth,
})

const WorldIDState = () => {
Expand All @@ -34,6 +35,7 @@ const WorldIDState = () => {
bridge_url,
action_description,
verification_level,
disable_face_auth,
setErrorState,
} = useIDKitStore(getOptions, shallow)

Expand All @@ -43,7 +45,8 @@ const WorldIDState = () => {
signal,
bridge_url,
verification_level,
action_description
action_description,
disable_face_auth
)

useEffect(() => reset, [reset])
Expand Down
16 changes: 14 additions & 2 deletions packages/react/src/services/wld-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export const useWorldBridge = (
signal?: IDKitConfig['signal'],
bridge_url?: IDKitConfig['bridge_url'],
verification_level?: IDKitConfig['verification_level'],
action_description?: IDKitConfig['action_description']
action_description?: IDKitConfig['action_description'],
disable_face_auth?: IDKitConfig['disable_face_auth']
): UseAppBridgeResponse => {
const ref_verification_level = useRef(verification_level)
const { reset, result, connectorURI, createClient, pollForUpdates, verificationState, errorCode } =
Expand All @@ -31,9 +32,20 @@ export const useWorldBridge = (
bridge_url,
action_description,
verification_level: ref_verification_level.current,
disable_face_auth,
})
}
}, [app_id, action, signal, action_description, createClient, ref_verification_level, bridge_url, connectorURI])
}, [
app_id,
action,
signal,
action_description,
createClient,
ref_verification_level,
bridge_url,
connectorURI,
disable_face_auth,
])

useEffect(() => {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
Expand Down
6 changes: 4 additions & 2 deletions packages/react/src/store/idkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export type IDKitStore = {
signal: IDKitConfig['signal']
bridge_url?: IDKitConfig['bridge_url']
action_description?: IDKitConfig['action_description']
disable_face_auth?: IDKitConfig['disable_face_auth']
verification_level: NonNullable<IDKitConfig['verification_level']>

open: boolean
stage: IDKITStage
autoClose: boolean
Expand Down Expand Up @@ -52,7 +52,7 @@ const useIDKitStore = createWithEqualityFn<IDKitStore>()(
action_description: '',
bridge_url: '',
verification_level: DEFAULT_VERIFICATION_LEVEL,

disable_face_auth: false,
open: false,
result: null,
errorTitle: '',
Expand Down Expand Up @@ -103,6 +103,7 @@ const useIDKitStore = createWithEqualityFn<IDKitStore>()(
verification_level,
action_description,
bridge_url,
disable_face_auth,
autoClose,
advanced,
}: Config,
Expand All @@ -116,6 +117,7 @@ const useIDKitStore = createWithEqualityFn<IDKitStore>()(
autoClose: autoClose ?? true,
app_id: advanced?.self_hosted ? SELF_HOSTED_APP_ID : app_id,
verification_level: verification_level ?? DEFAULT_VERIFICATION_LEVEL,
disable_face_auth,
})

get().addSuccessCallback(onSuccess, source)
Expand Down
Loading