Skip to content

Commit

Permalink
feat: done
Browse files Browse the repository at this point in the history
  • Loading branch information
janrtvld committed Nov 26, 2024
1 parent 41cd2c3 commit 9579682
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 112 deletions.
7 changes: 4 additions & 3 deletions apps/easypid/src/app/(app)/federation.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { FunkeFederationDetailScreen } from '@easypid/features/wallet/FunkeFederationDetailScreen'
import { useLocalSearchParams } from 'expo-router'
import type { TrustedEntity } from 'packages/agent/src/invitation/handler'

Check failure on line 3 in apps/easypid/src/app/(app)/federation.tsx

View workflow job for this annotation

GitHub Actions / Validate

Module '"packages/agent/src/invitation/handler"' declares 'TrustedEntity' locally, but it is not exported.

export default function Screen() {
const { entityId, trustedEntityIds, name, logo } = useLocalSearchParams()
const { entityId, trustedEntities, name, logo } = useLocalSearchParams()

const trustedEntityIdsArray = Array.isArray(trustedEntityIds) ? trustedEntityIds : trustedEntityIds?.split(',') ?? []
const trustedEntitiesArray = JSON.parse(decodeURIComponent(trustedEntities as string)) as Array<TrustedEntity>

return (
<FunkeFederationDetailScreen
entityId={entityId as string}
trustedEntityIds={trustedEntityIdsArray}
trustedEntities={trustedEntitiesArray}
name={name as string}
logo={logo as string}
/>
Expand Down
16 changes: 6 additions & 10 deletions apps/easypid/src/features/receive/slides/VerifyPartySlide.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { DisplayImage } from '@package/agent'
import type { DisplayImage, TrustedEntity } from '@package/agent'

import {
Circle,
Expand Down Expand Up @@ -26,7 +26,7 @@ interface VerifyPartySlideProps {
backgroundColor?: string
lastInteractionDate?: string
onContinue?: () => Promise<void>
verifiedEntityIds?: Record<string, boolean>
verifiedEntities?: Array<TrustedEntity>
}

export const VerifyPartySlide = ({
Expand All @@ -37,17 +37,13 @@ export const VerifyPartySlide = ({
backgroundColor,
lastInteractionDate,
onContinue,
verifiedEntityIds,
verifiedEntities,
}: VerifyPartySlideProps) => {
const router = useRouter()
const { onNext, onCancel } = useWizard()
const { withHaptics } = useHaptics()
const [isLoading, setIsLoading] = useState(false)

const trustedEntityIds = Object.entries(verifiedEntityIds ?? {})
.filter(([_, isVerified]) => isVerified)
.map(([entityId]) => entityId)

const handleContinue = async () => {
setIsLoading(true)
if (onContinue) {
Expand All @@ -59,7 +55,7 @@ export const VerifyPartySlide = ({

const onPressVerifiedIssuer = withHaptics(() => {
router.push(
`/federation?name=${name}&logo=${logo?.url}&entityId=${entityId}&trustedEntityIds=${trustedEntityIds?.join(',') ?? ''}`
`/federation?name=${encodeURIComponent(name ?? '')}&logo=${encodeURIComponent(logo?.url ?? '')}&entityId=${encodeURIComponent(entityId)}&trustedEntities=${encodeURIComponent(JSON.stringify(verifiedEntities ?? []))}`
)
})

Expand Down Expand Up @@ -99,11 +95,11 @@ export const VerifyPartySlide = ({
</YStack>

<YStack gap="$4">
{trustedEntityIds && trustedEntityIds.length > 0 ? (
{verifiedEntities && verifiedEntities.length > 0 ? (
<InfoButton
variant="info"
title="Recognized organisation"
description={`Approved by ${trustedEntityIds?.length} organisations`}
description={`Approved by ${verifiedEntities.length} organisations`}
onPress={onPressVerifiedIssuer}
/>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function FunkeOpenIdPresentationNotificationScreen() {
entityId={credentialsForRequest?.verifier.entityId as string}
verifierName={credentialsForRequest?.verifier.name}
logo={credentialsForRequest?.verifier.logo}
verifiedEntityIds={credentialsForRequest?.verifier.verifiedEntityIds}
verifiedEntities={credentialsForRequest?.verifier.verifiedEntities}
lastInteractionDate={lastInteractionDate}
onComplete={() => pushToWallet('replace')}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DisplayImage, FormattedSubmission } from '@package/agent'

import { type SlideStep, SlideWizard } from '@package/app'
import type { TrustedEntity } from 'packages/agent/src/invitation/handler'

Check failure on line 4 in apps/easypid/src/features/share/FunkePresentationNotificationScreen.tsx

View workflow job for this annotation

GitHub Actions / Validate

Module '"packages/agent/src/invitation/handler"' declares 'TrustedEntity' locally, but it is not exported.
import { LoadingRequestSlide } from '../receive/slides/LoadingRequestSlide'
import { VerifyPartySlide } from '../receive/slides/VerifyPartySlide'
import type { PresentationRequestResult } from './components/utils'
Expand All @@ -13,7 +14,7 @@ interface FunkePresentationNotificationScreenProps {
verifierName?: string
logo?: DisplayImage
lastInteractionDate?: string
verifiedEntityIds?: Record<string, boolean>
verifiedEntities?: Array<TrustedEntity>
submission?: FormattedSubmission
usePin: boolean
isAccepting: boolean
Expand All @@ -33,7 +34,7 @@ export function FunkePresentationNotificationScreen({
isAccepting,
submission,
onComplete,
verifiedEntityIds,
verifiedEntities,
}: FunkePresentationNotificationScreenProps) {
return (
<SlideWizard
Expand All @@ -56,7 +57,7 @@ export function FunkePresentationNotificationScreen({
name={verifierName}
logo={logo}
lastInteractionDate={lastInteractionDate}
verifiedEntityIds={verifiedEntityIds}
verifiedEntities={verifiedEntities}
/>
),
},
Expand Down
17 changes: 6 additions & 11 deletions apps/easypid/src/features/wallet/FunkeFederationDetailScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { TrustedEntity } from '@package/agent'
import {
Circle,
FlexPage,
Expand All @@ -12,33 +13,27 @@ import {
XStack,
YStack,
} from '@package/ui'
import { useTrustedEntities } from 'packages/agent/src'
import { TextBackButton, useScrollViewPosition } from 'packages/app/src'
import React from 'react'
import { useRef } from 'react'
import React, { useRef } from 'react'
import { useSafeAreaInsets } from 'react-native-safe-area-context'

interface FunkeFederationDetailScreenProps {
name: string
logo?: string
entityId?: string
trustedEntityIds?: string[]
trustedEntities?: Array<TrustedEntity>
}

export function FunkeFederationDetailScreen({
name,
logo,
entityId,
trustedEntityIds = [],
trustedEntities = [],
}: FunkeFederationDetailScreenProps) {
const { trustedEntities } = useTrustedEntities()

const { handleScroll, isScrolledByOffset, scrollEventThrottle } = useScrollViewPosition()
const { bottom } = useSafeAreaInsets()
const scrollViewRef = useRef<ScrollViewRefType>(null)

const filteredTrustedEntities = trustedEntities.filter((entity) => trustedEntityIds.includes(entity.entity_id))

return (
<FlexPage gap="$0" paddingHorizontal="$0">
<YStack
Expand Down Expand Up @@ -72,15 +67,15 @@ export function FunkeFederationDetailScreen({
<YStack gap="$2">
<Heading variant="sub2">Trusted by</Heading>
<Paragraph>
{filteredTrustedEntities.length > 0 ? (
{trustedEntities.length > 0 ? (
<>A list of organizations and whether they have approved {name}.</>
) : (
<>There are no organizations that have approved {name}.</>
)}
</Paragraph>
</YStack>
<YStack gap="$2">
{filteredTrustedEntities.map((entity) => {
{trustedEntities.map((entity) => {
return (
<XStack ai="center" key={entity.entity_id} br="$8" p="$3.5" gap="$3" bg="$grey-100">
{entity.logo_uri && (
Expand Down
24 changes: 13 additions & 11 deletions packages/agent/src/invitation/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ import {
import { setBatchCredentialMetadata } from '../openid4vc/batchMetadata'
import { getCredentialBindingResolver } from '../openid4vc/credentialBindingResolver'
import { extractOpenId4VcCredentialMetadata, setOpenId4VcCredentialMetadata } from '../openid4vc/displayMetadata'
import { TRUSTED_ENTITIES } from '../providers/TrustedEntitiesProvider'
import { BiometricAuthenticationError } from './error'
import { fetchInvitationDataUrl } from './fetchInvitation'
import { TRUSTED_ENTITIES } from './trustedEntities'
import type { TrustedEntity } from './trustedEntities'

export async function resolveOpenId4VciOffer({
agent,
Expand Down Expand Up @@ -498,20 +499,21 @@ export const getCredentialsForProofRequest = async ({
resolved.authorizationRequest.authorizationRequestPayload.client_metadata
}

let verifiedEntityIds: Record<string, boolean> | undefined = undefined
let verifiedEntities: Array<TrustedEntity> = []
if (entityId) {
const resolvedChains = await agent.modules.openId4VcHolder.resolveOpenIdFederationChains({
entityId: entityId ?? '',
entityId: entityId,
trustAnchorEntityIds: TRUSTED_ENTITIES,
})

// Return which resolved chains are actually resolved
verifiedEntityIds = Object.fromEntries(
resolvedChains.map((chain) => [
chain.trustAnchorEntityConfiguration.sub,
TRUSTED_ENTITIES.includes(chain.trustAnchorEntityConfiguration.sub),
])
)
verifiedEntities = resolvedChains
.map((chain) => ({
entity_id: chain.trustAnchorEntityConfiguration.sub,
organization_name:
chain.trustAnchorEntityConfiguration.metadata?.federation_entity?.organization_name ?? 'Unknown entity',
logo_uri: chain.trustAnchorEntityConfiguration.metadata?.federation_entity?.logo_uri,
}))
.filter((entity, index, self) => self.findIndex((e) => e.entity_id === entity.entity_id) === index)
}

let formattedSubmission: FormattedSubmission
Expand Down Expand Up @@ -549,7 +551,7 @@ export const getCredentialsForProofRequest = async ({
}
: undefined,
name: clientMetadata?.client_name,
verifiedEntityIds,
verifiedEntities,
},
formattedSubmission,
} as const
Expand Down
2 changes: 2 additions & 0 deletions packages/agent/src/invitation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ export {
acquireAuthorizationCodeUsingPresentation,
} from './handler'
export * from './error'

export type { TrustedEntity } from './trustedEntities'
16 changes: 16 additions & 0 deletions packages/agent/src/invitation/trustedEntities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const BASE_URL = 'https://macbook-pro-van-tom.curl-perch.ts.net/siop'

export const TRUSTED_ENTITIES = [
`${BASE_URL}/0193687b-0c27-7b82-a686-ff857dc6bbb3`,
`${BASE_URL}/0193687f-20d8-720a-9139-ed939ba510fa`,
// To be added
`${BASE_URL}/019368ed-3787-7669-b7f4-8c012238e90d`,
`${BASE_URL}/01936907-56a3-7007-a61f-44bff8b5d175`,
`${BASE_URL}/01936903-8879-733f-8eaf-6f2fa862099c`,
] satisfies [string, ...string[]]

export type TrustedEntity = {
entity_id: string
organization_name: string
logo_uri?: string
}
5 changes: 1 addition & 4 deletions packages/agent/src/providers/AgentProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import NativeAgentProvider from '@credo-ts/react-hooks'
import { ExchangeRecordDisplayMetadataProvider } from './ExchangeRecordDisplayMetadataProvider'
import { MdocRecordProvider } from './MdocProvider'
import { SdJwtVcRecordProvider } from './SdJwtVcsProvider'
import { TrustedEntitiesProvider } from './TrustedEntitiesProvider'
import { W3cCredentialRecordProvider } from './W3cCredentialsProvider'

export interface AgentProviderProps {
Expand All @@ -18,9 +17,7 @@ export const AgentProvider = ({ agent, children }: PropsWithChildren<AgentProvid
<W3cCredentialRecordProvider agent={agent}>
<SdJwtVcRecordProvider agent={agent}>
<MdocRecordProvider agent={agent}>
<ExchangeRecordDisplayMetadataProvider>
<TrustedEntitiesProvider agent={agent}>{children}</TrustedEntitiesProvider>
</ExchangeRecordDisplayMetadataProvider>
<ExchangeRecordDisplayMetadataProvider>{children}</ExchangeRecordDisplayMetadataProvider>
</MdocRecordProvider>
</SdJwtVcRecordProvider>
</W3cCredentialRecordProvider>
Expand Down
69 changes: 0 additions & 69 deletions packages/agent/src/providers/TrustedEntitiesProvider.tsx

This file was deleted.

0 comments on commit 9579682

Please sign in to comment.