summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-11-05 16:07:57 +0100
committerFlorian Dold <florian@dold.me>2021-11-05 16:08:04 +0100
commit842cc327541ebcfc761208f42bf5f74e22c6283c (patch)
tree62c47078a8f2d696d078981a2d4d387d5de83fff
parent4a8e4b90267505e2acc143c9a933de1f22829472 (diff)
downloadwallet-core-842cc327541ebcfc761208f42bf5f74e22c6283c.tar.gz
wallet-core-842cc327541ebcfc761208f42bf5f74e22c6283c.tar.bz2
wallet-core-842cc327541ebcfc761208f42bf5f74e22c6283c.zip
anastasis-core: support poll transition
-rw-r--r--packages/anastasis-core/src/challenge-feedback-types.ts19
-rw-r--r--packages/anastasis-core/src/index.ts57
-rw-r--r--packages/anastasis-core/src/provider-types.ts13
-rw-r--r--packages/anastasis-core/src/reducer-types.ts1
4 files changed, 87 insertions, 3 deletions
diff --git a/packages/anastasis-core/src/challenge-feedback-types.ts b/packages/anastasis-core/src/challenge-feedback-types.ts
index d6a2e3e80..0770d9296 100644
--- a/packages/anastasis-core/src/challenge-feedback-types.ts
+++ b/packages/anastasis-core/src/challenge-feedback-types.ts
@@ -80,6 +80,25 @@ export interface ChallengeFeedbackAuthIban {
* be contained in the bank transfer.
*/
wire_transfer_subject: string;
+
+ /**
+ * FIXME: This field is only present for compatibility with
+ * the C reducer test suite.
+ */
+ method: "iban";
+
+ answer_code: number;
+
+ /**
+ * FIXME: This field is only present for compatibility with
+ * the C reducer test suite.
+ */
+ details: {
+ challenge_amount: AmountString;
+ credit_iban: string;
+ business_name: string;
+ wire_transfer_subject: string;
+ };
}
/**
diff --git a/packages/anastasis-core/src/index.ts b/packages/anastasis-core/src/index.ts
index d3e938f0f..362ac3317 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -25,6 +25,7 @@ import {
import { anastasisData } from "./anastasis-data.js";
import {
EscrowConfigurationResponse,
+ IbanExternalAuthResponse,
TruthUploadRequest,
} from "./provider-types.js";
import {
@@ -810,6 +811,39 @@ async function tryRecoverSecret(
}
/**
+ * Re-check the status of challenges that are solved asynchronously.
+ */
+async function pollChallenges(
+ state: ReducerStateRecovery,
+ args: void,
+): Promise<ReducerStateRecovery | ReducerStateError> {
+ for (const truthUuid in state.challenge_feedback) {
+ if (state.recovery_state === RecoveryStates.RecoveryFinished) {
+ break;
+ }
+ const feedback = state.challenge_feedback[truthUuid];
+ const truth = state.verbatim_recovery_document!.escrow_methods.find(
+ (x) => x.uuid === truthUuid,
+ );
+ if (!truth) {
+ logger.warn(
+ "truth for challenge feedback entry not found in recovery document",
+ );
+ continue;
+ }
+ if (feedback.state === ChallengeFeedbackStatus.AuthIban) {
+ const s2 = await requestTruth(state, truth, {
+ pin: feedback.answer_code,
+ });
+ if (s2.recovery_state) {
+ state = s2;
+ }
+ }
+ }
+ return state;
+}
+
+/**
* Request a truth, optionally with a challenge solution
* provided by the user.
*/
@@ -839,6 +873,7 @@ async function requestTruth(
case ChallengeType.Email:
case ChallengeType.Sms:
case ChallengeType.Post:
+ case ChallengeType.Iban:
case ChallengeType.Totp: {
if ("answer" in solveRequest) {
const s = solveRequest.answer.trim().replace(/^A-/, "");
@@ -857,7 +892,7 @@ async function requestTruth(
break;
}
default:
- throw Error("unsupported challenge type");
+ throw Error(`unsupported challenge type "${truth.escrow_type}""`);
}
url.searchParams.set("response", respHash);
}
@@ -934,7 +969,24 @@ async function requestTruth(
const body = await resp.json();
logger.info(`got body ${j2s(body)}`);
if (body.method === "iban") {
- // FIXME:
+ const b = body as IbanExternalAuthResponse;
+ return {
+ ...state,
+ recovery_state: RecoveryStates.ChallengeSolving,
+ challenge_feedback: {
+ ...state.challenge_feedback,
+ [truth.uuid]: {
+ state: ChallengeFeedbackStatus.AuthIban,
+ answer_code: b.answer_code,
+ business_name: b.details.business_name,
+ challenge_amount: b.details.challenge_amount,
+ credit_iban: b.details.credit_iban,
+ wire_transfer_subject: b.details.wire_transfer_subject,
+ details: b.details,
+ method: "iban",
+ },
+ },
+ };
} else {
return {
code: TalerErrorCode.ANASTASIS_TRUTH_CHALLENGE_FAILED,
@@ -1395,6 +1447,7 @@ const recoveryTransitions: Record<
codecForActionArgsSelectChallenge(),
selectChallenge,
),
+ ...transition("poll", codecForAny(), pollChallenges),
...transition("next", codecForAny(), nextFromChallengeSelecting),
},
[RecoveryStates.ChallengeSolving]: {
diff --git a/packages/anastasis-core/src/provider-types.ts b/packages/anastasis-core/src/provider-types.ts
index b477c09b9..f4d998e0a 100644
--- a/packages/anastasis-core/src/provider-types.ts
+++ b/packages/anastasis-core/src/provider-types.ts
@@ -1,4 +1,4 @@
-import { AmountString } from "@gnu-taler/taler-util";
+import { Amounts, AmountString } from "@gnu-taler/taler-util";
export interface EscrowConfigurationResponse {
// Protocol identifier, clarifies that this is an Anastasis provider.
@@ -72,3 +72,14 @@ export interface TruthUploadRequest {
// store the truth?
storage_duration_years: number;
}
+
+export interface IbanExternalAuthResponse {
+ method: "iban";
+ answer_code: number;
+ details: {
+ challenge_amount: AmountString;
+ credit_iban: string;
+ business_name: string;
+ wire_transfer_subject: string;
+ };
+}
diff --git a/packages/anastasis-core/src/reducer-types.ts b/packages/anastasis-core/src/reducer-types.ts
index 1a560b885..0f64be4eb 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -6,6 +6,7 @@ import {
codecForNumber,
codecForString,
codecForTimestamp,
+ Duration,
Timestamp,
} from "@gnu-taler/taler-util";
import { ChallengeFeedback } from "./challenge-feedback-types.js";