π Authentication and Login Page (#109)
* Login page initial UI * Auth working with mock call * Store token in session and state via hook * Ability to sign out * Fix defaultMessage warnings * New unmodified nswag file * add nswag * Update nswag.json to this project's requirements * Generate clients from path segments to avoid conflicts * Change url param to be base only so that nswag doesn't have to remove stuff from the url * nswag works for login * Handle 404 in login * Display invalid login attempts * Stop showing logout button if unauthenticated * Initialize the theme * Fix error in library * Fix warning * Add in the logo to the app bar * Fix linting issues * Generate DTO's as interfaces rather than classes * Keep url inside api-client per PR * Remove commented out code, serialize token as token not string * Remove unused file per PR * Fix from PR feedback
This commit is contained in:
Π ΠΎΠ΄ΠΈΡΠ΅Π»Ρ
48f64d0402
ΠΠΎΠΌΠΌΠΈΡ
79c599a824
|
@ -1,5 +1,5 @@
|
|||
SKIP_PREFLIGHT_CHECK=true
|
||||
REACT_APP_MEDIATOR_SERVICE=http://localhost:8000/api/v1/
|
||||
REACT_APP_GUARDIAN_SERVICE=http://localhost:8001/api/v1/
|
||||
REACT_APP_MEDIATOR_SERVICE=http://localhost:8000
|
||||
REACT_APP_GUARDIAN_SERVICE=http://localhost:8001
|
||||
REACT_APP_MOCK_ENABLED=false
|
||||
PORT=3001
|
|
@ -1,3 +1,3 @@
|
|||
REACT_APP_MEDIATOR_SERVICE=http://localhost:8000/api/v1/
|
||||
REACT_APP_GUARDIAN_SERVICE=http://localhost:8001/api/v1/
|
||||
REACT_APP_MEDIATOR_SERVICE=http://localhost:8000
|
||||
REACT_APP_GUARDIAN_SERVICE=http://localhost:8001
|
||||
REACT_APP_MOCK_ENABLED=false
|
||||
|
|
|
@ -1,15 +1,37 @@
|
|||
import React from 'react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { DefaultLayout } from './layouts';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { AuthenticatedLayout } from './layouts';
|
||||
import { LoginPage } from './pages';
|
||||
import useToken from './useToken';
|
||||
|
||||
import MainRoutes from './routes/MainRoutes';
|
||||
import AuthenticatedRoutes from './routes/AuthenticatedRoutes';
|
||||
import UnauthenticatedLayout from './layouts/UnauthenticatedLayout';
|
||||
import theme from './theme';
|
||||
|
||||
const App: React.FunctionComponent = () => (
|
||||
<Router>
|
||||
<DefaultLayout>
|
||||
<MainRoutes />
|
||||
</DefaultLayout>
|
||||
</Router>
|
||||
);
|
||||
const App: React.FunctionComponent = () => {
|
||||
const { setToken, token } = useToken();
|
||||
|
||||
const getContent = () => {
|
||||
const unauthenticated = !token;
|
||||
if (unauthenticated) {
|
||||
return (
|
||||
<UnauthenticatedLayout>
|
||||
<LoginPage setToken={setToken} />
|
||||
</UnauthenticatedLayout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<AuthenticatedLayout>
|
||||
<AuthenticatedRoutes />
|
||||
</AuthenticatedLayout>
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
||||
return <ThemeProvider theme={theme()}>{getContent()}</ThemeProvider>;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { Box, Button, AppBar as MaterialAppBar, Toolbar, makeStyles } from '@material-ui/core';
|
||||
import React, { SVGProps, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { MessageId } from '../../lang';
|
||||
import useToken from '../../useToken';
|
||||
import { ReactComponent as ElectionGuardLogo } from '../../images/electionguard-logo.svg';
|
||||
|
||||
export interface AppBarProps {
|
||||
title?: string;
|
||||
Logo?: React.ComponentType<SVGProps<SVGSVGElement>>;
|
||||
loggedIn?: boolean;
|
||||
}
|
||||
|
||||
|
@ -37,24 +38,27 @@ const useStyles = makeStyles((theme) => ({
|
|||
/**
|
||||
* A persistent top App Bar with side drawer and optional additional content.
|
||||
*/
|
||||
export const AppBar: React.FunctionComponent<AppBarProps> = ({ title, Logo, loggedIn = false }) => {
|
||||
const [signedIn, setSignIn] = useState(loggedIn);
|
||||
export const AppBar: React.FunctionComponent<AppBarProps> = ({ title, loggedIn }) => {
|
||||
const { setToken } = useToken();
|
||||
const classes = useStyles();
|
||||
|
||||
const logoutButton = (
|
||||
<Button href="/" color="inherit" onClick={() => setToken(undefined)}>
|
||||
<FormattedMessage
|
||||
id={MessageId.AuthLogout}
|
||||
description="Sign out of application"
|
||||
defaultMessage="Sign Out"
|
||||
/>
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<MaterialAppBar position="static" title={title}>
|
||||
<Toolbar className={classes.toolbar}>
|
||||
<Box className={classes.logoContainer}>
|
||||
{Logo && <Logo className={classes.logo} />}
|
||||
<ElectionGuardLogo className={classes.logo} />
|
||||
</Box>
|
||||
{signedIn && (
|
||||
<Button color="inherit" onClick={() => setSignIn(!signedIn)}>
|
||||
<FormattedMessage
|
||||
id={MessageId.AuthLogout}
|
||||
description="Sign out of application"
|
||||
defaultMessage="Sign Out"
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
{loggedIn ? logoutButton : null}
|
||||
</Toolbar>
|
||||
</MaterialAppBar>
|
||||
);
|
||||
|
|
|
@ -53,7 +53,6 @@ export const MenuOption: React.FC<MenuOptionProps> = ({ title, Icon, disabled, o
|
|||
className={classes.title}
|
||||
color="textSecondary"
|
||||
id={title.id}
|
||||
defaultMessage={title.defaultMessage}
|
||||
/>
|
||||
</CardContent>
|
||||
</ButtonBase>
|
||||
|
|
|
@ -40,8 +40,6 @@ export const MenuOptions: React.FC<MenuOptionsProps> = ({ prompt, children }) =>
|
|||
component="p"
|
||||
className={classes.prompt}
|
||||
id={prompt.id}
|
||||
description="Prompt for a user on menu"
|
||||
defaultMessage={prompt.defaultMessage}
|
||||
/>
|
||||
<Container maxWidth="xs">
|
||||
<Grid container className={classes.options}>
|
||||
|
|
|
@ -49,7 +49,6 @@ export const WelcomeHeader: React.FC<WelcomeHeaderProps> = ({ Logo }) => {
|
|||
className={classes.welcomeText}
|
||||
id={MessageId.AppGreeting}
|
||||
description="Greeting to welcome the user to the app"
|
||||
defaultMessage="Welcome to"
|
||||
/>
|
||||
</Grid>
|
||||
{Logo && (
|
||||
|
|
|
@ -17,7 +17,10 @@ export interface DefaultLayoutProps {
|
|||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children, isLoading = false }) => {
|
||||
export const AuthenticatedLayout: React.FC<DefaultLayoutProps> = ({
|
||||
children,
|
||||
isLoading = false,
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<Box className={classes.root} height="100vh" display="flex" flexDirection="column">
|
||||
|
@ -41,4 +44,4 @@ export const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children, isLoadin
|
|||
);
|
||||
};
|
||||
|
||||
export default DefaultLayout;
|
||||
export default AuthenticatedLayout;
|
|
@ -0,0 +1,30 @@
|
|||
import { Box, makeStyles } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
|
||||
import AppBar from '../components/AppBar';
|
||||
import Footer from '../components/Footer';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
root: {
|
||||
minHeight: '100vh',
|
||||
},
|
||||
}));
|
||||
|
||||
export interface DefaultLayoutProps {
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export const UnauthenticatedLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<Box className={classes.root} height="100vh" display="flex" flexDirection="column">
|
||||
<AppBar title="Admin App" />
|
||||
<Box display="flex" flexDirection="column" flexGrow={1}>
|
||||
<>{children}</>
|
||||
</Box>
|
||||
<Footer />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default UnauthenticatedLayout;
|
|
@ -1,3 +1,3 @@
|
|||
export * from './DefaultLayout';
|
||||
export * from './AuthenticatedLayout';
|
||||
export * from './ListPageLayout';
|
||||
export * from './LoginLayout';
|
||||
|
|
|
@ -1,16 +1,120 @@
|
|||
import { Box } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import {
|
||||
Body_login_for_access_token_api_v1_auth_login_post,
|
||||
ErrorMessage,
|
||||
ClientFactory,
|
||||
Token,
|
||||
} from '@electionguard/api-client';
|
||||
import { Button, Container, InputAdornment, makeStyles, TextField } from '@material-ui/core';
|
||||
import { AccountCircle, Lock } from '@material-ui/icons';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export const LoginPage: React.FC = () => (
|
||||
<Box
|
||||
height="100%"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
Login
|
||||
</Box>
|
||||
);
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
errorMessage: {
|
||||
color: 'red',
|
||||
marginBottom: theme.spacing(3),
|
||||
},
|
||||
text: {
|
||||
marginBottom: theme.spacing(3),
|
||||
width: '100%',
|
||||
},
|
||||
submit: {
|
||||
marginTop: theme.spacing(3),
|
||||
width: '100%',
|
||||
},
|
||||
}));
|
||||
|
||||
export interface LoginPageProps {
|
||||
setToken: (token: Token) => void;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const isErrorMessage = (object: any): object is ErrorMessage => 'detail' in object;
|
||||
|
||||
export const LoginPage: React.FC<LoginPageProps> = ({ setToken }) => {
|
||||
const classes = useStyles();
|
||||
const [username, setUserName] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [result, setResult] = useState<string>();
|
||||
|
||||
const handleSubmit: React.FormEventHandler<HTMLFormElement> = async (e) => {
|
||||
e.preventDefault();
|
||||
const authClient = ClientFactory.GetAuthClient();
|
||||
const loginParams = {
|
||||
username,
|
||||
password,
|
||||
grant_type: 'password',
|
||||
scope: 'admin',
|
||||
client_id: 'electionguard-default-client-id',
|
||||
client_secret: 'electionguard-default-client-secret',
|
||||
} as Body_login_for_access_token_api_v1_auth_login_post;
|
||||
|
||||
await authClient
|
||||
.login(loginParams)
|
||||
.then((token: Token) => {
|
||||
setToken(token);
|
||||
})
|
||||
.catch((ex: unknown) => {
|
||||
if (typeof ex === 'string') {
|
||||
setResult(ex);
|
||||
} else if (isErrorMessage(ex)) {
|
||||
setResult(ex.detail);
|
||||
} else {
|
||||
setResult('An error occurred');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Container maxWidth="xs" className={classes.root}>
|
||||
<div className={classes.errorMessage}>{result}</div>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<TextField
|
||||
id="username"
|
||||
label="Username"
|
||||
variant="standard"
|
||||
className={classes.text}
|
||||
onChange={(e) => setUserName(e.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<AccountCircle />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
id="password"
|
||||
label="Password"
|
||||
variant="standard"
|
||||
className={classes.text}
|
||||
type="password"
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<Lock />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={classes.submit}
|
||||
>
|
||||
Log In
|
||||
</Button>
|
||||
</form>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginPage;
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
|||
import InternationalText from '../components/InternationalText';
|
||||
import { MenuOptions, MenuOptionType, TypedMenuOption } from '../components/MenuOption';
|
||||
import WelcomeHeader from '../components/WelcomeHeader';
|
||||
import { loremIpsum, Message, MessageId } from '../lang';
|
||||
import { Message, MessageId } from '../lang';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -23,7 +23,7 @@ export const MenuPage: React.FC = () => {
|
|||
<Grid container className={classes.root}>
|
||||
<Container maxWidth="md" className={classes.content}>
|
||||
<WelcomeHeader />
|
||||
<InternationalText id={MessageId.AppAbout} defaultMessage={loremIpsum} />
|
||||
<InternationalText id={MessageId.AppAbout} />
|
||||
</Container>
|
||||
<MenuOptions prompt={new Message(MessageId.MenuPrompt)}>
|
||||
<TypedMenuOption
|
||||
|
|
|
@ -21,7 +21,7 @@ import routeIds from './RouteIds';
|
|||
* The routes to display when the user is fully authenticated
|
||||
* and able to view the main UI
|
||||
*/
|
||||
const MainRoutes: React.FC = () => (
|
||||
const AuthenticatedRoutes: React.FC = () => (
|
||||
<Routes>
|
||||
<Route path={routeIds.home} element={<Navigate to="/menu" />} />
|
||||
<Route path="/menu" element={<MenuPage />} />
|
||||
|
@ -43,4 +43,4 @@ const MainRoutes: React.FC = () => (
|
|||
</Routes>
|
||||
);
|
||||
|
||||
export default MainRoutes;
|
||||
export default AuthenticatedRoutes;
|
|
@ -19,7 +19,7 @@ import {
|
|||
yellow,
|
||||
} from '@material-ui/core/colors';
|
||||
import { Localization } from '@material-ui/core/locale';
|
||||
import { Theme, ThemeOptions, createMuiTheme } from '@material-ui/core/styles';
|
||||
import { Theme, ThemeOptions, createTheme } from '@material-ui/core/styles';
|
||||
|
||||
const midnightBlue = '#002a84';
|
||||
|
||||
|
@ -55,7 +55,7 @@ export const theme = (localization?: Localization): Theme => {
|
|||
},
|
||||
},
|
||||
};
|
||||
return localization ? createMuiTheme(options, localization) : createMuiTheme(options);
|
||||
return localization ? createTheme(options, localization) : createTheme(options);
|
||||
};
|
||||
|
||||
export default theme;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { Token } from '@electionguard/api-client';
|
||||
import { useState } from 'react';
|
||||
|
||||
/**
|
||||
* A custom hook for an authentication token. Currently uses session storage, thus token is lost when user
|
||||
* closes tab. To sacrifice security for convenience replace 'sessionStorage' with 'localStorage' and user
|
||||
* will not need to log back in after closing tab.
|
||||
*/
|
||||
export default function useToken(): {
|
||||
setToken: (token?: Token) => void;
|
||||
token: Token;
|
||||
} {
|
||||
const getToken = () => {
|
||||
const tokenString = sessionStorage.getItem('token');
|
||||
const userToken = tokenString ? JSON.parse(tokenString) : undefined;
|
||||
return userToken;
|
||||
};
|
||||
const [token, setToken] = useState(getToken());
|
||||
|
||||
const saveToken = (userToken?: Token) => {
|
||||
const tokenString = JSON.stringify(userToken);
|
||||
if (userToken) {
|
||||
sessionStorage.setItem('token', tokenString);
|
||||
} else {
|
||||
sessionStorage.removeItem('token');
|
||||
}
|
||||
setToken(userToken);
|
||||
};
|
||||
|
||||
return {
|
||||
setToken: saveToken,
|
||||
token,
|
||||
};
|
||||
}
|
|
@ -37,8 +37,8 @@ make docker-dev
|
|||
In the local application environment variables will be used to determine the address for the Guardian and Mediator Services. There is also a variable that the api-client will use to determine if mock data should be used instead. The environment variables are shown below:
|
||||
|
||||
```
|
||||
REACT_APP_MEDIATOR_SERVICE=http://localhost:8000/api/v1/
|
||||
REACT_APP_GUARDIAN_SERVICE=http://localhost:8001/api/v1/
|
||||
REACT_APP_MEDIATOR_SERVICE=http://localhost:8000
|
||||
REACT_APP_GUARDIAN_SERVICE=http://localhost:8001
|
||||
REACT_APP_MOCK_ENABLED=false
|
||||
```
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"babel-loader": "8.1.0",
|
||||
"microbundle": "^0.13.3",
|
||||
"move-file-cli": "^3.0.0",
|
||||
"nswag": "^13.15.5",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-scripts": "^4.0.3",
|
||||
|
@ -17358,6 +17359,18 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/nswag": {
|
||||
"version": "13.15.5",
|
||||
"resolved": "https://registry.npmjs.org/nswag/-/nswag-13.15.5.tgz",
|
||||
"integrity": "sha512-1FHcyXME7YH9fYMkpr0DbU7tFz2mB+t6/nzFr8LkRonypwBBNaL++NVO1Gsi+r7hpV0b0QQqlP58JWHfRrbExQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"nswag": "bin/nswag.js"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=3.10.8"
|
||||
}
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
|
||||
|
@ -42737,6 +42750,12 @@
|
|||
"path-key": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"nswag": {
|
||||
"version": "13.15.5",
|
||||
"resolved": "https://registry.npmjs.org/nswag/-/nswag-13.15.5.tgz",
|
||||
"integrity": "sha512-1FHcyXME7YH9fYMkpr0DbU7tFz2mB+t6/nzFr8LkRonypwBBNaL++NVO1Gsi+r7hpV0b0QQqlP58JWHfRrbExQ==",
|
||||
"dev": true
|
||||
},
|
||||
"nth-check": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
"prettier": "prettier --check '{src,public}/**/*.{js,jsx,ts,tsx,css,html,svg}'",
|
||||
"npm-publish": "npm publish --access public",
|
||||
"npm-version-patch": "npm version patch",
|
||||
"npm-version-minor": "npm version minor"
|
||||
"npm-version-minor": "npm version minor",
|
||||
"nswag-generate": "nswag run src/nswag/nswag.json"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "17.0.2",
|
||||
|
@ -42,6 +43,7 @@
|
|||
"babel-loader": "8.1.0",
|
||||
"microbundle": "^0.13.3",
|
||||
"move-file-cli": "^3.0.0",
|
||||
"nswag": "^13.15.5",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-scripts": "^4.0.3",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './api/index';
|
||||
export * from './data';
|
||||
export * from './models';
|
||||
export * from './nswag';
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { AuthClient } from './clients';
|
||||
|
||||
export class ClientFactory {
|
||||
private static GetUrl(): string {
|
||||
return process.env.REACT_APP_MEDIATOR_SERVICE || '';
|
||||
}
|
||||
|
||||
public static GetAuthClient(): AuthClient {
|
||||
const url = this.GetUrl();
|
||||
return new AuthClient(url);
|
||||
}
|
||||
}
|
Π Π°Π·Π½ΠΈΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ Π½Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΠΈΠ·-Π·Π° ΡΠ²ΠΎΠ΅Π³ΠΎ Π±ΠΎΠ»ΡΡΠΎΠ³ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ°
ΠΠ°Π³ΡΡΠ·ΠΈΡΡ ΡΠ°Π·Π½ΠΈΡΡ
|
@ -0,0 +1,9 @@
|
|||
export {
|
||||
AuthClient,
|
||||
Body_login_for_access_token_api_v1_auth_login_post,
|
||||
ApiException,
|
||||
ErrorMessage,
|
||||
Token,
|
||||
} from './clients';
|
||||
|
||||
export { ClientFactory } from './ClientFactory';
|
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
"runtime": "NetCore21",
|
||||
"defaultVariables": null,
|
||||
"documentGenerator": {
|
||||
"fromDocument": {
|
||||
"url": "http://localhost:8000/api/v1/openapi.json",
|
||||
"output": null,
|
||||
"newLineBehavior": "Auto"
|
||||
}
|
||||
},
|
||||
"codeGenerators": {
|
||||
"openApiToTypeScriptClient": {
|
||||
"className": "{controller}Client",
|
||||
"moduleName": "",
|
||||
"namespace": "",
|
||||
"typeScriptVersion": 2.7,
|
||||
"template": "Fetch",
|
||||
"promiseType": "Promise",
|
||||
"httpClass": "HttpClient",
|
||||
"withCredentials": false,
|
||||
"useSingletonProvider": false,
|
||||
"injectionTokenType": "OpaqueToken",
|
||||
"rxJsVersion": 6.0,
|
||||
"dateTimeType": "Date",
|
||||
"nullValue": "Undefined",
|
||||
"generateClientClasses": true,
|
||||
"generateClientInterfaces": false,
|
||||
"generateOptionalParameters": false,
|
||||
"exportTypes": true,
|
||||
"wrapDtoExceptions": false,
|
||||
"exceptionClass": "ApiException",
|
||||
"clientBaseClass": null,
|
||||
"wrapResponses": false,
|
||||
"wrapResponseMethods": [],
|
||||
"generateResponseClasses": true,
|
||||
"responseClass": "SwaggerResponse",
|
||||
"protectedMethods": [],
|
||||
"configurationClass": null,
|
||||
"useTransformOptionsMethod": false,
|
||||
"useTransformResultMethod": false,
|
||||
"generateDtoTypes": true,
|
||||
"operationGenerationMode": "MultipleClientsFromPathSegments",
|
||||
"markOptionalProperties": true,
|
||||
"generateCloneMethod": false,
|
||||
"typeStyle": "Interface",
|
||||
"enumStyle": "Enum",
|
||||
"useLeafType": false,
|
||||
"classTypes": [],
|
||||
"extendedClasses": [],
|
||||
"extensionCode": null,
|
||||
"generateDefaultValues": true,
|
||||
"excludedTypeNames": [],
|
||||
"excludedParameterNames": [],
|
||||
"handleReferences": false,
|
||||
"generateConstructorInterface": true,
|
||||
"convertConstructorInterfaceData": false,
|
||||
"importRequiredTypes": true,
|
||||
"useGetBaseUrlMethod": false,
|
||||
"baseUrlTokenName": "API_BASE_URL",
|
||||
"queryNullValue": "",
|
||||
"useAbortSignal": false,
|
||||
"inlineNamedDictionaries": false,
|
||||
"inlineNamedAny": false,
|
||||
"includeHttpContext": false,
|
||||
"templateDirectory": null,
|
||||
"typeNameGeneratorType": null,
|
||||
"propertyNameGeneratorType": null,
|
||||
"enumNameGeneratorType": null,
|
||||
"serviceHost": null,
|
||||
"serviceSchemes": null,
|
||||
"output": "clients.ts",
|
||||
"newLineBehavior": "LF"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ export const decryptSharesBallot = async (
|
|||
guardian: { id, name: '' },
|
||||
context,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}ballot/decrypt-shares`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/ballot/decrypt-shares`;
|
||||
const response = await post<{ resp: DecryptBallotSharesResponse }>(path, data);
|
||||
return response.parsedBody?.resp.shares;
|
||||
};
|
||||
|
@ -41,7 +41,7 @@ export const getBallot = async (
|
|||
election_id: string,
|
||||
ballot_id: string
|
||||
): Promise<CiphertextBallot[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot?election_id=${election_id}&ballot_id=${ballot_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot?election_id=${election_id}&ballot_id=${ballot_id}`;
|
||||
const response = await get<{ resp: BallotQueryResponse }>(path);
|
||||
return response.parsedBody?.resp.ballots;
|
||||
};
|
||||
|
@ -49,7 +49,7 @@ export const getBallot = async (
|
|||
export const getBallotInventory = async (
|
||||
election_id: string
|
||||
): Promise<BallotInventory | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot?election_id=${election_id}`;
|
||||
const response = await get<{ resp: BallotInventoryResponse }>(path);
|
||||
return response.parsedBody?.resp.inventory;
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ export const findBallots = async (
|
|||
const data: BaseQueryRequest = {
|
||||
filter: { ballot_id },
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot/find?election_id=${election_id}&skip=${skip}&limit=${limit}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot/find?election_id=${election_id}&skip=${skip}&limit=${limit}`;
|
||||
const response = await post<{ resp: BallotQueryResponse }>(path, data);
|
||||
return response.parsedBody?.resp.ballots;
|
||||
};
|
||||
|
@ -80,7 +80,7 @@ export const castBallots = async (
|
|||
context,
|
||||
ballots,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot/cast?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot/cast?election_id=${election_id}`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -97,7 +97,7 @@ export const spoilBallots = async (
|
|||
context,
|
||||
ballots,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot/spoil?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot/spoil?election_id=${election_id}`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -114,7 +114,7 @@ export const submitBallots = async (
|
|||
context,
|
||||
ballots,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot/spoil?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot/spoil?election_id=${election_id}`;
|
||||
const response = await put<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -131,7 +131,7 @@ export const validateBallot = async (
|
|||
context,
|
||||
schema_override,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot/validate`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot/validate`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -146,7 +146,7 @@ export const decryptBallot = async (
|
|||
shares,
|
||||
context,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot/decrypt`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot/decrypt`;
|
||||
const response = await post<{ resp: DecryptedBallots }>(path, data);
|
||||
return response.parsedBody?.resp;
|
||||
};
|
||||
|
@ -161,7 +161,7 @@ export const encryptBallot = async (
|
|||
seed_hash,
|
||||
ballots,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}ballot/encrypt`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/ballot/encrypt`;
|
||||
const response = await post<{ resp: EncryptBallotsResponse }>(path, data);
|
||||
return response.parsedBody?.resp.encrypted_ballots;
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ export { getManifestPreview } from '../mocks/electionSetup';
|
|||
export const getJointKeys = async (): Promise<JointKey[]> => {
|
||||
const keys: JointKey[] = [];
|
||||
const data = { filter: { state: 'CREATED' } };
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/find?skip=0&limit=100`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/find?skip=0&limit=100`;
|
||||
|
||||
const response = await post<{
|
||||
status: string;
|
||||
|
|
|
@ -14,13 +14,13 @@ import {
|
|||
import { BaseResponse } from '../models/base';
|
||||
|
||||
export const getConstants = async (): Promise<ElectionConstants | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}election/constants`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/election/constants`;
|
||||
const response = await get<{ data: ElectionConstants }>(path);
|
||||
return response.parsedBody?.data;
|
||||
};
|
||||
|
||||
export const getElection = async (election_id: string): Promise<Election[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}election?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/election?election_id=${election_id}`;
|
||||
const response = await get<{ data: ElectionQueryResponse }>(path);
|
||||
return response.parsedBody?.data.elections;
|
||||
};
|
||||
|
@ -37,7 +37,7 @@ export const putElection = async (
|
|||
manifest,
|
||||
context,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}election`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/election`;
|
||||
const response = await put<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -50,27 +50,27 @@ export const findElection = async (
|
|||
const data: ElectionQueryRequest = {
|
||||
filter,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}election/find?skip=${skip}&limit=${limit}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/election/find?skip=${skip}&limit=${limit}`;
|
||||
const response = await post<ElectionQueryResponse>(path, data);
|
||||
return response.parsedBody?.elections;
|
||||
};
|
||||
|
||||
export const openElection = async (election_id: string): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}election/open?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/election/open?election_id=${election_id}`;
|
||||
|
||||
const response = await post<{ resp: BaseResponse }>(path, {});
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
||||
export const closeElection = async (election_id: string): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}election/close?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/election/close?election_id=${election_id}`;
|
||||
|
||||
const response = await post<{ resp: BaseResponse }>(path, {});
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
||||
export const publishElection = async (election_id: string): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}election/publish?election_id=${election_id}`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/election/publish?election_id=${election_id}`;
|
||||
|
||||
const response = await post<{ resp: BaseResponse }>(path, {});
|
||||
return response.parsedBody?.resp.is_success();
|
||||
|
@ -84,7 +84,7 @@ export const makeContextElection = async (
|
|||
manifest_hash = '',
|
||||
manifest = {}
|
||||
): Promise<CiphertextElectionContext | undefined> => {
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}election/context`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/election/context`;
|
||||
const data: MakeElectionContextRequest = {
|
||||
elgamal_public_key,
|
||||
commitment_hash,
|
||||
|
|
|
@ -39,13 +39,13 @@ export const postGuardian = async (
|
|||
name,
|
||||
key_name,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian`;
|
||||
const response = await post<{ resp: GuardianPublicKeysResponse }>(path, data);
|
||||
return response.parsedBody?.resp.public_keys;
|
||||
};
|
||||
|
||||
export const getGuardian = async (guardian_id: string): Promise<Guardian | undefined> => {
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian?guardian_id=${guardian_id}`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian?guardian_id=${guardian_id}`;
|
||||
const response = await get<{ guardian: Guardian }>(path);
|
||||
return response.parsedBody?.guardian;
|
||||
};
|
||||
|
@ -53,14 +53,14 @@ export const getGuardian = async (guardian_id: string): Promise<Guardian | undef
|
|||
export const getGuardianPublicKeys = async (
|
||||
guardian_id: string
|
||||
): Promise<PublicKeySetApi[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian/public-keys?guardian_id=${guardian_id}`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian/public-keys?guardian_id=${guardian_id}`;
|
||||
const response = await get<{ resp: GuardianPublicKeysResponse }>(path);
|
||||
return response.parsedBody?.resp.public_keys;
|
||||
};
|
||||
|
||||
export const findGuardians = async (): Promise<Guardian[] | undefined> => {
|
||||
const data = {};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian/find?skip=0&limit=100`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian/find?skip=0&limit=100`;
|
||||
|
||||
const response = await post<{ resp: ApiGuardianQueryResponse }>(path, data);
|
||||
return response.parsedBody?.resp.guardians;
|
||||
|
@ -78,7 +78,7 @@ export const backupGuardian = async (
|
|||
public_keys,
|
||||
override_rsa,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian/backup`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian/backup`;
|
||||
const response = await post<{ resp: GuardianBackupResponse }>(path, data);
|
||||
return response.parsedBody?.resp.backups;
|
||||
};
|
||||
|
@ -93,7 +93,7 @@ export const backupVerificationGuardian = async (
|
|||
backup,
|
||||
override_rsa,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian/backup/verify`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian/backup/verify`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -106,7 +106,7 @@ export const backupChallengeGuardian = async (
|
|||
guardian_id,
|
||||
backup,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian/challenge`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian/challenge`;
|
||||
const response = await post<{ resp: BackupChallengeResponse }>(path, data);
|
||||
return response.parsedBody?.resp.challenge;
|
||||
};
|
||||
|
@ -119,7 +119,7 @@ export const verifyChallengeGuardian = async (
|
|||
verifier_id,
|
||||
challenge,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian/challenge/verify`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian/challenge/verify`;
|
||||
const response = await post<{ resp: BackupVerificationResponse }>(path, data);
|
||||
return response.parsedBody?.resp.verification;
|
||||
};
|
||||
|
@ -128,19 +128,19 @@ export const getGuardians = async (
|
|||
key_name: string,
|
||||
guardian_id: string
|
||||
): Promise<KeyCeremonyGuardian[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}guardian?key_name=${key_name}&guardian_id=${guardian_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/guardian?key_name=${key_name}&guardian_id=${guardian_id}`;
|
||||
const response = await get<{ resp: GuardianQueryResponse }>(path);
|
||||
return response.parsedBody?.resp.guardians;
|
||||
};
|
||||
|
||||
export const putGuardians = async (data: KeyCeremonyGuardian): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}guardian`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/guardian`;
|
||||
const response = await put<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
||||
export const postGuardians = async (data: KeyCeremonyGuardian): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}guardian`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/guardian`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -153,7 +153,7 @@ export const findKeyGuardians = async (
|
|||
const data: BaseQueryRequest = {
|
||||
filter: { guardian_id },
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}guardian/find?skip=${skip}&limit=${limit}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/guardian/find?skip=${skip}&limit=${limit}`;
|
||||
const response = await post<{ resp: GuardianQueryResponse }>(path, data);
|
||||
return response.parsedBody?.resp.guardians;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ export const postJointKey = async (data: BaseJointKey): Promise<boolean | undefi
|
|||
guardian_ids: data.guardians.map((g) => g.id),
|
||||
};
|
||||
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony`;
|
||||
const response = await put<{ resp: BaseResponse }>(path, submitData);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
|
|
@ -61,7 +61,7 @@ export const getKeyCeremonyGuardiansByStep = (step: KeyCeremonyStep): KeyCeremon
|
|||
getKeyCeremonyGuardians().map((guardian) => setKeyCeremonyGuardianToStep(guardian, step));
|
||||
|
||||
export const getKeyCeremonies = async (key_name: string): Promise<KeyCeremony[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony?key_name=${key_name}`;
|
||||
const response = await get<{ resp: KeyCeremonyQueryResponse }>(path);
|
||||
return response.parsedBody?.resp.key_ceremonies;
|
||||
};
|
||||
|
@ -79,7 +79,7 @@ export const putKeyCeremony = async (
|
|||
guardian_ids,
|
||||
};
|
||||
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony`;
|
||||
const response = await put<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -87,7 +87,7 @@ export const putKeyCeremony = async (
|
|||
export const getKeyCeremonyState = async (
|
||||
key_name: string
|
||||
): Promise<KeyCeremonyState | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/state?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/state?key_name=${key_name}`;
|
||||
const response = await get<{ resp: KeyCeremonyStateResponse }>(path);
|
||||
return response.parsedBody?.resp.state;
|
||||
};
|
||||
|
@ -100,25 +100,25 @@ export const findKeyCeremonies = async (
|
|||
const data: BaseQueryRequest = {
|
||||
filter: { ballot_id },
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/find?skip=${skip}&limit=${limit}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/find?skip=${skip}&limit=${limit}`;
|
||||
const response = await post<{ resp: KeyCeremonyQueryResponse }>(path, data);
|
||||
return response.parsedBody?.resp.key_ceremonies;
|
||||
};
|
||||
|
||||
export const openKeyCeremony = async (key_name: string): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/open?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/open?key_name=${key_name}`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, {});
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
||||
export const closeKeyCeremony = async (key_name: string): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/close?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/close?key_name=${key_name}`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, {});
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
||||
export const challengeKeyCeremony = async (key_name: string): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/challenge?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/challenge?key_name=${key_name}`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, {});
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -126,13 +126,13 @@ export const challengeKeyCeremony = async (key_name: string): Promise<boolean |
|
|||
export const challengeVerifyKeyCeremony = async (
|
||||
key_name: string
|
||||
): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/challenge/verify?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/challenge/verify?key_name=${key_name}`;
|
||||
const response = await get<{ resp: BaseResponse }>(path);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
||||
export const cancelKeyCeremony = async (key_name: string): Promise<boolean | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/cancel?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/cancel?key_name=${key_name}`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, {});
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -140,7 +140,7 @@ export const cancelKeyCeremony = async (key_name: string): Promise<boolean | und
|
|||
export const getJointKeyKeyCeremony = async (
|
||||
key_name: string
|
||||
): Promise<ElectionJointKey | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/joint_key?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/joint_key?key_name=${key_name}`;
|
||||
const response = await get<{ resp: ElectionJointKeyResponse }>(path);
|
||||
return response.parsedBody?.resp.elgamal_public_key;
|
||||
};
|
||||
|
@ -154,7 +154,7 @@ export const combineKeyCeremony = async (
|
|||
election_public_keys,
|
||||
};
|
||||
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/combine`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/combine`;
|
||||
const response = await post<{ resp: ElectionJointKeyResponse }>(path, data);
|
||||
return response.parsedBody?.resp.elgamal_public_key;
|
||||
};
|
||||
|
@ -162,7 +162,7 @@ export const combineKeyCeremony = async (
|
|||
export const publishKeyCeremony = async (
|
||||
key_name: string
|
||||
): Promise<ElectionJointKey | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/ceremony/publish?key_name=${key_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/ceremony/publish?key_name=${key_name}`;
|
||||
const response = await post<{ resp: ElectionJointKeyResponse }>(path, {});
|
||||
return response.parsedBody?.resp.elgamal_public_key;
|
||||
};
|
||||
|
@ -175,7 +175,7 @@ export const announceGuardianKeyCeremony = async (
|
|||
key_name,
|
||||
public_keys,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/guardian/announce`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/guardian/announce`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -190,7 +190,7 @@ export const backupGuardianKeyCeremony = async (
|
|||
guardian_id,
|
||||
backups,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/guardian/backup`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/guardian/backup`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -205,7 +205,7 @@ export const verifyGuardianKeyCeremony = async (
|
|||
guardian_id,
|
||||
verifications,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/guardian/verify`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/guardian/verify`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -220,7 +220,7 @@ export const challengeGuardianKeyCeremony = async (
|
|||
guardian_id,
|
||||
challenges,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}key/guardian/challenge`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/key/guardian/challenge`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
import { get, post, put } from '../utils/http';
|
||||
|
||||
export const getManifest = async (manifest_hash: string): Promise<Manifest[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}manifest?manifest_hash=${manifest_hash}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/manifest?manifest_hash=${manifest_hash}`;
|
||||
const response = await get<{ resp: ManifestQueryResponse }>(path);
|
||||
return response.parsedBody?.resp.manifests;
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ export const putManifest = async (manifest: ElectionManifest): Promise<ElementMo
|
|||
manifest,
|
||||
schema_override: undefined,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}manifest`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/manifest`;
|
||||
const response = await put<{ resp: ManifestSubmitResponse }>(path, data);
|
||||
return response.parsedBody?.resp.manifest_hash;
|
||||
};
|
||||
|
@ -34,7 +34,7 @@ export const findManifest = async (
|
|||
const data: BaseQueryRequest = {
|
||||
filter: { manifest_id },
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}manifest/find?skip=${skip}&limit=${limit}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/manifest/find?skip=${skip}&limit=${limit}`;
|
||||
const response = await post<{ resp: ManifestQueryResponse }>(path, data);
|
||||
return response.parsedBody?.resp.manifests;
|
||||
};
|
||||
|
@ -44,7 +44,7 @@ export const validateManifest = async (manifest: ElectionManifest): Promise<stri
|
|||
manifest,
|
||||
schema_override: undefined,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}manifest/validate`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/manifest/validate`;
|
||||
const response = await post<{ resp: ValidateManifestResponse }>(path, data);
|
||||
return response.parsedBody?.resp.manifest_hash;
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ export const decryptShareTally = async (
|
|||
election_id: string,
|
||||
tally_name: string
|
||||
): Promise<CiphertextTallyDecryptionShare[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}tally/decrypt-share?election_id=${election_id}&tally_name=${tally_name}`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/tally/decrypt-share?election_id=${election_id}&tally_name=${tally_name}`;
|
||||
const response = await get<{ resp: DecryptionShareResponse }>(path);
|
||||
return response.parsedBody?.resp.shares;
|
||||
};
|
||||
|
@ -34,7 +34,7 @@ export const decryptSharePostTally = async (
|
|||
context,
|
||||
};
|
||||
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}tally/decrypt-share`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/tally/decrypt-share`;
|
||||
const response = await post<{ resp: DecryptionShareResponse }>(path, data);
|
||||
return response.parsedBody?.resp.shares;
|
||||
};
|
||||
|
@ -44,7 +44,7 @@ export const getTallyDecrypt = async (
|
|||
tally_name: string,
|
||||
guardian_id: string
|
||||
): Promise<CiphertextTallyDecryptionShare[] | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}tally/decrypt?election_id=${election_id}&tally_name=${tally_name}&guardian_id=${guardian_id}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/tally/decrypt?election_id=${election_id}&tally_name=${tally_name}&guardian_id=${guardian_id}`;
|
||||
const response = await get<{ resp: DecryptionShareResponse }>(path);
|
||||
return response.parsedBody?.resp.shares;
|
||||
};
|
||||
|
@ -55,7 +55,7 @@ export const postShareTally = async (
|
|||
const data: DecryptionShareRequest = {
|
||||
share,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}tally/submit-share`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/tally/submit-share`;
|
||||
const response = await post<{ resp: BaseResponse }>(path, data);
|
||||
return response.parsedBody?.resp.is_success();
|
||||
};
|
||||
|
@ -68,7 +68,7 @@ export const findTallyDecrypt = async (
|
|||
const data: BaseQueryRequest = {
|
||||
filter: {},
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}tally/find?tally_name=${tally_name}&skip=${skip}&limit=${limit}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/tally/find?tally_name=${tally_name}&skip=${skip}&limit=${limit}`;
|
||||
const response = await post<{ resp: DecryptionShareResponse }>(path, data);
|
||||
return response.parsedBody?.resp.shares;
|
||||
};
|
||||
|
@ -77,7 +77,7 @@ export const getTally = async (
|
|||
election_id: string,
|
||||
tally_name: string
|
||||
): Promise<CiphertextTally | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}tally?election_id=${election_id}&tally_name=${tally_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/tally?election_id=${election_id}&tally_name=${tally_name}`;
|
||||
const response = await get<{ resp: CiphertextTally }>(path);
|
||||
return response.parsedBody?.resp;
|
||||
};
|
||||
|
@ -86,7 +86,7 @@ export const postTally = async (
|
|||
election_id: string,
|
||||
tally_name: string
|
||||
): Promise<CiphertextTally | undefined> => {
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}tally?election_id=${election_id}&tally_name=${tally_name}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/tally?election_id=${election_id}&tally_name=${tally_name}`;
|
||||
const response = await post<{ resp: CiphertextTally }>(path, {});
|
||||
return response.parsedBody?.resp;
|
||||
};
|
||||
|
@ -100,7 +100,7 @@ export const findTally = async (
|
|||
const data: BaseQueryRequest = {
|
||||
filter,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}tally/find?election_id=${election_id}skip=${skip}&limit=${limit}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/tally/find?election_id=${election_id}skip=${skip}&limit=${limit}`;
|
||||
const response = await post<{ resp: CiphertextTallyQueryResponse }>(path, data);
|
||||
return response.parsedBody?.resp.tallies;
|
||||
};
|
||||
|
@ -114,7 +114,7 @@ export const decryptTally = async (
|
|||
election_id,
|
||||
tally_name,
|
||||
};
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}tally/decrypt?restart=${restart}`;
|
||||
const path = `${process.env.REACT_APP_MEDIATOR_SERVICE}/api/v1/tally/decrypt?restart=${restart}`;
|
||||
const response = await post<{ resp: PlaintextTallyQueryResponse }>(path, data);
|
||||
return response.parsedBody?.resp.tallies;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ import { post } from '../utils/http';
|
|||
export const getUsersWithGuardianRole = async (): Promise<User[]> => {
|
||||
const users: User[] = [];
|
||||
const data = {};
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}guardian/find?skip=0&limit=100`;
|
||||
const path = `${process.env.REACT_APP_GUARDIAN_SERVICE}/api/v1/guardian/find?skip=0&limit=100`;
|
||||
|
||||
const response = await post<{
|
||||
status: string;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AsyncResult, JointKey, getGuardianApiClient } from '@electionguard/api-client';
|
||||
import { ApiClientFactory, AsyncResult, JointKey } from '@electionguard/api-client';
|
||||
import { Box } from '@material-ui/core';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
|
@ -37,7 +37,7 @@ export const ElectionSetupWizard: React.FC<ElectionSetupWizardProps> = ({ getKey
|
|||
const { nextStep } = createEnumStepper(ElectionSetupStep);
|
||||
const next = () => setStep(nextStep(step));
|
||||
|
||||
const service = getGuardianApiClient();
|
||||
const service = ApiClientFactory.getGuardianApiClient();
|
||||
return (
|
||||
<Box height="100%">
|
||||
<WizardStep active={step === ElectionSetupStep.Instructions}>
|
||||
|
|
ΠΠ°Π³ΡΡΠ·ΠΊΠ°β¦
Π‘ΡΡΠ»ΠΊΠ° Π² Π½ΠΎΠ²ΠΎΠΉ Π·Π°Π΄Π°ΡΠ΅