Skip to content

Commit

Permalink
fix: issue with ausweis sdk when setting up pid later (#255)
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <[email protected]>
Co-authored-by: Berend Sliedrecht <[email protected]>
  • Loading branch information
TimoGlastra and berendsliedrecht authored Dec 4, 2024
1 parent f41f39f commit 5aaad86
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 19 deletions.
5 changes: 5 additions & 0 deletions apps/easypid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,11 @@ The following standards and specifications were implemented.

### Phase 2

#### 04-12-2024

**Wallet**
- Fixed an issue where the PID setup would get stuck if you skipped it during onboarding [commit](https://github.com/animo/openid4vc-playground-funke/commit/65178e776bc421b9ca413542ea0e86db4ad1ead4)

#### 28-11-2024

**Playground**
Expand Down
5 changes: 4 additions & 1 deletion apps/easypid/src/features/onboarding/onboardingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,16 @@ export function OnboardingContextProvider({
}, [currentStepName])

const finishOnboarding = useCallback(() => {
// We don't need to handle the error if it's not active, but it's important we cancel
receivePidUseCase?.cancelIdCardScanning().catch(() => {})

setHasFinishedOnboarding(true)
// The Onboarding fades out based on the mmkv value
// Wait 500ms before navigating to home
setTimeout(() => {
router.replace('/')
}, 500)
}, [router, setHasFinishedOnboarding])
}, [router, setHasFinishedOnboarding, receivePidUseCase])

const onPinEnter = async (pin: string) => {
setWalletPin(pin)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { bdrPidCredentialDisplay, bdrPidIssuerDisplay } from '@easypid/use-cases/bdrPidMetadata'
import { CardWithAttributes } from '@package/app'
import { Button, HeroIcons, Paragraph, ScrollView, YStack } from '@package/ui'
import { sanitizeString } from '@package/utils'
import { CardWithAttributes } from 'packages/app/src'
import { useState } from 'react'

interface OnboardingIdCardRequestedAttributesProps {
Expand Down
15 changes: 7 additions & 8 deletions apps/easypid/src/features/pid/FunkePidSetupScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,6 @@ export function FunkePidSetupScreen() {
}

const onWalletPinEnter = async (pin: string) => {
// FIXME: We need to check if the pin is correct, but wallet is not locked.
// PIN is also not used now, as we only do C flow.

// await secureUnlock.unlockUsingPin(pin).then(() => {
// setWalletPin(pin)
// })

// If pin is simulator pin we require the user to retry so that second time
// they can set the real pin
const isSimulatorPinCode = pin === SIMULATOR_PIN
Expand Down Expand Up @@ -211,6 +204,12 @@ export function FunkePidSetupScreen() {
const onStart = (shouldUseCloudHsm: boolean) => setShouldUseCloudHsm(shouldUseCloudHsm)

const onIdCardPinEnter = (pin: string) => setIdCardPin(pin)
const onCancel = useCallback(() => {
// We just want to make sure to cancel, don't care about the result
void receivePidUseCase?.cancelIdCardScanning().catch(() => {})

pushToWallet()
}, [receivePidUseCase, pushToWallet])

const onStartScanning = async () => {
if (receivePidUseCase?.state !== 'id-card-auth') {
Expand Down Expand Up @@ -449,7 +448,7 @@ export function FunkePidSetupScreen() {
title: 'Stop ID Setup?',
description: 'If you stop, you can do the setup later.',
}}
onCancel={pushToWallet}
onCancel={onCancel}
/>
)
}
11 changes: 3 additions & 8 deletions apps/easypid/src/use-cases/ReceivePidUseCaseCFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
BiometricAuthenticationError,
OpenId4VciAuthorizationFlow,
type SdJwtVcRecord,
getCredentialCategoryMetadata,
receiveCredentialFromOpenId4VciOffer,
resolveOpenId4VciOffer,
setCredentialCategoryMetadata,
Expand All @@ -15,12 +14,7 @@ import {
import { getShouldUseCloudHsm } from '../features/onboarding/useShouldUseCloudHsm'
import { ReceivePidUseCaseFlow, type ReceivePidUseCaseFlowOptions } from './ReceivePidUseCaseFlow'
import { C_PRIME_SD_JWT_MDOC_OFFER } from './bdrPidIssuerOffers'
import {
bdrPidCredentialDisplay,
bdrPidIssuerDisplay,
bdrPidOpenId4VcMetadata,
bdrPidSdJwtTypeMetadata,
} from './bdrPidMetadata'
import { bdrPidOpenId4VcMetadata, bdrPidSdJwtTypeMetadata } from './bdrPidMetadata'

export class ReceivePidUseCaseCFlow extends ReceivePidUseCaseFlow {
public static async initialize(options: ReceivePidUseCaseFlowOptions) {
Expand Down Expand Up @@ -53,7 +47,8 @@ export class ReceivePidUseCaseCFlow extends ReceivePidUseCaseFlow {
resolved.resolvedAuthorizationRequest,
resolved.resolvedCredentialOffer
)
authFlow.startAuthFlow()
// We handle the error differently
authFlow.startAuthFlow().catch(() => {})
const accessRights = await authFlow.accessRights
authFlow.options.onStateChange?.('id-card-auth')
return { authFlow, accessRights }
Expand Down
54 changes: 53 additions & 1 deletion apps/easypid/src/use-cases/ReceivePidUseCaseFlow.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { AusweisAuthFlow, type AusweisAuthFlowOptions, sendCommand } from '@animo-id/expo-ausweis-sdk'
import {
AusweisAuthFlow,
type AusweisAuthFlowOptions,
addMessageListener,
initializeSdk,
sendCommand,
} from '@animo-id/expo-ausweis-sdk'
import type { MdocRecord } from '@credo-ts/core'
import type { AppAgent } from '@easypid/agent'
import type {
Expand Down Expand Up @@ -165,11 +171,57 @@ export abstract class ReceivePidUseCaseFlow<ExtraOptions = {}> {
}
}

/**
* We always try to gracefully shut the auth flow down
* but somtimes due to an error it may not be the case
* we make sure to always clean running auth flow before we
* start a new one
*/
private async cancelPotentiallyAbandonedAuthFlow() {
await initializeSdk()

const cancelPromise = new Promise((resolve, reject) => {
let hasCancelled = false
const subscription = addMessageListener((message) => {
// Auth flow is now cancelled
if (message.msg === 'AUTH' && message.result?.reason === 'User_Cancelled') {
subscription.remove()
resolve(undefined)
return
}

if (message.msg === 'STATUS' && !hasCancelled) {
// Auth flow is active, we need to cancel
if (message.workflow === 'AUTH') {
hasCancelled = true
sendCommand({ cmd: 'CANCEL' })
return
}

// Auth flow is not active, no need to cancel
subscription.remove()
resolve(undefined)
return
}
})

sendCommand({ cmd: 'GET_STATUS' })
})

return cancelPromise
}

protected async startAuthFlow() {
if (this.idCardAuthFlow.isActive) {
throw new Error('authentication flow already active')
}

try {
await this.cancelPotentiallyAbandonedAuthFlow()
} catch (error) {
return
}

// We return an authentication promise to make it easier to track the state
// We remove the callbacks once the error or success is triggered.
const authenticationPromise = new Promise<void>((resolve, reject) => {
Expand Down

0 comments on commit 5aaad86

Please sign in to comment.