summaryrefslogtreecommitdiff
path: root/packages/anastasis-core/src/reducer-types.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/anastasis-core/src/reducer-types.ts')
-rw-r--r--packages/anastasis-core/src/reducer-types.ts373
1 files changed, 320 insertions, 53 deletions
diff --git a/packages/anastasis-core/src/reducer-types.ts b/packages/anastasis-core/src/reducer-types.ts
index 1a443bf9b..ad88f40ed 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -1,4 +1,30 @@
-import { Duration, Timestamp } from "@gnu-taler/taler-util";
+/*
+ This file is part of GNU Anastasis
+ (C) 2021-2022 Anastasis SARL
+
+ GNU Anastasis is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+import {
+ AmountString,
+ buildCodecForObject,
+ codecForAny,
+ codecForList,
+ codecForNumber,
+ codecForString,
+ codecForTimestamp,
+ TalerProtocolTimestamp,
+} from "@gnu-taler/taler-util";
+import { ChallengeFeedback } from "./challenge-feedback-types.js";
import { KeyShare } from "./crypto.js";
import { RecoveryDocument } from "./recovery-document-types.js";
@@ -15,7 +41,6 @@ export interface CountryInfo {
code: string;
name: string;
continent: string;
- currency: string;
}
export interface Policy {
@@ -23,7 +48,7 @@ export interface Policy {
authentication_method: number;
provider: string;
}[];
-}
+}
export interface PolicyProvider {
provider_url: string;
@@ -32,45 +57,91 @@ export interface PolicyProvider {
export interface SuccessDetails {
[provider_url: string]: {
policy_version: number;
- policy_expiration: Timestamp;
+ policy_expiration: TalerProtocolTimestamp;
};
}
export interface CoreSecret {
mime: string;
value: string;
+ /**
+ * Filename, only set if the secret comes from
+ * a file. Should be set unless the mime type is "text/plain";
+ */
+ filename?: string;
}
export interface ReducerStateBackup {
- recovery_state?: undefined;
+ reducer_type: "backup";
+
backup_state: BackupStates;
- code?: undefined;
- currencies?: string[];
+
continents?: ContinentInfo[];
- countries?: any;
+
+ countries?: CountryInfo[];
+
identity_attributes?: { [n: string]: string };
- authentication_providers?: { [url: string]: AuthenticationProviderStatus };
+
+ authentication_providers?: AuthenticationProviderStatusMap;
+
authentication_methods?: AuthMethod[];
+
required_attributes?: UserAttributeSpec[];
+
selected_continent?: string;
+
selected_country?: string;
+
secret_name?: string;
+
policies?: Policy[];
+
+ recovery_data?: {
+ /**
+ * Map from truth key (`${methodIndex}/${providerUrl}`) to
+ * the truth metadata.
+ */
+ truth_metadata: Record<string, TruthMetaData>;
+ recovery_document: RecoveryDocument;
+ };
+
/**
* Policy providers are providers that we checked to be functional
* and that are actually used in policies.
*/
policy_providers?: PolicyProvider[];
success_details?: SuccessDetails;
+
+ /**
+ * Currently requested payments.
+ *
+ * List of taler://pay URIs.
+ *
+ * FIXME: There should be more information in this,
+ * including the provider and amount.
+ */
payments?: string[];
+
+ /**
+ * FIXME: Why is this not a map from provider to payto?
+ */
policy_payment_requests?: {
+ /**
+ * FIXME: This is not a payto URI, right?!
+ */
payto: string;
provider: string;
}[];
core_secret?: CoreSecret;
- expiration?: Duration;
+ expiration?: TalerProtocolTimestamp;
+
+ upload_fees?: { fee: AmountString }[];
+
+ // FIXME: The payment secrets and pay URIs should
+ // probably be consolidated into a single field.
+ truth_upload_payment_secrets?: Record<string, string>;
}
export interface AuthMethod {
@@ -81,7 +152,6 @@ export interface AuthMethod {
}
export interface ChallengeInfo {
- cost: string;
instructions: string;
type: string;
uuid: string;
@@ -93,6 +163,10 @@ export interface UserAttributeSpec {
type: string;
uuid: string;
widget: string;
+ optional?: boolean;
+ "validation-regex": string | undefined;
+ "validation-logic": string | undefined;
+ autocomplete?: string;
}
export interface RecoveryInternalData {
@@ -111,27 +185,22 @@ export interface RecoveryInformation {
}[][];
}
-export interface ReducerStateRecovery {
- recovery_state: RecoveryStates;
+export interface AuthenticationProviderStatusMap {
+ [url: string]: AuthenticationProviderStatus;
+}
- /**
- * Unused in the recovery states.
- */
- backup_state?: undefined;
+export interface ReducerStateRecovery {
+ reducer_type: "recovery";
- /**
- * Unused in the recovery states.
- */
- code?: undefined;
+ recovery_state: RecoveryStates;
identity_attributes?: { [n: string]: string };
- continents?: any;
- countries?: any;
+ continents?: ContinentInfo[];
+ countries?: CountryInfo[];
selected_continent?: string;
selected_country?: string;
- currencies?: string[];
required_attributes?: UserAttributeSpec[];
@@ -148,6 +217,11 @@ export interface ReducerStateRecovery {
selected_challenge_uuid?: string;
+ /**
+ * Explicitly selected version by the user.
+ */
+ selected_version?: SelectedVersionInfo;
+
challenge_feedback?: { [uuid: string]: ChallengeFeedback };
/**
@@ -155,26 +229,45 @@ export interface ReducerStateRecovery {
*/
recovered_key_shares?: { [truth_uuid: string]: KeyShare };
- core_secret?: {
- mime: string;
- value: string;
- };
-
- authentication_providers?: { [url: string]: AuthenticationProviderStatus };
+ core_secret?: CoreSecret;
- recovery_error?: any;
+ authentication_providers?: AuthenticationProviderStatusMap;
}
-export interface ChallengeFeedback {
- state: string;
+/**
+ * Truth data as stored in the reducer.
+ */
+export interface TruthMetaData {
+ uuid: string;
+
+ key_share: string;
+
+ policy_index: number;
+
+ pol_method_index: number;
+
+ /**
+ * Nonce used for encrypting the truth.
+ */
+ nonce: string;
+
+ /**
+ * Key that the truth (i.e. secret question answer, email address, mobile number, ...)
+ * is encrypted with when stored at the provider.
+ */
+ truth_key: string;
+
+ /**
+ * Truth-specific salt.
+ */
+ master_salt: string;
}
export interface ReducerStateError {
- backup_state?: undefined;
- recovery_state?: undefined;
+ reducer_type: "error";
code: number;
hint?: string;
- message?: string;
+ detail?: string;
}
export enum BackupStates {
@@ -202,31 +295,44 @@ export enum RecoveryStates {
export interface MethodSpec {
type: string;
- usage_fee: string;
+ usage_fee: AmountString;
}
-// FIXME: This should be tagged!
-export type AuthenticationProviderStatusEmpty = {};
+export type AuthenticationProviderStatusNotContacted = {
+ status: "not-contacted";
+};
export interface AuthenticationProviderStatusOk {
+ status: "ok";
+
annual_fee: string;
business_name: string;
currency: string;
http_status: 200;
liability_limit: string;
- salt: string;
+ provider_salt: string;
storage_limit_in_megabytes: number;
truth_upload_fee: string;
methods: MethodSpec[];
+ // FIXME: add timestamp?
+}
+
+export interface AuthenticationProviderStatusDisabled {
+ status: "disabled";
}
export interface AuthenticationProviderStatusError {
- http_status: number;
- error_code: number;
+ status: "error";
+
+ http_status?: number;
+ code: number;
+ hint?: string;
+ // FIXME: add timestamp?
}
export type AuthenticationProviderStatus =
- | AuthenticationProviderStatusEmpty
+ | AuthenticationProviderStatusNotContacted
+ | AuthenticationProviderStatusDisabled
| AuthenticationProviderStatusError
| AuthenticationProviderStatusOk;
@@ -236,14 +342,27 @@ export interface ReducerStateBackupUserAttributesCollecting
selected_country: string;
currencies: string[];
required_attributes: UserAttributeSpec[];
- authentication_providers: { [url: string]: AuthenticationProviderStatus };
+ authentication_providers: AuthenticationProviderStatusMap;
}
-export interface ActionArgEnterUserAttributes {
+export interface ActionArgsEnterUserAttributes {
identity_attributes: Record<string, string>;
}
-export interface ActionArgAddAuthentication {
+export const codecForActionArgsEnterUserAttributes = () =>
+ buildCodecForObject<ActionArgsEnterUserAttributes>()
+ .property("identity_attributes", codecForAny())
+ .build("ActionArgsEnterUserAttributes");
+
+export interface ActionArgsAddProvider {
+ provider_url: string;
+}
+
+export interface ActionArgsDeleteProvider {
+ provider_url: string;
+}
+
+export interface ActionArgsAddAuthentication {
authentication_method: {
type: string;
instructions: string;
@@ -252,32 +371,180 @@ export interface ActionArgAddAuthentication {
};
}
-export interface ActionArgDeleteAuthentication {
+export interface ActionArgsDeleteAuthentication {
authentication_method: number;
}
-export interface ActionArgDeletePolicy {
+export interface ActionArgsDeletePolicy {
policy_index: number;
}
-export interface ActionArgEnterSecretName {
+export interface ActionArgsEnterSecretName {
name: string;
}
-export interface ActionArgEnterSecret {
+export interface ActionArgsEnterSecret {
secret: {
value: string;
mime?: string;
+ filename?: string;
};
- expiration: Duration;
+ expiration: TalerProtocolTimestamp;
+}
+
+export interface ActionArgsSelectContinent {
+ continent: string;
+}
+
+export const codecForActionArgSelectContinent = () =>
+ buildCodecForObject<ActionArgsSelectContinent>()
+ .property("continent", codecForString())
+ .build("ActionArgSelectContinent");
+
+export interface ActionArgsSelectCountry {
+ country_code: string;
}
export interface ActionArgsSelectChallenge {
uuid: string;
}
-export type ActionArgsSolveChallengeRequest = SolveChallengeAnswerRequest;
-
+export type ActionArgsSolveChallengeRequest =
+ | SolveChallengeAnswerRequest
+ | SolveChallengePinRequest
+ | SolveChallengeHashRequest;
+
+/**
+ * Answer to a challenge.
+ *
+ * For "question" challenges, this is a string with the answer.
+ *
+ * For "sms" / "email" / "post" this is a numeric code with optionally
+ * the "A-" prefix.
+ */
export interface SolveChallengeAnswerRequest {
answer: string;
}
+
+/**
+ * Answer to a challenge that requires a numeric response.
+ *
+ * XXX: Should be deprecated in favor of just "answer".
+ */
+export interface SolveChallengePinRequest {
+ pin: number;
+}
+
+/**
+ * Answer to a challenge by directly providing the hash.
+ *
+ * XXX: When / why is this even used?
+ */
+export interface SolveChallengeHashRequest {
+ /**
+ * Base32-crock encoded hash code.
+ */
+ hash: string;
+}
+
+export interface PolicyMember {
+ authentication_method: number;
+ provider: string;
+}
+
+export interface ActionArgsAddPolicy {
+ policy: PolicyMember[];
+}
+
+export interface ActionArgsUpdateExpiration {
+ expiration: TalerProtocolTimestamp;
+}
+
+export interface SelectedVersionInfo {
+ attribute_mask: number;
+ providers: {
+ url: string;
+ version: number;
+ }[];
+}
+
+export type ActionArgsChangeVersion = SelectedVersionInfo;
+
+export interface ActionArgsUpdatePolicy {
+ policy_index: number;
+ policy: PolicyMember[];
+}
+
+/**
+ * Cursor for a provider discovery process.
+ */
+export interface DiscoveryCursor {
+ position: {
+ provider_url: string;
+ mask: number;
+ max_version?: number;
+ }[];
+}
+
+export interface PolicyMetaInfo {
+ policy_hash: string;
+ provider_url: string;
+ version: number;
+ attribute_mask: number;
+ server_time: TalerProtocolTimestamp;
+ secret_name?: string;
+}
+
+/**
+ * Aggregated / de-duplicated policy meta info.
+ */
+export interface AggregatedPolicyMetaInfo {
+ secret_name?: string;
+ policy_hash: string;
+ attribute_mask: number;
+ providers: {
+ url: string;
+ version: number;
+ }[];
+}
+
+export interface DiscoveryResult {
+ /**
+ * Found policies.
+ */
+ policies: PolicyMetaInfo[];
+
+ /**
+ * Cursor that allows getting more results.
+ */
+ cursor?: DiscoveryCursor;
+}
+
+// FIXME: specify schema!
+export const codecForActionArgsChangeVersion = codecForAny;
+
+export const codecForPolicyMember = () =>
+ buildCodecForObject<PolicyMember>()
+ .property("authentication_method", codecForNumber())
+ .property("provider", codecForString())
+ .build("PolicyMember");
+
+export const codecForActionArgsAddPolicy = () =>
+ buildCodecForObject<ActionArgsAddPolicy>()
+ .property("policy", codecForList(codecForPolicyMember()))
+ .build("ActionArgsAddPolicy");
+
+export const codecForActionArgsUpdateExpiration = () =>
+ buildCodecForObject<ActionArgsUpdateExpiration>()
+ .property("expiration", codecForTimestamp)
+ .build("ActionArgsUpdateExpiration");
+
+export const codecForActionArgsSelectChallenge = () =>
+ buildCodecForObject<ActionArgsSelectChallenge>()
+ .property("uuid", codecForString())
+ .build("ActionArgsSelectChallenge");
+
+export const codecForActionArgSelectCountry = () =>
+ buildCodecForObject<ActionArgsSelectCountry>()
+ .property("country_code", codecForString())
+ .build("ActionArgSelectCountry");