move declarations into anastasis-core

This commit is contained in:
Florian Dold 2021-10-18 19:19:20 +02:00
parent b1034801d1
commit 3a69f27412
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
4 changed files with 104 additions and 204 deletions

View File

@ -22,6 +22,7 @@
}, },
"dependencies": { "dependencies": {
"@gnu-taler/taler-util": "workspace:^0.8.3", "@gnu-taler/taler-util": "workspace:^0.8.3",
"anastasis-core": "workspace:^0.0.1",
"preact": "^10.3.1", "preact": "^10.3.1",
"preact-render-to-string": "^5.1.4", "preact-render-to-string": "^5.1.4",
"preact-router": "^3.2.1" "preact-router": "^3.2.1"

View File

@ -1,144 +1,16 @@
import { TalerErrorCode } from "@gnu-taler/taler-util"; import { TalerErrorCode } from "@gnu-taler/taler-util";
import { BackupStates, getBackupStartState, getRecoveryStartState, RecoveryStates, reduceAction, ReducerState } from "anastasis-core";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
export type ReducerState = const reducerBaseUrl = "http://localhost:5000/";
| ReducerStateBackup let remoteReducer = true;
| ReducerStateRecovery
| ReducerStateError;
export interface ReducerStateBackup {
recovery_state: undefined;
backup_state: BackupStates;
code: undefined;
continents: any;
countries: any;
identity_attributes?: { [n: string]: string };
authentication_providers: any;
authentication_methods?: AuthMethod[];
required_attributes: any;
secret_name?: string;
policies?: {
methods: {
authentication_method: number;
provider: string;
}[];
}[];
success_details: {
[provider_url: string]: {
policy_version: number;
};
};
payments?: string[];
policy_payment_requests?: {
payto: string;
provider: string;
}[];
core_secret?: {
mime: string;
value: string;
};
}
export interface AuthMethod {
type: string;
instructions: string;
challenge: string;
}
export interface ChallengeInfo {
cost: string;
instructions: string;
type: string;
uuid: string;
}
export interface ReducerStateRecovery {
backup_state: undefined;
recovery_state: RecoveryStates;
code: undefined;
identity_attributes?: { [n: string]: string };
continents: any;
countries: any;
required_attributes: any;
recovery_information?: {
challenges: ChallengeInfo[];
policies: {
/**
* UUID of the associated challenge.
*/
uuid: string;
}[][];
};
recovery_document?: {
secret_name: string;
provider_url: string;
version: number;
};
selected_challenge_uuid?: string;
challenge_feedback?: { [uuid: string]: ChallengeFeedback };
core_secret?: {
mime: string;
value: string;
};
authentication_providers?: {
[url: string]: {
business_name: string;
};
};
recovery_error: any;
}
export interface ChallengeFeedback {
state: string;
}
export interface ReducerStateError {
backup_state: undefined;
recovery_state: undefined;
code: number;
}
interface AnastasisState { interface AnastasisState {
reducerState: ReducerState | undefined; reducerState: ReducerState | undefined;
currentError: any; currentError: any;
} }
export enum BackupStates { async function getBackupStartStateRemote(): Promise<ReducerState> {
ContinentSelecting = "CONTINENT_SELECTING",
CountrySelecting = "COUNTRY_SELECTING",
UserAttributesCollecting = "USER_ATTRIBUTES_COLLECTING",
AuthenticationsEditing = "AUTHENTICATIONS_EDITING",
PoliciesReviewing = "POLICIES_REVIEWING",
SecretEditing = "SECRET_EDITING",
TruthsPaying = "TRUTHS_PAYING",
PoliciesPaying = "POLICIES_PAYING",
BackupFinished = "BACKUP_FINISHED",
}
export enum RecoveryStates {
ContinentSelecting = "CONTINENT_SELECTING",
CountrySelecting = "COUNTRY_SELECTING",
UserAttributesCollecting = "USER_ATTRIBUTES_COLLECTING",
SecretSelecting = "SECRET_SELECTING",
ChallengeSelecting = "CHALLENGE_SELECTING",
ChallengePaying = "CHALLENGE_PAYING",
ChallengeSolving = "CHALLENGE_SOLVING",
RecoveryFinished = "RECOVERY_FINISHED",
}
const reducerBaseUrl = "http://localhost:5000/";
async function getBackupStartState(): Promise<ReducerState> {
let resp: Response; let resp: Response;
try { try {
@ -159,7 +31,7 @@ async function getBackupStartState(): Promise<ReducerState> {
} }
} }
async function getRecoveryStartState(): Promise<ReducerState> { async function getRecoveryStartStateRemote(): Promise<ReducerState> {
let resp: Response; let resp: Response;
try { try {
resp = await fetch(new URL("start-recovery", reducerBaseUrl).href); resp = await fetch(new URL("start-recovery", reducerBaseUrl).href);
@ -179,7 +51,7 @@ async function getRecoveryStartState(): Promise<ReducerState> {
} }
} }
async function reduceState( async function reduceStateRemote(
state: any, state: any,
action: string, action: string,
args: any, args: any,
@ -286,7 +158,12 @@ export function useAnastasisReducer(): AnastasisReducerApi {
async function doTransition(action: string, args: any) { async function doTransition(action: string, args: any) {
console.log("reducing with", action, args); console.log("reducing with", action, args);
const s = await reduceState(anastasisState.reducerState, action, args); let s: ReducerState;
if (remoteReducer) {
s = await reduceStateRemote(anastasisState.reducerState, action, args);
} else {
s = await reduceAction(anastasisState.reducerState!, action, args);
}
console.log("got new state from reducer", s); console.log("got new state from reducer", s);
if (s.code) { if (s.code) {
setAnastasisState({ ...anastasisState, currentError: s }); setAnastasisState({ ...anastasisState, currentError: s });
@ -303,7 +180,12 @@ export function useAnastasisReducer(): AnastasisReducerApi {
currentReducerState: anastasisState.reducerState, currentReducerState: anastasisState.reducerState,
currentError: anastasisState.currentError, currentError: anastasisState.currentError,
async startBackup() { async startBackup() {
const s = await getBackupStartState(); let s: ReducerState;
if (remoteReducer) {
s = await getBackupStartStateRemote();
} else {
s = await getBackupStartState();
}
if (s.code !== undefined) { if (s.code !== undefined) {
setAnastasisState({ setAnastasisState({
...anastasisState, ...anastasisState,
@ -318,7 +200,12 @@ export function useAnastasisReducer(): AnastasisReducerApi {
} }
}, },
async startRecover() { async startRecover() {
const s = await getRecoveryStartState(); let s: ReducerState;
if (remoteReducer) {
s = await getRecoveryStartStateRemote();
} else {
s = await getRecoveryStartState();
}
if (s.code !== undefined) { if (s.code !== undefined) {
setAnastasisState({ setAnastasisState({
...anastasisState, ...anastasisState,
@ -394,12 +281,14 @@ export function useAnastasisReducer(): AnastasisReducerApi {
class ReducerTxImpl implements ReducerTransactionHandle { class ReducerTxImpl implements ReducerTransactionHandle {
constructor(public transactionState: ReducerState) {} constructor(public transactionState: ReducerState) {}
async transition(action: string, args: any): Promise<ReducerState> { async transition(action: string, args: any): Promise<ReducerState> {
let s: ReducerState;
if (remoteReducer) {
s = await reduceStateRemote(this.transactionState, action, args);
} else {
s = await reduceAction(this.transactionState, action, args);
}
console.log("making transition in transaction", action); console.log("making transition in transaction", action);
this.transactionState = await reduceState( this.transactionState = s;
this.transactionState,
action,
args,
);
// Abort transaction as soon as we transition into an error state. // Abort transaction as soon as we transition into an error state.
if (this.transactionState.code !== undefined) { if (this.transactionState.code !== undefined) {
throw Error("transition resulted in error"); throw Error("transition resulted in error");

View File

@ -5,6 +5,15 @@ import {
encodeCrock, encodeCrock,
stringToBytes, stringToBytes,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import {
AuthMethod,
BackupStates,
ChallengeFeedback,
ChallengeInfo,
RecoveryStates,
ReducerStateBackup,
ReducerStateRecovery,
} from "anastasis-core";
import { import {
FunctionalComponent, FunctionalComponent,
ComponentChildren, ComponentChildren,
@ -14,13 +23,6 @@ import {
import { useState, useContext, useRef, useLayoutEffect } from "preact/hooks"; import { useState, useContext, useRef, useLayoutEffect } from "preact/hooks";
import { import {
AnastasisReducerApi, AnastasisReducerApi,
AuthMethod,
BackupStates,
ChallengeFeedback,
ChallengeInfo,
RecoveryStates,
ReducerStateBackup,
ReducerStateRecovery,
useAnastasisReducer, useAnastasisReducer,
} from "../../hooks/use-anastasis-reducer"; } from "../../hooks/use-anastasis-reducer";
import style from "./style.css"; import style from "./style.css";
@ -511,8 +513,8 @@ const AnastasisClientImpl: FunctionalComponent = () => {
</p> </p>
<p>The backup is stored by the following providers:</p> <p>The backup is stored by the following providers:</p>
<ul> <ul>
{Object.keys(backupState.success_details).map((x, i) => { {Object.keys(backupState.success_details!).map((x, i) => {
const sd = backupState.success_details[x]; const sd = backupState.success_details![x];
return ( return (
<li> <li>
{x} (Policy version {sd.policy_version}) {x} (Policy version {sd.policy_version})
@ -835,11 +837,11 @@ function AuthenticationEditor(props: AuthenticationEditorProps) {
undefined, undefined,
); );
const { reducer, backupState } = props; const { reducer, backupState } = props;
const providers = backupState.authentication_providers; const providers = backupState.authentication_providers!;
const authAvailableSet = new Set<string>(); const authAvailableSet = new Set<string>();
for (const provKey of Object.keys(providers)) { for (const provKey of Object.keys(providers)) {
const p = providers[provKey]; const p = providers[provKey];
if (p.methods) { if ("http_status" in p && (!("error_code" in p)) && p.methods) {
for (const meth of p.methods) { for (const meth of p.methods) {
authAvailableSet.add(meth.type); authAvailableSet.add(meth.type);
} }

View File

@ -1,26 +1,26 @@
{ {
"compilerOptions": { "compilerOptions": {
/* Basic Options */ /* Basic Options */
"target": "ES5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ "target": "ES5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */,
"module": "ESNext", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "ESNext" /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation: */ // "lib": [], /* Specify library files to be included in the compilation: */
"allowJs": true, /* Allow javascript files to be compiled. */ "allowJs": true /* Allow javascript files to be compiled. */,
// "checkJs": true, /* Report errors in .js files. */ // "checkJs": true, /* Report errors in .js files. */
"jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
"jsxFactory": "h", /* Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h. */ "jsxFactory": "h" /* Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h. */,
// "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */ // "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */ // "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "removeComments": true, /* Do not emit comments to output. */ // "removeComments": true, /* Do not emit comments to output. */
"noEmit": true, /* Do not emit outputs. */ "noEmit": true /* Do not emit outputs. */,
// "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */ /* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */ "strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */ // "strictNullChecks": true, /* Enable strict null checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
@ -33,8 +33,8 @@
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */ /* Module Resolution Options */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
"esModuleInterop": true, /* */ "esModuleInterop": true /* */,
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
@ -56,5 +56,13 @@
/* Advanced Options */ /* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */ "skipLibCheck": true /* Skip type checking of declaration files. */
}, },
"references": [
{
"path": "../taler-util/"
},
{
"path": "../anastasis-core/"
}
],
"include": ["src/**/*", "tests/**/*"] "include": ["src/**/*", "tests/**/*"]
} }