anastasis-core: support secret version selection

This commit is contained in:
Florian Dold 2021-11-04 17:55:05 +01:00
parent 4ebeb00243
commit 5c6f380910
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
2 changed files with 53 additions and 2 deletions

View File

@ -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<ReducerStateRecovery | ReducerStateError> {
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),

View File

@ -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<ActionArgsChangeVersion>()
.property("provider_url", codecForString())
.property("version", codecForNumber())
.build("ActionArgsChangeVersion");
export const codecForPolicyMember = () =>
buildCodecForObject<PolicyMember>()
.property("authentication_method", codecForNumber())