4.0.0 • Published 2 months ago

@taktikal/core-api v4.0.0

Weekly downloads
158
License
ISC
Repository
gitlab
Last release
2 months ago

Config

setCoreApiUrl()

Sets the default Core API URL that will be used by fns.

setCoreApiUrl(apiUrl): Promise<void>;
  • apiUrl (string)

Functions

processSignDocument()

High level function that deals with signing a document for a Signee in a SigningProcess.

processSignDocument(startSignOptions, [options]): Promise<void>;
  • startSignOptions (ProcessStartSignOptions)
  • options ({ apiUrl?: string })

The ProcessStartSignOptions look like so:

interface ProcessStartSignOptions {
  signeeKey: string;
  processKey: string;
  onStartSign: {
    success: (controlCode: string) => void;
    certificateNotActive: () => void;
    locked: (lockedBy?: string) => void;
    pinBlocked: () => void;
    error: (e: any) => void;
  };
  onSign: {
    success: (signedDocument: CoreApiSignedDocument) => void;
    userCancelled: () => void;
    timeout: () => void;
    error: (e: any) => void;
  };
  onComplete?: () => void;
}

The optional onComplete fn can be used for state cleanup. It is called:

  • When creating the signing request fails
  • When signing fails
  • When signing is successful

Signing a document

The process of signing a document goes along these lines:

1. The user clicks the "Sign document" button

When the button is clicked, we send a request to the Core API to start signing the document. A "pending" state of some sort should be shown to the user.

2. We receive a response

The response we are hoping for is a token and controlCode.

  • The token is a unique token that can be used to check the status of the signing request.
  • The controlCode is a 4 digit code that will be shown on the user's phone. It should be shown in the UI as well so the user can confirm that the signing request came from you.

We can receive a few types of errors when starting signing:

  • pinBlocked means that the users has entered the PIN for his eID incorrectly too many times and it has been blocked. The user will have to visit the bank or Auðkenni to get this resolved.
  • locked means that another user is currently signing the same document.
  • certificateNotActive means that the users eID exists but is not active.
  • error is an unexpected error. May be a network connectivity issue or any other issue that happens from time to time.

3. Wait until document has been signed

We periodically check whether or not the document has been signed. The result can be one of the following:

  • success means that we successfully signed the document!
  • userCancelled means that the user received the signing request but cancelled it manually.
  • timeout means that the user did not respond to the signing request in time.
  • error, like before, is an unexpected error.

Dealing with different errors

When starting signing the certificateNotActive and pinBlocked errors are, for the time being, irrecoverable. The user should not be prompted to retry signing, he should instead be moved to an "error" state that instructs him to go fix the issue with his eID.

After signing has successfully started, the user should be moved to a new step where the controlCode is shown in big and bold letters. It should also be made clear to the user that he should check his phone for the signing request, since users may or may not be familiar with how signing documents takes place.

Errors that are encountered during signing (userCancelled, timeout) are temporary so the user should be promted to retry signing.

Error messages

We suggest the following error messages:

PIN blocked

Pin númer hefur verið slegið inn of oft rangt og hefur verið læst.

Þú þarft að fara í eina af skráningarstöðvum Auðkennis hjá t.d. banka eða fjarskiptafyrirtæki til að virkja skilríkið. Framvísa þarf ökuskírteini eða vegabréfi.

Certificate not active

Skilríki á síma er ógilt.

Þú þarft að fara í eina af skráningarstöðvum Auðkennis hjá t.d. banka eða fjarskiptafyrirtæki til að endurnýja skilríkið. Framvísa þarf ökuskírteini eða vegabréfi.

Locked

With lockedBy:

${lockedBy} er að undirrita skjalið, prófaðu aftur eftir augnablik

Without:

Annar undirritandi er að undirrita skjalið, prófaðu aftur eftir augnablik

User cancelled

Þú virðist hafa hætt við undirritun

Timeout

Undirritun rann út á tíma.

Gleymdirðu nokkuð að athuga símann?

authenticate()

Takes in a flow key and a user's phone number and authenticates the user via eID.

authenticate(flowKey, phoneNumber, [options]): Promise<CoreApiNameAddressAuthResponse | CoreApiNameAuthResponse>;
  • flowKey (string)
  • phoneNumber (string)
  • options ({ apiUrl?: string, type: "name" | "name_and_address" })

Returns a Promise that resolve to CoreApiNameAuthResponse if the type is "name" and CoreApiNameAddressAuthResponse if the type is "name_and_address".

export interface CoreApiNameAuthResponse {
  name: string;
  ssn: string;
  phoneNumber: string;
  token: string;
  flowKey: string;
  meta: {};
}

export interface CoreApiNameAddressAuthResponse {
  name: string;
  ssn: string;
  phoneNumber: string;
  address: string;
  postalCode: string;
  city: string;
  token: string;
  flowKey: string;
  meta: {
    GenderCode: NationalRegistryGenderCode;
  };
}

getFlow()

Gets a flow by flow key.

getFlow(flowKey, [options]): Promise<GetFlowResponse>;
  • flowKey (string)
  • options ({ apiUrl?: string })

Returns a GetFlowResponse.

export type GetFlowResponse<T extends CoreApiFlow = CoreApiFlow> =
  | {
      status: "ok";
      flow: T;
    }
  | {
      status: "not_found";
      flow: null;
    }
  | {
      status: "flow_key_not_valid";
      flow: null;
    };

The flow's type will be one of RenderFlow, DropAndSign and FillAndSign. If you want a specific type of flow, consider using one of the more specific "get flow by type" functions in the next section.

getDropAndSignFlow(), getFillAndSignFlow() and getRenderFlow()

Gets a flow of a specific type by flow key.

getDropAndSignFlow(flowKey, [options]): Promise<GetFlowByTypeResponse<CoreApiDropAndSignFlow>>;
getFillAndSignFlow(flowKey, [options]): Promise<GetFlowByTypeResponse<CoreApiFillAndSignFlow>>;
getRenderFlow(flowKey, [options]): Promise<GetFlowByTypeResponse<CoreApiRenderFlow>>;
  • flowKey (string)
  • options ({ apiUrl?: string })

The return type is the same as from getFlow(), except an additional status is added to the GetFlowResponse called "not_of_type".

export type GetFlowByTypeResponse<T extends CoreApiFlow> =
  | GetFlowResponse<T>
  | {
      status: "not_of_type";
    };

getSigningProcessBySignee()

Gets a signing process for a signee.

getSigningProcessBySignee(processKey, signeeKey, [options]): Promise<GetSigningProcessResponse>;
  • processKey (string)
  • signeeKey (string)
  • options ({ apiUrl?: string })

Returns a GetSigningProcessResponse.

export type GetSigningProcessResponse<Meta extends {} = {}> =
  | {
      status: "ok";
      signingProcess: CoreApiSigningProcess<Meta>;
    }
  | {
      status: "error";
      type: "process_not_found";
    }
  | {
      status: "error";
      type: "not_signee_of_process";
    };

getSigningProcessList()

Gets a list of signing processes that all have a single signee.

getSigningProcessList(keyString, [options]): Promise<GetSigningProcessListResponse>;
  • keyString (string)
  • options ({ apiUrl?: string })

The keyString is a list of process and signee key pairs:

sp00000:si0000000000,sp11111:si1111111111,sp33333:si3333333333

It is expected that:

  • All processes were created by flows in the same company
  • All processes only have a single signee
  • All signees have the same ssn

Returns a GetSigningProcessListResponse.

export type GetSigningProcessListResponse<Meta extends {} = {}> =
  | {
      status: "ok";
      processes: CoreApiSigningProcess<Meta>[];
      allSigned: boolean;
      companyName: string;
      companyKey: string;
    }
  | {
      status: "error";
      type: "process_not_found";
      processKey: string;
      signeeKey: string;
    }
  | {
      status: "error";
      type: "not_signee_of_process";
      processKey: string;
      signeeKey: string;
    }
  | {
      status: "error";
      type: "not_single_signee_in_process";
      processKey: string;
    }
  | {
      status: "error";
      type: "different_signees_in_processes";
    }
  | {
      status: "error";
      type: "flows_from_different_companies";
    };

processStartSignDocument()

Starts signing a document for a Signee in an existing Signingprocess.

The returned controlCode should be shown to the user in the UI. The token should be passed to processGetSignedDocument which will get the result of the signing.

processStartSignDocument(processKey, signeeKey, [options]): Promise<StartSignDocumentResponse>;
  • processKey (string)
  • signeeKey (string)
  • options ({ apiUrl?: string })

Returns a StartSignDocumentResponse:

export type StartSignDocumentResponse =
  | {
      status: "ok";
      controlCode: string;
      token: string;
    }
  | {
      status: "error";
      type: "locked";
      lockedBy?: string;
    }
  | {
      status: "error";
      type: "pin_blocked";
    }
  | {
      status: "error";
      type: "certificate_not_active";
    };

processGetSignedDocument()

Should be called right after starting signing for a Signee in a SigningProcess. Waits until the signee has finished signing and returns the signed document.

processGetSignedDocument(processKey, token, [options]): Promise<GetSignedDocumentResponse>;
  • processKey (string)
  • token (string) - Token from processStartSignDocument
  • options ({ apiUrl?: string })

Returns a GetSignedDocumentResponse:

export type GetSignedDocumentResponse =
  | {
      status: "signed";
      signedDocument: CoreApiSignedDocument;
    }
  | {
      status: "error";
      type: "user_cancelled" | "timeout";
      message: string;
    };

createSigningProcess()

Creates a SigningProcess that supports multiple Signees.

createSigningProcess(companyKey, apiKey, createSigningProcessBody, [options]): Promise<CoreApiSigningProcess>;
  • companyKey (string)
  • apiKey (string) - The API key for the company
  • createSigningProcessBody (CoreApiCreateSigningProcessBody)
  • options ({ apiUrl?: string })

Returns a CoreApiSigningProcess.

export interface CoreApiCreateSigningProcessBody<Meta extends {} = {}> {
  flowKey: string;
  meta: Meta;
  createSignees: Array<{
    name: string;
    ssn: string;
    email: string;
    phoneNumber: string;
    communicationDeliveryType: string;
    address?: string;
    postalCode?: string;
    city?: string;
  }>;
  pdfDocument?: string;
  pdfFileName?: string;
  requiresAuth?: boolean;
  attachments?: CoreApiSigningProcessAttachment[];
  signInOrder?: boolean;
  signatureLocation?: CoreApiSignatureLocation;
  user?: string;
}

The pdfDocument and pdfFileName are optional for RenderFlows.

requiresAuth

Having the signee key for a signee in a SigningProcess acts as a form of authentication. This means that if a malicious third party obtains a signing URL with both the process key and signee key, he will be able to view the document to be signed.

This does not let the third party sign the document, for that they would need the signee's eID. But the document may contain sensitive information.

If that is the case, the requiresAuth option will send the user to ${url}${processKey} instead of ${url}${processKey}/${signeeKey}. If the signing front end only receives the process key, it should make the user authenticate into the SigningProcess before showing him the document (sending him to ${processKey}/${signeeKey}).

Note: Only the app.taktikal.is/s/ signing page currently supports authenticating into a SigningProcess. Authenticating into a SigningProcess is currently not in the @taktikal/core-api package. Expect it to be added soon.

attachments

The attachments will be sent via email. This option is currently only used by Fill & Sign.

user

The email of the user that is creating the SigningProcess. This is only required for DropAndSign flows.

getSigneePdfBuffer()

Gets the PDF document for a Signee in a SigningProcess as a Buffer.

getSigneePdfBuffer(processKey, signeeKey, [options]): Promise<Buffer>;
  • processKey (string)
  • signeeKey (string)
  • options ({ apiUrl?: string })

Returns a Buffer.

Example usage:

const buffer = await getSigneePdfBuffer(processKey, signeeKey);
res.contentType("application/pdf");
res.send(buffer);

nationalRegistryLookup()

Looks up a person in the Icelandic national registry.

nationalRegistryLookup(type, flowKey, ssn, [options]): Promise<NationalRegistryLookupResponse<
  CoreApiNationalRegistryNameResponse | CoreApiNationalRegistryNameAddressResponse
>>;
  • type ("name" | "name_and_address")
  • flowKey (string)
  • ssn (string) - 10 digit kennitala
  • options ({ apiUrl?: string })

Returns a NationalRegistryLookupResponse that contains a CoreApiNationalRegistryNameResponse if the type is "name" and contains a CoreApiNationalRegistryNameAddressResponse if the type is "name_and_address".

export interface CoreApiNationalRegistryNameAddressResponse {
  name: string;
  ssn: string; // 10 digits
  address: string;
  postalCode: string; // 3 digits
  city: string;
}

export interface CoreApiNationalRegistryNameResponse {
  ssn: string;
  name: string;
}

export type NationalRegistryLookupResponse<T = CoreApiNationalRegistryNameResponse> =
  | {
      status: "ok";
      data: T;
    }
  | {
      status: "not_found";
    };

companyRegistryLookup()

Looks up a person in the Icelandic national company registry.

companyRegistryLookup(flowKey, ssn, [options]): Promise<CompanyRegistryLookupResponse>;
  • flowKey (string)
  • ssn (string) - 10 digit kennitala
  • options ({ apiUrl?: string })

Returns a CompanyRegistryLookupResponse that contains a CoreApiCompanyRegistryResponse.

export interface CoreApiCompanyRegistryResponse {
  name: string;
  ssn: string;
  address: string;
  postalCode: string;
  city: string;
  industryCodeIs: string;
  leagalIdentityType: string;
  municipalityCode: string;
  vat: number;
}

export type CompanyRegistryLookupResponse =
  | {
      status: "ok";
      data: CoreApiCompanyRegistryResponse;
    }
  | {
      status: "not_found";
    };

getHasCertificate()

Checks whether or not a user has a valid eID certificate.

getHasCertificate(flowKey, ssn, phoneNumber, [options]): Promise<HasCertificateResponse>;
  • flowKey (string)
  • ssn (string) - 10 digit kennitala
  • phoneNumber (string)
  • options ({ apiUrl?: string })

Returns a HasCertificateResponse.

export type HasCertificateResponse =
  | {
      status: "has_certificate";
      name: string; // Name of the person in the national registry
    }
  | {
      status: "no_certificate";
    };

Types

The types that are used by this package are accessible as named exports:

AuthResponse
GetFlowByTypeResponse
GetFlowResponse
GetSignedDocumentResponse
NationalRegistryLookupResponse
StartSignDocumentResponse
HasCertificateResponse

The Core API types that this package makes use of are also accessible as named exports.

CoreApiFillAndSignFlow
CoreApiSignedDocument
CoreApiNationalRegistryNameResponse
CoreApiNameAuthResponse
CoreApiSigningProcessAttachment
CoreApiNameAddressAuthResponse
CoreApiGetSignedDocumentResponse
CoreApiErrorResponseData
CoreApiCustomer
CoreApiCreateSigningProcessBody
CoreApiDropAndSignFlow
CoreApiFlow
CoreApiFlowProductType
CoreApiHasCertificateResponse
CoreApiNationalRegistryNameAddressResponse
CoreApiRenderFlow
CoreApiSignee
CoreApiSigningProcess
CoreApiStartSignProcessDocumentResponse
CoreApiSigneeSignatureType
CoreApiAccessToken
4.0.0

2 months ago

3.6.1

3 months ago

3.6.0

3 months ago

3.4.0

7 months ago

3.5.0

7 months ago

3.3.2

7 months ago

3.2.0

8 months ago

3.1.3

11 months ago

3.1.2

11 months ago

3.1.1

11 months ago

3.1.0

11 months ago

3.0.1

11 months ago

3.0.0

11 months ago

2.2.0

11 months ago

2.1.0

12 months ago

2.0.2

1 year ago

2.0.1

1 year ago

2.0.0

1 year ago

1.5.0

1 year ago

1.4.0

1 year ago

1.3.2

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.2.0

2 years ago

1.2.1

2 years ago

1.1.4

2 years ago

1.1.1

2 years ago

1.1.3

2 years ago

1.1.2

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago