aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/anastasis-core/src/index.ts30
-rw-r--r--packages/anastasis-core/src/reducer-types.ts25
2 files changed, 53 insertions, 2 deletions
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<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),
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<ActionArgsChangeVersion>()
+ .property("provider_url", codecForString())
+ .property("version", codecForNumber())
+ .build("ActionArgsChangeVersion");
+
export const codecForPolicyMember = () =>
buildCodecForObject<PolicyMember>()
.property("authentication_method", codecForNumber())