Options
All
  • Public
  • Public/Protected
  • All
Menu

The API is responsible for handling all the cryptographic operations and all network communication with:

  • the Digital Ballot Box
  • the Voter Authorization Coordinator service
  • the OTP provider(s)

Expected sequence of methods being executed

Method Description
initialize Initializes the library by fetching election configuration
requestAccessCode Initiates the authorization process, in case voter has not authorized yet. Requests access code to be sent to voter email
validateAccessCode Gets voter authorized to vote.
registerVoter Registers the voter on the bulletin board
{@link AVClient.constructBallotCryptograms constructBallotCryptograms }
spoilBallot Optional. Initiates process of testing the ballot encryption.
castBallot Finalizes the voting process.
purgeData Optional. Explicitly purges internal data.

Example walkthrough test

import { AVClient } from '../lib/av_client';
import { expect } from 'chai';
import { readmeTestSetup, readmeTestTeardown } from './readme_example_helper';
import { BallotSelection } from '../lib/av_client/types';

describe('entire voter flow using OTP authorization', () => {
beforeEach(() => readmeTestSetup());
afterEach(() => readmeTestTeardown());

it.skip('returns a receipt', async () => {
const client = new AVClient('http://us-avx:3000/dbb/us/api');
await client.initialize()

await client.requestAccessCode('123', 'us-voter-123@aion.dk');

// ... voter receives email with access code (OTP code) ...

await client.validateAccessCode('1234');

await client.registerVoter();

const ballotSelection: BallotSelection = {
reference: 'ballot-1',
contestSelections: [
{
reference: 'contest ref 1',
optionSelections: [{reference: 'option ref 1'}]
},
{
reference: 'contest ref 2',
optionSelections: [{reference: 'option ref 3'}]
}
]
}

const trackingCode = await client.constructBallot(ballotSelection);
expect(trackingCode.length).to.eq(64);

const affidavit = Buffer.from('some bytes, most likely as binary PDF').toString('base64');
const ballotTrackingCode = await client.castBallot(affidavit);

expect(typeof ballotTrackingCode === "string").to.be.true;
});
});

Hierarchy

  • AVClient

Implements

Index

Constructors

  • new AVClient(bulletinBoardURL: string, dbbPublicKey?: string): AVClient
  • Parameters

    • bulletinBoardURL: string

      URL to the Assembly Voting backend server, specific for election.

    • Optional dbbPublicKey: string

    Returns AVClient

Methods

  • initialize(electionConfig: undefined | ElectionConfig, keyPair: KeyPair): Promise<void>
  • initialize(electionConfig: ElectionConfig): Promise<void>
  • initialize(): Promise<void>
  • Initializes the client with an election config. If no config is provided, it fetches one from the backend.

    throws

    NetworkError if any request failed to get a response

    Parameters

    • electionConfig: undefined | ElectionConfig

      Allows injection of an election configuration for testing purposes

    • keyPair: KeyPair

      Allows injection of a keypair to support automatic testing

    Returns Promise<void>

    Returns undefined if succeeded or throws an error

  • Parameters

    Returns Promise<void>

  • Returns Promise<void>

  • requestAccessCode(opaqueVoterId: string, email: string): Promise<void>
  • Should be called when a voter chooses digital vote submission (instead of mail-in).

    Will attempt to get backend services to send an access code (one time password, OTP) to voter's email address.

    Should be followed by validateAccessCode to submit access code for validation.

    throws

    VoterRecordNotFound if no voter was found

    throws

    NetworkError if any request failed to get a response

    Parameters

    • opaqueVoterId: string

      Voter ID that preserves voter anonymity.

    • email: string

      where the voter expects to receive otp code.

    Returns Promise<void>

    Returns undefined or throws an error.

  • validateAccessCode(code: string): Promise<void>
  • Should be called after requestAccessCode.

    Takes an access code (OTP) that voter received, uses it to authorize to submit votes.

    Internally, generates a private/public key pair, then attempts to authorize the public key with each OTP provider.

    Should be followed by {@link AVClient.constructBallotCryptograms | constructBallotCryptograms}.

    throws

    InvalidStateError if called before required data is available

    throws

    AccessCodeExpired if an OTP code has expired

    throws

    AccessCodeInvalid if an OTP code is invalid

    throws

    NetworkError if any request failed to get a response

    Parameters

    • code: string

      An access code string.

    Returns Promise<void>

    Returns undefined if authorization succeeded or throws an error

  • createVoterRegistration(): Promise<void>
  • Compatible with new DBB structure (WIP)

    Returns Promise<void>

  • registerVoter(): Promise<void>
  • Registers a voter

    Returns Promise<void>

    undefined or throws an error

  • Should be called after validateAccessCode.

    Encrypts a ballot-selection (CVR) and generates vote cryptograms.

    Example:

    const client = new AVClient(url);
    const cvr = { '1': 'option1', '2': 'optiona' };
    const trackingCode = await client.constructBallotCryptograms(cvr);

    Example of handling errors:

    try {
    await client.constructBallotCryptograms({});
    } catch(error) {
    if(error instanceof AvClientError) {
    switch(error.name) {
    case 'InvalidStateError':
    console.log("State is not valid for this call");
    break;
    case 'NetworkError':
    console.log("It's a network error");
    break;
    default:
    console.log('Something else was wrong');
    }
    }
    }

    Where '1' and '2' are contest ids, and 'option1' and 'optiona' are values internal to the AV election config.

    Should be followed by either spoilBallot or castBallot.

    throws

    InvalidStateError if called before required data is available

    throws

    CorruptCvrError if the cast vote record is invalid

    throws

    NetworkError if any request failed to get a response

    Parameters

    Returns Promise<string>

    Returns the ballot tracking code. Example:

    '5e4d8fe41fa3819cc064e2ace0eda8a847fe322594a6fd5a9a51c699e63804b7'
    
  • Should be the last call in the entire voting process.

    Requests that the previously constructed ballot is cast.

    throws

    NetworkError if any request failed to get a response

    Parameters

    • Optional _affidavit: string

    Returns Promise<BallotBoxReceipt>

    Returns the vote receipt. Example of a receipt:

    {
    previousBoardHash: 'd8d9742271592d1b212bbd4cbvobbe357aef8e00cdbdf312df95e9cf9a1a921465',
    boardHash: '5a9175c2b3617298d78be7d0244a68f34bc8b2a37061bb4d3fdf97edc1424098',
    registeredAt: '2020-03-01T10:00:00.000+01:00',
    serverSignature: 'dbcce518142b8740a5c911f727f3c02829211a8ddfccabeb89297877e4198bc1,46826ddfccaac9ca105e39c8a2d015098479624c411b4783ca1a3600daf4e8fa',
    voteSubmissionId: 6
    }
  • spoilBallot(): Promise<string>
  • Should be called when voter chooses to test the encryption of their ballot. Gets commitment opening of the digital ballot box and validates it.

    throws

    InvalidStateError if called before required data is available

    throws

    ServerCommitmentError if the server commitment is invalid

    throws

    NetworkError if any request failed to get a response

    Returns Promise<string>

    Returns undefined if the validation succeeds or throws an error

  • challengeBallot(): Promise<void>
  • Should be called when the voter has 'paired' the verifier and the voting app. Computes and encrypts the clientEncryptionCommitment and posts it to the DBB

    throws

    InvalidStateError if called before required data is available

    throws

    NetworkError if any request failed to get a response

    Returns Promise<void>

    Returns void if the computation was succesful

  • purgeData(): void
  • getVoterSession(): VoterSessionItem
  • Returns VoterSessionItem

  • getVoterBallotConfig(): BallotConfig
  • Returns BallotConfig

  • getDbbPublicKey(): string
  • Returns string

  • waitForVerifierRegistration(): Promise<string>
  • Should be called after spoilBallot. Gets the verifier public key from the DBB

    throws

    InvalidStateError if called before required data is available

    throws

    TimeoutError if the verifier doesn't register itself to the DBB in time

    throws

    NetworkError if any request failed to get a response

    Returns Promise<string>

    Returns the pairing code based on the address of the verifier item in the DBB

  • checkBallotStatus(trackingCode: string): Promise<BallotStatus>
  • Finds the ballot status corresponding to the given trackingcode. Also returns the activities associated with the ballot

    Parameters

    • trackingCode: string

      base58-encoded trackingcode

    Returns Promise<BallotStatus>