anastasis-core: support poll transition
This commit is contained in:
parent
4a8e4b9026
commit
842cc32754
@ -80,6 +80,25 @@ export interface ChallengeFeedbackAuthIban {
|
|||||||
* be contained in the bank transfer.
|
* be contained in the bank transfer.
|
||||||
*/
|
*/
|
||||||
wire_transfer_subject: string;
|
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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
import { anastasisData } from "./anastasis-data.js";
|
import { anastasisData } from "./anastasis-data.js";
|
||||||
import {
|
import {
|
||||||
EscrowConfigurationResponse,
|
EscrowConfigurationResponse,
|
||||||
|
IbanExternalAuthResponse,
|
||||||
TruthUploadRequest,
|
TruthUploadRequest,
|
||||||
} from "./provider-types.js";
|
} from "./provider-types.js";
|
||||||
import {
|
import {
|
||||||
@ -809,6 +810,39 @@ async function tryRecoverSecret(
|
|||||||
return { ...state };
|
return { ...state };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Request a truth, optionally with a challenge solution
|
||||||
* provided by the user.
|
* provided by the user.
|
||||||
@ -839,6 +873,7 @@ async function requestTruth(
|
|||||||
case ChallengeType.Email:
|
case ChallengeType.Email:
|
||||||
case ChallengeType.Sms:
|
case ChallengeType.Sms:
|
||||||
case ChallengeType.Post:
|
case ChallengeType.Post:
|
||||||
|
case ChallengeType.Iban:
|
||||||
case ChallengeType.Totp: {
|
case ChallengeType.Totp: {
|
||||||
if ("answer" in solveRequest) {
|
if ("answer" in solveRequest) {
|
||||||
const s = solveRequest.answer.trim().replace(/^A-/, "");
|
const s = solveRequest.answer.trim().replace(/^A-/, "");
|
||||||
@ -857,7 +892,7 @@ async function requestTruth(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw Error("unsupported challenge type");
|
throw Error(`unsupported challenge type "${truth.escrow_type}""`);
|
||||||
}
|
}
|
||||||
url.searchParams.set("response", respHash);
|
url.searchParams.set("response", respHash);
|
||||||
}
|
}
|
||||||
@ -934,7 +969,24 @@ async function requestTruth(
|
|||||||
const body = await resp.json();
|
const body = await resp.json();
|
||||||
logger.info(`got body ${j2s(body)}`);
|
logger.info(`got body ${j2s(body)}`);
|
||||||
if (body.method === "iban") {
|
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 {
|
} else {
|
||||||
return {
|
return {
|
||||||
code: TalerErrorCode.ANASTASIS_TRUTH_CHALLENGE_FAILED,
|
code: TalerErrorCode.ANASTASIS_TRUTH_CHALLENGE_FAILED,
|
||||||
@ -1395,6 +1447,7 @@ const recoveryTransitions: Record<
|
|||||||
codecForActionArgsSelectChallenge(),
|
codecForActionArgsSelectChallenge(),
|
||||||
selectChallenge,
|
selectChallenge,
|
||||||
),
|
),
|
||||||
|
...transition("poll", codecForAny(), pollChallenges),
|
||||||
...transition("next", codecForAny(), nextFromChallengeSelecting),
|
...transition("next", codecForAny(), nextFromChallengeSelecting),
|
||||||
},
|
},
|
||||||
[RecoveryStates.ChallengeSolving]: {
|
[RecoveryStates.ChallengeSolving]: {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AmountString } from "@gnu-taler/taler-util";
|
import { Amounts, AmountString } from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
export interface EscrowConfigurationResponse {
|
export interface EscrowConfigurationResponse {
|
||||||
// Protocol identifier, clarifies that this is an Anastasis provider.
|
// Protocol identifier, clarifies that this is an Anastasis provider.
|
||||||
@ -72,3 +72,14 @@ export interface TruthUploadRequest {
|
|||||||
// store the truth?
|
// store the truth?
|
||||||
storage_duration_years: number;
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
codecForNumber,
|
codecForNumber,
|
||||||
codecForString,
|
codecForString,
|
||||||
codecForTimestamp,
|
codecForTimestamp,
|
||||||
|
Duration,
|
||||||
Timestamp,
|
Timestamp,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { ChallengeFeedback } from "./challenge-feedback-types.js";
|
import { ChallengeFeedback } from "./challenge-feedback-types.js";
|
||||||
|
Loading…
Reference in New Issue
Block a user