From 5c6f38091068d67f88edda1d776e3c5f86c1a94e Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 4 Nov 2021 17:55:05 +0100 Subject: anastasis-core: support secret version selection --- packages/anastasis-core/src/index.ts | 30 +++++++++++++++++++++++++++- packages/anastasis-core/src/reducer-types.ts | 25 ++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) (limited to 'packages/anastasis-core/src') diff --git a/packages/anastasis-core/src/index.ts b/packages/anastasis-core/src/index.ts index c1a6d3ff0..2ed69b55a 100644 --- a/packages/anastasis-core/src/index.ts +++ b/packages/anastasis-core/src/index.ts @@ -64,6 +64,8 @@ import { ReducerStateRecovery, SuccessDetails, UserAttributeSpec, + codecForActionArgsChangeVersion, + ActionArgsChangeVersion, } from "./reducer-types.js"; import fetchPonyfill from "fetch-ponyfill"; import { @@ -578,6 +580,7 @@ async function downloadPolicy( const newProviderStatus: { [url: string]: AuthenticationProviderStatusOk } = {}; const userAttributes = state.identity_attributes!; + const restrictProvider = state.selected_provider_url; // FIXME: Shouldn't we also store the status of bad providers? for (const url of providerUrls) { const pi = await getProviderInfo(url); @@ -592,9 +595,17 @@ async function downloadPolicy( if (!pi) { continue; } + if (restrictProvider && url !== state.selected_provider_url) { + // User wants specific provider. + continue; + } const userId = await userIdentifierDerive(userAttributes, pi.salt); const acctKeypair = accountKeypairDerive(userId); - const resp = await fetch(new URL(`policy/${acctKeypair.pub}`, url).href); + const reqUrl = new URL(`policy/${acctKeypair.pub}`, url); + if (state.selected_version) { + reqUrl.searchParams.set("version", `${state.selected_version}`); + } + const resp = await fetch(reqUrl.href); if (resp.status !== 200) { continue; } @@ -842,6 +853,18 @@ async function recoveryEnterUserAttributes( return downloadPolicy(st); } +async function changeVersion( + state: ReducerStateRecovery, + args: ActionArgsChangeVersion, +): Promise { + const st: ReducerStateRecovery = { + ...state, + selected_version: args.version, + selected_provider_url: args.provider_url, + }; + return downloadPolicy(st); +} + async function selectChallenge( state: ReducerStateRecovery, ta: ActionArgsSelectChallenge, @@ -1209,6 +1232,11 @@ const recoveryTransitions: Record< [RecoveryStates.SecretSelecting]: { ...transitionRecoveryJump("back", RecoveryStates.UserAttributesCollecting), ...transitionRecoveryJump("next", RecoveryStates.ChallengeSelecting), + ...transition( + "change_version", + codecForActionArgsChangeVersion(), + changeVersion, + ), }, [RecoveryStates.ChallengeSelecting]: { ...transitionRecoveryJump("back", RecoveryStates.SecretSelecting), diff --git a/packages/anastasis-core/src/reducer-types.ts b/packages/anastasis-core/src/reducer-types.ts index 19f7d431a..08e61cefe 100644 --- a/packages/anastasis-core/src/reducer-types.ts +++ b/packages/anastasis-core/src/reducer-types.ts @@ -171,6 +171,18 @@ export interface ReducerStateRecovery { selected_challenge_uuid?: string; + /** + * Explicitly selected version by the user. + * FIXME: In the C reducer this is called "version". + */ + selected_version?: number; + + /** + * Explicitly selected provider URL by the user. + * FIXME: In the C reducer this is called "provider_url". + */ + selected_provider_url?: string; + challenge_feedback?: { [uuid: string]: ChallengeFeedback }; /** @@ -343,7 +355,7 @@ export interface SolveChallengePinRequest { * * XXX: When / why is this even used? */ - export interface SolveChallengeHashRequest { +export interface SolveChallengeHashRequest { /** * Base32-crock encoded hash code. */ @@ -363,6 +375,17 @@ export interface ActionArgsUpdateExpiration { expiration: Timestamp; } +export interface ActionArgsChangeVersion { + provider_url: string; + version: number; +} + +export const codecForActionArgsChangeVersion = () => + buildCodecForObject() + .property("provider_url", codecForString()) + .property("version", codecForNumber()) + .build("ActionArgsChangeVersion"); + export const codecForPolicyMember = () => buildCodecForObject() .property("authentication_method", codecForNumber()) -- cgit v1.2.3