diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..5f9ce88
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+max_line_length = 120
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..db2cc34
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,3 @@
+bin
+node_modules
+dist
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..100bc2f
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,24 @@
+module.exports = {
+ root: true,
+ parser: "@typescript-eslint/parser",
+ plugins: [
+ "@typescript-eslint",
+ ],
+ extends: [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/eslint-recommended",
+ "plugin:@typescript-eslint/recommended",
+ ],
+ rules: {
+ "quotes": "error",
+ "semi": "off",
+ "key-spacing": ["error", { "align": "value" }],
+ "comma-dangle": ["error", "always-multiline"],
+ "object-curly-spacing": ["error", "always"],
+ "array-bracket-spacing": "error",
+ "indent": "off",
+ "@typescript-eslint/indent": ["error", 2],
+ "@typescript-eslint/semi": ["error"],
+ "@typescript-eslint/no-explicit-any": "off",
+ },
+};
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..49cbbf8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+node_modules
+.vscode
+/web-eid.js
+/config.js
+/errors
+/models
+/services
+/utils
+/*.tgz
+dist/
+*.swp
diff --git a/LICENSE b/LICENSE
index b5f78ce..0b8eeef 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020 eID on platform Web
+Copyright (c) 2020 The Web eID Project
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..974ab1d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1053 @@
+# web-eid.js
+
+![European Regional Development Fund](https://github.com/e-gov/RIHA-Frontend/raw/master/logo/EU/EU.png)
+
+`web-eid.js` — add strong authentication and digital signing with electronic ID smart cards to
+web applications with the Web eID JavaScript library. `web-eid.js`
+is a thin wrapper on top of the messaging interface provided by the Web eID
+browser extension.
+
+## Quickstart
+
+Complete the three steps below to add strong authentication and digital signing
+support to your web application front end. Instructions for the back end are
+available [here]().
+
+To run this quickstart you need a modern web application that uses NPM to
+manage JavaScript packages.
+
+See full example [here]().
+
+### 1. Add web-eid.js to the project
+
+1. Run the following command to install the library using NPM:
+
+ echo '@web-eid:registry=https://gitlab.com/api/v4/packages/npm' >> .npmrc
+ npm install web-eid
+
+1. Configure the web server to expose `node_modules/web-eid/dist/es/web-eid.js`
+
+See below for alternative installation options.
+
+### 2. Add authentication support to your web app
+
+Copy the following code to the authentication page of your web application,
+amending `options` according to your back end configuration:
+
+```html
+
+
+
+
+
+```
+
+See below for `options` description.
+
+### 3. Add digital signature support to your web app
+
+Copy the following code to the digital signing page of your web application,
+amending `options` according to your back end configuration:
+
+```html
+
+
+
+
+
+```
+
+See below for `options` description.
+
+### 4. Run the example
+
+1. Download and run [the Web eID installer](https://web-eid.eu) for your operating system.
+2. Start your web appliction.
+3. Web eID requires HTTPS. If your web application does not have HTTPS support, use e.g. [ngrok](https://ngrok.com/) to add it.
+4. Open the HTTPS URL in the browser, attach a smart card reader, insert the electronic ID card and try out authentication and signing.
+
+## Table of contents
+
+
+
+
+
+- [Quickstart](#quickstart)
+- [Install](#install)
+ - [Without a module system](#without-a-module-system)
+ - [ES module for server-side build tools](#es-module-for-server-side-build-tools)
+ - [ES module for browsers](#es-module-for-browsers)
+ - [UMD module for AMD and browser-side CommonJS module loaders](#umd-module-for-amd-and-browser-side-commonjs-module-loaders)
+- [API](#api)
+ - [Status](#status)
+ - [Status parameters](#status-parameters)
+ - [Status returns](#status-returns)
+ - [Status example - check using async-await](#status-example-check-using-async-await)
+ - [Status example - check using promises](#status-example-check-using-promises)
+ - [Status example - success](#status-example-success)
+ - [Status example - failure](#status-example-failure)
+ - [Authenticate](#authenticate)
+ - [Authenticate parameters](#authenticate-parameters)
+ - [Authenticate returns](#authenticate-returns)
+ - [Authenticate example - using async-await](#authenticate-example-using-async-await)
+ - [Authenticate example - using promises](#authenticate-example-using-promises)
+ - [Authenticate example - success](#authenticate-example-success)
+ - [Authenticate example - failure](#authenticate-example-failure)
+ - [Sign](#sign)
+ - [Sign parameters](#sign-parameters)
+ - [Sign returns](#sign-returns)
+ - [Sign example - using async-await](#sign-example-using-async-await)
+ - [Sign example - using promises](#sign-example-using-promises)
+ - [Sign example - success](#sign-example-success)
+ - [Sign example - failure](#sign-example-failure)
+- [Known errors](#known-errors)
+ - [Error codes](#error-codes)
+ - [Timeout errors](#timeout-errors)
+ - [Health errors](#health-errors)
+ - [Security errors](#security-errors)
+ - [Third party errors](#third-party-errors)
+ - [Developer mistakes](#developer-mistakes)
+- [Development](#development)
+ - [Testing changes locally](#testing-changes-locally)
+ - [Using `npm link`](#using-npm-link)
+ - [Using `npm pack`](#using-npm-pack)
+
+
+
+
+## Install
+
+### Without a module system
+
+Use the **dist/iife** build. It exposes `webeid` object globally.
+```html
+
+
+```
+
+
+### ES module for server-side build tools
+
+When using a server-side build tool like WebPack, Babel, Rollup or the
+TypeScript compiler:
+
+1. Run the following command to install the library using NPM:
+
+ echo '@web-eid:registry=https://gitlab.com/api/v4/packages/npm' >> .npmrc
+ npm install web-eid
+
+2. Import modules without an extension:
+
+```javascript
+// Import the Web-eID library
+import webeid from 'web-eid';
+
+// ...or only what you need
+import {
+ status,
+ authenticate,
+ Action,
+ ErrorCode,
+ hasVersionProperties
+} from 'web-eid';
+
+
+// If you need TypeScript interfaces, they are also available!
+import AuthenticateOptions from 'web-eid/models/AuthenticateOptions';
+```
+
+### ES module for browsers
+
+1. Configure the web server to expose `node_modules/web-eid/dist/es/web-eid.js`
+2. Import the modules and specify the file extension
+
+```javascript
+// Import the Web-eID library
+import webeid from 'web-eid.js';
+```
+
+### UMD module for AMD and browser-side CommonJS module loaders
+Use the **dist/umd** build.
+
+**CommonJS**
+```javascript
+var webeid = require("web-eid");
+```
+
+**AMD**
+```javascript
+define(["web-eid"], function(webeid) {
+ ...
+});
+```
+
+
+## API
+
+### Status
+```ts
+status(options?: RequestOptions): Promise
+```
+
+To verify that the user has a valid extension and native application version, a status check can be performed.
+We recommend checking the status before performing other actions - if status check fails, other actions will most likely fail as well.
+However the choice is yours and you may perform the status check retroactively when an action (for example [authenticate](#authenticate)) fails.
+
+#### Status parameters
+
+| Name | Type | Default | Description |
+|-------------------|----------|---------|-----------------------------------------|
+| `options` | `object` | | Optional status request options object |
+| `options.timeout` | `number` | `2000` | Timeout for the request in milliseconds |
+
+#### Status returns
+
+```ts
+Promise
+```
+```typescript
+Version {
+ // SemVer string in the format x.y.z
+ library: string;
+
+ // SemVer string in the format x.y.z
+ nativeApp: string;
+
+ // SemVer string in the format x.y.z
+ extension: string;
+}
+```
+
+#### Status example - check using async-await
+
+```js
+try {
+ const status = await webeid.status();
+
+ // HANDLE SUCCESS
+
+} catch (error) {
+
+ // HANDLE FAILURE
+
+}
+```
+
+#### Status example - check using promises
+
+```js
+webeid.status()
+.then((status) => { /* HANDLE SUCCESS */ })
+.catch((error) => { /* HANDLE FAILURE */ });
+```
+
+#### Status example - success
+
+The result of a status check is the status object which contains SemVer strings for the library, browser extension and native application.
+
+```js
+{
+ library: "1.2.3",
+ nativeApp: "1.2.3",
+ extension: "1.2.3"
+}
+```
+
+#### Status example - failure
+
+When the status check fails, in addition to the usual `name`, `message` and `stack` properties, the error object contains additional info **when possible**.
+See [Known errors](#known-errors) for error `code` options.
+
+```javascript
+{
+ // Name of the Error object
+ "name": "VersionMismatchError",
+
+ // Human readable message, meant for the developer
+ "message": "Update required for Web-eID extension and native app",
+
+ // Programmatic error code, meant for error handling
+ "code": "ERR_WEBEID_VERSION_MISMATCH",
+
+ // SemVer strings of the library, always present
+ "library": "1.2.3",
+
+ // Missing if extension is not installed
+ "extension": "0.2.3",
+
+ // Missing if extension or native application is not installed
+ "nativeApp": "0.2.3",
+
+ // List of components which require an update
+ // Only present if the error is ERR_WEBEID_VERSION_MISMATCH
+ "requiresUpdate": {
+ "extension": true,
+ "nativeApp": true
+ },
+
+ // Stack trace
+ "stack": ...
+}
+```
+
+
+### Authenticate
+
+```ts
+authenticate(options: AuthenticateOptions): Promise
+```
+Requests the Web-eID browser extension to authenticate the user.
+
+#### Authenticate parameters
+
+| Name | Type | Default | Description |
+|----------------------------------|----------|----------|-------------------------------------------------------|
+| `options` | `object` | | **Required** authentication request options object |
+| `options.getAuthChallengeUrl` | `string` | | **Required** authentication challenge GET request URL |
+| `options.postAuthTokenUrl` | `string` | | **Required** authentication token POST request URL |
+| `options.headers` | `object` | `{ }` | **Optional** HTTP request headers |
+| `options.userInteractionTimeout` | `number` | `120000` | **Optional** user interaction timeout in milliseconds |
+| `options.serverRequestTimeout` | `number` | `20000` | **Optional** server request timeout in milliseconds |
+
+**`AuthenticateOptions.getAuthChallengeUrl`**
+This URL should respond to a GET request with a cryptographic nonce.
+The request will be made by the browser extension.
+The extension will use this nonce to generate an authentication token.
+
+**`AuthenticateOptions.postAuthTokenUrl`**
+This URL should accept a JSON payload via a POST request which contains
+the authentication token generated by the browser extension.
+
+After the server validates the token,
+the server should respond with a 2xx status code and an optional JSON payload.
+
+If the provided token was invalid or the user should be forbidden access
+for a different reason, the server should respond with an appropriate
+HTTP error status code and an optional JSON payload.
+
+When this request succeeds or fails, the response, including the optional payload, will be part of the resolution or failure of the Promise which the `authenticate(...)` method returns.
+
+**`AuthenticateOptions.headers`**
+This optional field may contain additional HTTP headers which the browser extension will use while making the **auth challenge** and **auth token** requests.
+For example, this option can be used to specify authorization headers.
+
+#### Authenticate returns
+
+```ts
+Promise // HTTP response of the auth token POST request
+```
+```typescript
+interface HttpResponse {
+ // The HTTP request's response headers.
+ headers: Iterable<[string, string]>;
+
+ // A boolean indicating whether the response
+ ok: boolean;
+
+ // Indicates whether or not the response is the result of a redirect.
+ redirected: boolean;
+
+ // The status code of the response. (This will be 200 for a success).
+ status: number;
+
+ // The status message corresponding to the status code. (e.g., OK for 200).
+ statusText: string;
+
+ // The type of the response (e.g., basic, cors).
+ type: string;
+
+ // The URL of the response.
+ url: string;
+
+ // Response body. Can be an object deserialized from JSON or plain text.
+ body: object | string;
+}
+```
+
+#### Authenticate example - using async-await
+
+```js
+try {
+ const options = {
+ getAuthChallengeUrl: "/auth-challenge",
+ postAuthTokenUrl: "/auth-token",
+ };
+
+ const response = await webeid.authenticate(options);
+
+ // HANDLE SUCCESS
+
+} catch (error) {
+
+ // HANDLE FAILURE
+
+}
+```
+
+#### Authenticate example - using promises
+
+```js
+const options = {
+ getAuthChallengeUrl: "/auth/challenge",
+ postAuthTokenUrl: "/auth/token",
+};
+
+webeid.authenticate(options)
+.then((status) => { /* HANDLE SUCCESS */ })
+.catch((error) => { /* HANDLE FAILURE */ });
+```
+
+#### Authenticate example - success
+
+The result of a status check is the status object which contains SemVer strings for the library, browser extension and native application.
+
+```js
+{
+ // The body content is useful when authenticating in a SPA applications.
+ // The server can also send a 204 status with an empty response.
+ body: {
+ name: {
+ first: "John",
+ last: "Smith",
+ },
+ age: 20,
+ },
+
+ headers: {
+ "connection": "keep-alive",
+ "content-length": "49",
+ "content-type": "application/json; charset=utf-8",
+ "date": "Mon, 27 Apr 2020 06:28:54 GMT",
+ "etag": "W/\"30-YHV2nUGU912eoDvI+roJ2Yqn5SA\"",
+ "x-powered-by": "Express"
+ }
+
+ ok: true,
+ redirected: false,
+ status: 200,
+ statusText: "OK",
+ type: "basic",
+
+ // The server may chooses to redirect the request on the
+ // postAuthTokenUrl address. In case of one or more redirects
+ // the URL will be set to the last URL which finally gave an OK status.
+ url: "https://example.com/auth/token",
+}
+```
+
+#### Authenticate example - failure
+
+When the authenticate request fails, in addition to the usual `name`, `message` and `stack` properties, the error object contains additional info **when possible**.
+See [Known errors](#known-errors) for error `code` options.
+
+```js
+{
+ // Name of the Error object
+ name: "ServerRejectedError",
+
+ // Human readable message, meant for the developer
+ message: "server rejected the request",
+
+ // Programmatic error code, meant for error handling
+ code: "ERR_WEBEID_SERVER_REJECTED",
+
+ // The response object only exists when the server responded
+ // with a failure status code.
+ response: {
+ body: {
+ message: "Invalid token",
+ },
+
+ headers: {
+ "connection": "keep-alive",
+ "content-length": "25",
+ "content-type": "application/json; charset=utf-8",
+ "date": "Mon, 27 Apr 2020 06:28:54 GMT",
+ "etag": "W/\"30-YHV2nUGU912eoDvI+roJ2Yqn5SA\"",
+ "x-powered-by": "Express",
+ },
+
+ ok: false,
+ redirected: false,
+ status: 401,
+ statusText: "Unauthorized",
+ type: "basic",
+
+ url: "https://example.com/auth/token",
+ },
+
+ // Stack trace
+ "stack": ...
+}
+```
+
+
+### Sign
+
+```ts
+sign(options: SignOptions): Promise
+```
+Requests the Web-eID browser extension to sign a document hash.
+
+#### Sign parameters
+
+| Name | Type | Default | Description |
+|----------------------------------|----------|----------|-------------------------------------------------------|
+| `options` | `object` | | **Required** sign request options object |
+| `options.postPrepareSigningUrl` | `string` | | **Required** prepare signing POST request URL |
+| `options.postFinalizeSigningUrl` | `string` | | **Required** finalize signing POST request URL |
+| `options.headers` | `object` | `{ }` | **Optional** HTTP request headers |
+| `options.userInteractionTimeout` | `number` | `120000` | **Optional** user interaction timeout in milliseconds |
+| `options.serverRequestTimeout` | `number` | `20000` | **Optional** server request timeout in milliseconds |
+
+**`SignOptions.postPrepareSigningUrl`**
+During the signing process, a POST request will be made by the browser extension against the backend service using this URL to initiate preparations for document signing.
+
+The request body will have a JSON payload with `certificate` and `supportedSignatureAlgorithms` field which is provided by the browser extension.
+
+*Example request body:*
+```js
+{
+ // User's X.509 signing certificate
+ certificate: "MIIF2DCCA8CgAwIBAgIQVcAUfV...",
+
+ supportedSignatureAlgorithms: [
+ {
+ crypto: "ECC",
+ hash: "SHA-224",
+ padding: "NONE"
+ },
+ {
+ crypto: "ECC",
+ hash: "SHA-256",
+ padding: "NONE"
+ },
+ {
+ crypto: "ECC",
+ hash: "SHA-384",
+ padding: "NONE"
+ },
+ ...
+ ]
+}
+```
+
+Additional information about the request, for example the ID of the document to be signed, can be passed to the server via URL parameters.
+Furthermore, additional request headers, for example authentication and authorization tokens, can be specified using `SignOptions.headers`.
+
+The response must be a JSON object with `hash` and `algorithm` fields.
+Additional fields can be specified in the response, these fields will be passed on to the **finalize document** request by the browser extension.
+
+*Example response body:*
+```js
+{
+ // Base64-encoded document hash
+ hash: "iH7aF+AIAml46AgI2oYGcJzYzbg9JYFKR0oniGAZ7CkT8zVMx9JZtIelHezaOKyP",
+
+ // Hash algorithm from the supportedSignatureAlgorithms array
+ algorithm: "SHA-384",
+
+ // Optional arbitrary data for the finalize request
+ documentId: 123,
+ expires: "2020-10-20T00:00:00.000+0300"
+}
+```
+
+**`SignOptions.postFinalizeSigningUrl`**
+The browser extension will use this URL to make a POST request for which the backend service should finalize the signing process.
+
+The request body will have a JSON payload with the `signature` field. In addition, the payload includes the `hash`, `algorithm` and additional arbitrary fields provided by the server during the **prepare signing** request.
+
+*Example request body:*
+```js
+{
+ // Base64-encoded signature
+ signature: "O0vhA3XSflWsE/v0xcdLGPG0mbWHySSPXWJkRni8vklWKhlzWvGuHD98rWZzf31VsuldBlhJo9eflZvmKK/tUuTjiwXw2BLq3E+qv6Vs6nLHJNJs/ki6Lm/s+bwffyrH",
+
+ // Base64-encoded document hash from the prepare request's response
+ hash: "SHA-384",
+
+ // Hash algorithm from the prepare request's response
+ algorithm: "",
+
+ // Optional arbitrary data from the prepare request's response
+ documentId: 123,
+ expires: "2020-10-20T00:00:00.000+0300"
+}
+```
+
+When this request succeeds or fails, the response, including the optional payload, will be part of the resolution or failure of the Promise which the `sign(...)` method returns.
+
+**`SignOptions.headers`**
+This optional field may contain additional HTTP headers which the browser extension will use while making the **prepare** and **finalize** requests.
+For example, this option can be used to specify authorization headers.
+
+
+#### Sign returns
+
+```ts
+Promise // HTTP response of the finalize signing POST request
+```
+```typescript
+interface HttpResponse {
+ // The HTTP request's response headers.
+ headers: Iterable<[string, string]>;
+
+ // A boolean indicating whether the response
+ ok: boolean;
+
+ // Indicates whether or not the response is the result of a redirect.
+ redirected: boolean;
+
+ // The status code of the response. (This will be 200 for a success).
+ status: number;
+
+ // The status message corresponding to the status code. (e.g., OK for 200).
+ statusText: string;
+
+ // The type of the response (e.g., basic, cors).
+ type: string;
+
+ // The URL of the response.
+ url: string;
+
+ // Response body. Can be an object deserialized from JSON or plain text.
+ body: object | string;
+}
+```
+
+#### Sign example - using async-await
+
+```js
+try {
+ const options = {
+ postPrepareSigningUrl: "/document/123/sign/prepare",
+ postFinalizeSigningUrl: "/document/123/sign/finalize",
+ };
+
+ const response = await webeid.sign(options);
+
+ // HANDLE SUCCESS
+
+} catch (error) {
+
+ // HANDLE FAILURE
+
+}
+```
+
+#### Sign example - using promises
+
+```js
+const options = {
+ postPrepareSigningUrl: "/document/123/sign/prepare",
+ postFinalizeSigningUrl: "/document/123/sign/finalize",
+};
+
+webeid.sign(options)
+.then((status) => { /* HANDLE SUCCESS */ })
+.catch((error) => { /* HANDLE FAILURE */ });
+```
+
+#### Sign example - success
+
+The result of a status check is the status object which contains SemVer strings for the library, browser extension and native application.
+
+```js
+{
+ // The body content is useful when signing in a SPA applications.
+ // The server can also send a 204 status with an empty response.
+ body: {
+ documentId: "123"
+ },
+
+ headers: {
+ "content-length": "20",
+ "content-type": "application/json; charset=utf-8",
+ "date": "Thu, 10 Sep 2020 18:28:12 GMT",
+ "etag": "W/\"14-jy7dMclQhztcZaNKkjCj7ZOnAXw\"",
+ "x-firefox-spdy": "h2",
+ "x-powered-by": "Express"
+ },
+
+ ok: true,
+ redirected: false,
+ status: 200,
+ statusText: "OK",
+ type: "basic",
+
+ // The server may chooses to redirect the request on the
+ // postFinalizeSigningUrl address. In case of one or more redirects
+ // the URL will be set to the last URL which finally gave an OK status.
+ url: "https://example.com/document/123/sign/finalize"
+}
+```
+
+#### Sign example - failure
+
+When the signing request fails, in addition to the usual `name`, `message` and `stack` properties, the error object contains additional info **when possible**.
+See [Known errors](#known-errors) for error `code` options.
+
+```js
+{
+ // Name of the Error object
+ name: "ServerRejectedError"
+
+ // Human readable message, meant for the developer
+ message: "server rejected the request"
+
+ // Programmatic error code, meant for error handling
+ code: "ERR_WEBEID_SERVER_REJECTED"
+
+ // The response object only exists when the server responded
+ // with a failure status code.
+ response: {
+ body: {
+ message: "Prepared document hash doesn't match"
+ },
+
+ headers: {
+ "content-length": "50",
+ "content-type": "application/json; charset=utf-8",
+ "date": "Thu, 10 Sep 2020 18:34:26 GMT",
+ "etag": "W/\"32-irPE0oVZ8Habt+b+xMX5wvxwCkk\"",
+ "x-firefox-spdy": "h2",
+ "x-powered-by": "Express"
+ },
+
+ ok: false,
+ redirected: false,
+ status: 400,
+ statusText: "Bad Request",
+ type: "basic",
+
+ url: "https://example.com/document/234/sign/finalize"
+ }
+
+ // Stack trace
+ "stack": ...
+}
+```
+
+## Known errors
+
+There are several known errors that you can catch for the purpose of displaying more helpful error messages to the user.
+Errors returned by the library should always have a `code` property which contains a programmatic error code.
+
+To avoid typos, you can use the `ErrorCode` enum.
+
+**Example**
+```ts
+try {
+ const response = await webeid.authenticate(options);
+
+ // HANDLE SUCCESS
+
+} catch (error) {
+ switch (error.code) {
+ case webeid.ErrorCode.ERR_WEBEID_SERVER_REJECTED: {
+ // It's possible to check the response status code or body here
+ if (error.response?.status === 401) {
+ showError(error.response.body.message);
+
+ } else if (error.response?.status === 503)
+ showError(
+ "Authentication is disabled while we are " +
+ "performing routine maintenance, try again in 10 minutes!"
+ );
+
+ } else {
+ showError(
+ "Authentication failed, " +
+ "please check your credentials and try again!"
+ );
+
+ }
+ break;
+ }
+
+ case webeid.ErrorCode.ERR_WEBEID_USER_TIMEOUT: {
+ showError("Authentication timed out, please try again!");
+ break;
+ }
+
+ default: {
+ showError(
+ "An unknown error occurred. " +
+ "Please try again and contact support if the problem persists!"
+ )
+ }
+ }
+}
+```
+
+#### Error codes
+
+##### Timeout errors
+
+- **`ERR_WEBEID_ACTION_TIMEOUT`**
+ - **Thrown when:** The browser extension has accepted a task, replying to an action with an acknowledge message, but failed to reply reply with a success or failure message in time.
+ - **Likely reason:** Should not happen.
+ - **How to resolve:** Report a bug.
+
+- **`ERR_WEBEID_USER_TIMEOUT`**
+ - **Thrown when:** User interaction timed out.
+ - **Likely reason:** User failed to enter a PIN code. In addition, the user did not cancel PIN entry.
+ - **How to resolve:** The user may try again. The user interaction timeout is configurable, see [Authenticate](#authenticate) and [Sign](#sign) for details.
+
+- **`ERR_WEBEID_SERVER_TIMEOUT`**
+ - **Thrown when:** Server request timed out.
+ - **Likely reason:** Server failed to respond in a given time.
+ - **How to resolve:** The server may be busy. The server request timeout is configurable, see [Authenticate](#authenticate) and [Sign](#sign) for details.
+
+##### Health errors
+
+- **`ERR_WEBEID_VERSION_MISMATCH`**
+ - **Thrown when:** The browser extension and/or native application versions are not matching.
+ - **Likely reason:** Either the browser extension or the native application or both, require an update
+ - **How to resolve:** An additional object `requiresUpdate` might be attached to the error object.
+ The user can be instructed to update the required component.
+
+ ```js
+ try {
+ const status = webeid.status();
+ ...
+ } catch (error) {
+ if (error?.code === "ERR_WEBEID_VERSION_MISMATCH") {
+ if (error.requiresUpdate?.extension) {
+ // Web eID browser extension needs to be updated
+ }
+
+ if (error.requiresUpdate?.nativeApp) {
+ // Web eID native application needs to be updated
+ }
+ }
+ }
+ ```
+
+- **`ERR_WEBEID_VERSION_INVALID`**
+ - **Thrown when:** The native application did not provide a valid version string during handshake.
+ - **Likely reason:** Should not happen.
+ - **How to resolve:** Report a bug.
+
+- **`ERR_WEBEID_EXTENSION_UNAVAILABLE`**
+ - **Thrown when:** The browser extension fails during the handshake step and does not respond to an action message with a matching acknowledge message.
+ - **Likely reason:** The browser extension is not installed.
+ - **How to resolve:** The user can be instructed to install the Web eID browser extension.
+
+- **`ERR_WEBEID_NATIVE_UNAVAILABLE`**
+ - **Thrown when:** The native application fails during the handshake step.
+ - **Likely reason:** The browser extension is not installed.
+ - **How to resolve:** The user can be instructed to install the Web eID native application.
+
+- **`ERR_WEBEID_UNKNOWN_ERROR`**
+ - **Thrown when:** An unknown error occurs.
+ - **Likely reason:** Should not happen.
+ - **How to resolve:** Report a bug.
+
+##### Security errors
+- **`ERR_WEBEID_CONTEXT_INSECURE`**
+ - **Thrown when:** The library is used from an insecure context.
+ - **Likely reason:** See [https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts)
+ - **How to resolve:** Use HTTPS.
+
+- **`ERR_WEBEID_PROTOCOL_INSECURE`**
+ - **Thrown when:** A provided URL does not start with `https:`.
+ - **Likely reason:** getAuthChallengeUrl or postAuthTokenUrl options are missing a secure protocol.
+ - **How to resolve:** Use HTTPS.
+
+- **`ERR_WEBEID_TLS_CONNECTION_BROKEN`**
+ - **Thrown when:** There's an issue with the TLS connection.
+ - **Likely reason:** The TLS handshake failed (for example, the certificate had expired)
+ - **How to resolve:** Check the website certificate.
+
+- **`ERR_WEBEID_TLS_CONNECTION_INSECURE`**
+ - **Thrown when:** There's an issue with the TLS connection.
+ - **Likely reason:** The connection is not a TLS connection.
+ - **How to resolve:** Check the website certificate.
+
+- **`ERR_WEBEID_TLS_CONNECTION_WEAK`**
+ - **Thrown when:** There's an issue with the TLS connection.
+ - **Likely reason:** The connection is a TLS connection but is considered weak. Most likely the negotiated cipher suite is considered weak.
+ - **How to resolve:** Check the website certificate.
+
+- **`ERR_WEBEID_CERTIFICATE_CHANGED`**
+ - **Thrown when:** Certificate fingerprint changed between requests during the same operation.
+ - **Likely reason:** Either a man-in-the-middle attack attempt or the website changed certificate between requests.
+ - **How to resolve:** Log the incident and instruct the user to try again.
+
+- **`ERR_WEBEID_ORIGIN_MISMATCH`**
+ - **Thrown when:** Origins of provide URLs mismatch for an operation.
+ - **Likely reason:** The URLs provided in `authenticate` or `sign` method options were not using the same origin (protocol, domain and port). Either a developer mistake or an XSS attack attempt.
+ - **How to resolve:** Make sure the same origin is used. Log the incident and instruct the user to try again.
+
+##### Third party errors
+- **`ERR_WEBEID_SERVER_REJECTED`**
+ - **Thrown when:** The server replies, but with an HTTP error status code (400 or greater).
+ - **Likely reason:** User not authorized, server rejects document signing or other server error.
+ - **How to resolve:** This error should include the `response` object that might provide the necessary details.
+
+ ```js
+ try {
+ const response = webeid.authenticate(options);
+ ...
+ } catch (error) {
+ if (error?.code === "ERR_WEBEID_SERVER_REJECTED") {
+ if (error.response?.status === 401) {
+ // Authorization has been refused
+ }
+ }
+ }
+ ```
+
+- **`ERR_WEBEID_USER_CANCELLED`**
+ - **Thrown when:** User cancelled the current operation.
+ - **Likely reason:** User closed the certificate selection, pin entry or similar user interaction dialog.
+ - **How to resolve:** Respect the user's wishes.
+
+- **`ERR_WEBEID_NATIVE_FATAL`**
+ - **Thrown when:** Native application terminated with a fatal error.
+ - **Likely reason:** The native application was in an unrecoverable state. For example, the card reader might have been malfunctioning.
+ - **How to resolve:** Log the incident and instruct the user to try again. Inspect the error object's `nativeException` attribute for details.
+
+##### Developer mistakes
+- **`ERR_WEBEID_ACTION_PENDING`**
+ - **Thrown when:** An action of the same type is already pending.
+ - **Likely reason:** The user is allowed to initiate actions multiple times without waiting for their resolution.
+ - **How to resolve:** Make sure to disable buttons which trigger actions until the action is resolved.
+
+ ```js
+ authenticateButton.disabled = true;
+
+ try {
+ const response = await authenticate(options);
+ ...
+ } catch (error) {
+ ...
+ } finally {
+ authenticateButton.disabled = false;
+ }
+ ```
+
+- **`ERR_WEBEID_MISSING_PARAMETER`**
+ - **Thrown when:** Required parameter was missing.
+ - **Likely reason:** While calling a library function, a required parameter was not provided.
+ - **How to resolve:** The error message might contain helpful hints on what was missing. Check the documentation.
+
+
+## Development
+
+**You are welcome to create pull requests for the Web-eID library!**
+
+- Make sure your code editor takes advantage of the `.editorconfig` file.
+ It lets your code editor know what the basic formatting rules for this project should be.
+ See: [https://editorconfig.org](https://editorconfig.org)
+- Run `npm install` to install dependencies.
+- Run `npm run lint` before making a pull request.
+- Run `npm run build` to build compile the project and generate bundles.
+ The build process will run the following commands in sequence.
+
+ | Command | Description |
+ |-|-|
+ | `npm run clean` | Removes the `./dist` directory. |
+ | `npm run compile` | Runs the TypeScript compiler, generates: `./dist/node` |
+ | `npm run bundle` | Runs the Rollup bundler, generates: `./dist/es` `./dist/iife` `./dist/umd`|
+
+
+### Testing changes locally
+
+When you've made changes to the library and wish to test the behavior within another project, there are a couple of ways to do it.
+
+
+#### Using `npm link`
+
+You can use `npm link` to link the Web-eID library source directory to a another project.
+
+**Example**
+```bash
+cd ~/workspace/web-eid-library
+npm run build
+
+cd ~/workspace/example-website
+npm link ~/workspace/web-eid-library
+```
+
+**Pros**
+- This option might be more convenient for active development.
+- After making changes to the Web-eID library source and rebuilding the library project, you don't need to reinstall the dependency in your other project.
+
+**Cons**
+- ES modules are located at `web-eid/dist/node/` instead of directly under `web-eid/`.
+ ```ts
+ import AuthenticateOptions from 'web-eid/dist/node/models/AuthenticateOptions';
+ ```
+
+#### Using `npm pack`
+
+You can use `npm pack` to generate a package and install the package archive.
+
+**Example**
+```bash
+cd ~/workspace/web-eid-library
+npm run build
+npm package
+
+cd ~/workspace/example-website
+npm install ~/workspace/web-eid-library/web-eid-*.tgz
+```
+
+**Pros**
+- Accurately simulates a installing from the NPM repository.
+- Shorter import path.
+ ```ts
+ import AuthenticateOptions from 'web-eid/models/AuthenticateOptions';
+ ```
+
+**Cons**
+- After making changes to the library, you need to rebuild the package and reinstall the library as a dependency.
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..248f0a2
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1246 @@
+{
+ "name": "@web-eid/web-eid-library",
+ "version": "0.9.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+ "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.8.3"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
+ "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.0",
+ "esutils": "^2.0.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@types/eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
+ "dev": true
+ },
+ "@types/json-schema": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
+ "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==",
+ "dev": true
+ },
+ "@typescript-eslint/eslint-plugin": {
+ "version": "2.19.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.19.2.tgz",
+ "integrity": "sha512-HX2qOq2GOV04HNrmKnTpSIpHjfl7iwdXe3u/Nvt+/cpmdvzYvY0NHSiTkYN257jHnq4OM/yo+OsFgati+7LqJA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/experimental-utils": "2.19.2",
+ "eslint-utils": "^1.4.3",
+ "functional-red-black-tree": "^1.0.1",
+ "regexpp": "^3.0.0",
+ "tsutils": "^3.17.1"
+ }
+ },
+ "@typescript-eslint/experimental-utils": {
+ "version": "2.19.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.2.tgz",
+ "integrity": "sha512-B88QuwT1wMJR750YvTJBNjMZwmiPpbmKYLm1yI7PCc3x0NariqPwqaPsoJRwU9DmUi0cd9dkhz1IqEnwfD+P1A==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.3",
+ "@typescript-eslint/typescript-estree": "2.19.2",
+ "eslint-scope": "^5.0.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "2.19.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.19.2.tgz",
+ "integrity": "sha512-8uwnYGKqX9wWHGPGdLB9sk9+12sjcdqEEYKGgbS8A0IvYX59h01o8os5qXUHMq2na8vpDRaV0suTLM7S8wraTA==",
+ "dev": true,
+ "requires": {
+ "@types/eslint-visitor-keys": "^1.0.0",
+ "@typescript-eslint/experimental-utils": "2.19.2",
+ "@typescript-eslint/typescript-estree": "2.19.2",
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "2.19.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.2.tgz",
+ "integrity": "sha512-Xu/qa0MDk6upQWqE4Qy2X16Xg8Vi32tQS2PR0AvnT/ZYS4YGDvtn2MStOh5y8Zy2mg4NuL06KUHlvCh95j9C6Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "eslint-visitor-keys": "^1.1.0",
+ "glob": "^7.1.6",
+ "is-glob": "^4.0.1",
+ "lodash": "^4.17.15",
+ "semver": "^6.3.0",
+ "tsutils": "^3.17.1"
+ }
+ },
+ "acorn": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
+ "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
+ "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==",
+ "dev": true
+ },
+ "ajv": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
+ "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-escapes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
+ "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.8.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^3.1.0"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
+ "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.10.0",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^1.4.3",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.2",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.0.0",
+ "globals": "^12.1.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^7.0.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.14",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.3",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^6.1.2",
+ "strip-ansi": "^5.2.0",
+ "strip-json-comments": "^3.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "dependencies": {
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+ "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+ "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+ "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+ "dev": true
+ },
+ "espree": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz",
+ "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.0",
+ "acorn-jsx": "^5.1.0",
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz",
+ "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.0.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "estree-walker": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
+ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "figures": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz",
+ "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "flatted": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
+ "dev": true
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+ "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "globals": {
+ "version": "12.3.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
+ "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.8.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+ "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz",
+ "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^2.4.2",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.15",
+ "mute-stream": "0.0.8",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.5.3",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^5.1.0",
+ "through": "^2.3.6"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz",
+ "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==",
+ "dev": true,
+ "requires": {
+ "merge-stream": "^2.0.0",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+ "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "regexpp": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz",
+ "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==",
+ "dev": true
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "rollup": {
+ "version": "2.26.11",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.26.11.tgz",
+ "integrity": "sha512-xyfxxhsE6hW57xhfL1I+ixH8l2bdoIMaAecdQiWF3N7IgJEMu99JG+daBiSZQjnBpzFxa0/xZm+3pbCdAQehHw==",
+ "dev": true,
+ "requires": {
+ "fsevents": "~2.1.2"
+ }
+ },
+ "rollup-plugin-terser": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz",
+ "integrity": "sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.5.5",
+ "jest-worker": "^24.9.0",
+ "rollup-pluginutils": "^2.8.2",
+ "serialize-javascript": "^4.0.0",
+ "terser": "^4.6.2"
+ }
+ },
+ "rollup-pluginutils": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+ "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
+ "dev": true,
+ "requires": {
+ "estree-walker": "^0.6.1"
+ }
+ },
+ "run-async": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+ "dev": true,
+ "requires": {
+ "is-promise": "^2.1.0"
+ }
+ },
+ "rxjs": {
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
+ "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ }
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ }
+ }
+ },
+ "terser": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
+ "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.20.0",
+ "source-map": "~0.6.1",
+ "source-map-support": "~0.5.12"
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "tslib": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
+ "dev": true
+ },
+ "tsutils": {
+ "version": "3.17.1",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
+ "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
+ "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "v8-compile-cache": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
+ "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..76ff2f0
--- /dev/null
+++ b/package.json
@@ -0,0 +1,50 @@
+{
+ "name": "@web-eid/web-eid-library",
+ "version": "0.9.0",
+ "description": "",
+ "scripts": {
+ "lint": "eslint . --ext .ts",
+ "build": "npm run clean && npm run compile && npm run bundle",
+ "clean": "rimraf ./dist",
+ "compile": "tsc",
+ "bundle": "rollup -c",
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "prepare": "npm run build",
+ "prepack": "cp -R ./dist/node/* ./",
+ "postpack": "rimraf ./web-eid.js ./config.js ./errors ./models ./services ./utils ./*.d.ts ./*.map"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git@gitlab.com:web-eid/webextension/web-eid-library.git"
+ },
+ "files": [
+ "config.d.ts",
+ "config.d.ts.map",
+ "config.js",
+ "config.js.map",
+ "web-eid.d.ts",
+ "web-eid.d.ts.map",
+ "web-eid.js",
+ "web-eid.js.map",
+ "errors/**/*",
+ "models/**/*",
+ "services/**/*",
+ "utils/**/*",
+ "dist/es/*",
+ "dist/iife/*",
+ "dist/umd/*"
+ ],
+ "types": "web-eid.d.ts",
+ "author": "Tanel Metsar",
+ "license": "MIT",
+ "devDependencies": {
+ "@typescript-eslint/eslint-plugin": "^2.19.2",
+ "@typescript-eslint/parser": "^2.19.2",
+ "eslint": "^6.8.0",
+ "rimraf": "^3.0.2",
+ "rollup": "^2.26.11",
+ "rollup-plugin-terser": "^5.3.1",
+ "typescript": "^3.8.3"
+ },
+ "dependencies": {}
+}
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..a82916a
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,38 @@
+import { terser } from "rollup-plugin-terser";
+
+export default {
+ input: "./dist/node/web-eid.js",
+
+ output: [
+ {
+ file: "dist/iife/web-eid.js",
+ format: "iife",
+ name: "webeid",
+ sourcemap: true,
+ },
+ {
+ file: "dist/iife/web-eid.min.js",
+ format: "iife",
+ name: "webeid",
+ sourcemap: false,
+ plugins: [terser()],
+ },
+ {
+ file: "dist/umd/web-eid.js",
+ format: "umd",
+ name: "webeid",
+ sourcemap: true,
+ },
+ {
+ file: "dist/umd/web-eid.min.js",
+ format: "umd",
+ name: "webeid",
+ sourcemap: false,
+ plugins: [terser()],
+ },
+ {
+ file: "dist/es/web-eid.js",
+ format: "es",
+ },
+ ],
+};
diff --git a/src/config.ts b/src/config.ts
new file mode 100644
index 0000000..e6b5ea5
--- /dev/null
+++ b/src/config.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default Object.freeze({
+ VERSION: "0.9.0",
+ EXTENSION_HANDSHAKE_TIMEOUT: 1000, // 1 second
+ NATIVE_APP_HANDSHAKE_TIMEOUT: 5 * 1000, // 5 seconds
+ DEFAULT_USER_INTERACTION_TIMEOUT: 2 * 60 * 1000, // 2 minutes
+ DEFAULT_SERVER_REQUEST_TIMEOUT: 20 * 1000, // 20 seconds
+});
diff --git a/src/errors/ActionPendingError.ts b/src/errors/ActionPendingError.ts
new file mode 100644
index 0000000..b266570
--- /dev/null
+++ b/src/errors/ActionPendingError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class ActionPendingError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "same action for Web-eID browser extension is already pending") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_ACTION_PENDING;
+ }
+}
diff --git a/src/errors/ActionTimeoutError.ts b/src/errors/ActionTimeoutError.ts
new file mode 100644
index 0000000..301f6e7
--- /dev/null
+++ b/src/errors/ActionTimeoutError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class ActionTimeoutError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "extension message timeout") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_ACTION_TIMEOUT;
+ }
+}
diff --git a/src/errors/CertificateChangedError.ts b/src/errors/CertificateChangedError.ts
new file mode 100644
index 0000000..2ccf493
--- /dev/null
+++ b/src/errors/CertificateChangedError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class CertificateChangedError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "server certificate changed between requests") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_CERTIFICATE_CHANGED;
+ }
+}
diff --git a/src/errors/ContextInsecureError.ts b/src/errors/ContextInsecureError.ts
new file mode 100644
index 0000000..26789ac
--- /dev/null
+++ b/src/errors/ContextInsecureError.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+const SECURE_CONTEXTS_INFO_URL = "https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts";
+
+export default class ContextInsecureError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "Secure context required, see " + SECURE_CONTEXTS_INFO_URL) {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_CONTEXT_INSECURE;
+ }
+}
diff --git a/src/errors/ErrorCode.ts b/src/errors/ErrorCode.ts
new file mode 100644
index 0000000..a8545d4
--- /dev/null
+++ b/src/errors/ErrorCode.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+enum ErrorCode {
+ // Timeout errors
+ ERR_WEBEID_ACTION_TIMEOUT = "ERR_WEBEID_ACTION_TIMEOUT",
+ ERR_WEBEID_USER_TIMEOUT = "ERR_WEBEID_USER_TIMEOUT",
+ ERR_WEBEID_SERVER_TIMEOUT = "ERR_WEBEID_SERVER_TIMEOUT",
+
+ // Health errors
+ ERR_WEBEID_VERSION_MISMATCH = "ERR_WEBEID_VERSION_MISMATCH",
+ ERR_WEBEID_VERSION_INVALID = "ERR_WEBEID_VERSION_INVALID",
+ ERR_WEBEID_EXTENSION_UNAVAILABLE = "ERR_WEBEID_EXTENSION_UNAVAILABLE",
+ ERR_WEBEID_NATIVE_UNAVAILABLE = "ERR_WEBEID_NATIVE_UNAVAILABLE",
+ ERR_WEBEID_UNKNOWN_ERROR = "ERR_WEBEID_UNKNOWN_ERROR",
+
+ // Security errors
+ ERR_WEBEID_CONTEXT_INSECURE = "ERR_WEBEID_CONTEXT_INSECURE",
+ ERR_WEBEID_PROTOCOL_INSECURE = "ERR_WEBEID_PROTOCOL_INSECURE",
+ ERR_WEBEID_TLS_CONNECTION_BROKEN = "ERR_WEBEID_TLS_CONNECTION_BROKEN",
+ ERR_WEBEID_TLS_CONNECTION_INSECURE = "ERR_WEBEID_TLS_CONNECTION_INSECURE",
+ ERR_WEBEID_TLS_CONNECTION_WEAK = "ERR_WEBEID_TLS_CONNECTION_WEAK",
+ ERR_WEBEID_CERTIFICATE_CHANGED = "ERR_WEBEID_CERTIFICATE_CHANGED",
+ ERR_WEBEID_ORIGIN_MISMATCH = "ERR_WEBEID_ORIGIN_MISMATCH",
+
+ // Third party errors
+ ERR_WEBEID_SERVER_REJECTED = "ERR_WEBEID_SERVER_REJECTED",
+ ERR_WEBEID_USER_CANCELLED = "ERR_WEBEID_USER_CANCELLED",
+ ERR_WEBEID_NATIVE_FATAL = "ERR_WEBEID_NATIVE_FATAL",
+
+ // Developer mistakes
+ ERR_WEBEID_ACTION_PENDING = "ERR_WEBEID_ACTION_PENDING",
+ ERR_WEBEID_MISSING_PARAMETER = "ERR_WEBEID_MISSING_PARAMETER",
+}
+
+export default ErrorCode;
diff --git a/src/errors/ExtensionUnavailableError.ts b/src/errors/ExtensionUnavailableError.ts
new file mode 100644
index 0000000..5115a27
--- /dev/null
+++ b/src/errors/ExtensionUnavailableError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class ExtensionUnavailableError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "Web-eID extension is not available") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_EXTENSION_UNAVAILABLE;
+ }
+}
diff --git a/src/errors/MissingParameterError.ts b/src/errors/MissingParameterError.ts
new file mode 100644
index 0000000..5ff3461
--- /dev/null
+++ b/src/errors/MissingParameterError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class MissingParameterError extends Error {
+ public code: ErrorCode;
+
+ constructor(message: string) {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_MISSING_PARAMETER;
+ }
+}
diff --git a/src/errors/NativeFatalError.ts b/src/errors/NativeFatalError.ts
new file mode 100644
index 0000000..f56aa30
--- /dev/null
+++ b/src/errors/NativeFatalError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class NativeFatalError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "native application terminated with a fatal error") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_NATIVE_FATAL;
+ }
+}
diff --git a/src/errors/NativeUnavailableError.ts b/src/errors/NativeUnavailableError.ts
new file mode 100644
index 0000000..8bf6ff3
--- /dev/null
+++ b/src/errors/NativeUnavailableError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class NativeUnavailableError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "Web-eID native application is not available") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_NATIVE_UNAVAILABLE;
+ }
+}
diff --git a/src/errors/OriginMismatchError.ts b/src/errors/OriginMismatchError.ts
new file mode 100644
index 0000000..1501dda
--- /dev/null
+++ b/src/errors/OriginMismatchError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class OriginMismatchError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "URLs for a single operation require the same origin") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_ORIGIN_MISMATCH;
+ }
+}
diff --git a/src/errors/ProtocolInsecureError.ts b/src/errors/ProtocolInsecureError.ts
new file mode 100644
index 0000000..666a703
--- /dev/null
+++ b/src/errors/ProtocolInsecureError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class ProtocolInsecureError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "HTTPS required") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_PROTOCOL_INSECURE;
+ }
+}
diff --git a/src/errors/ServerRejectedError.ts b/src/errors/ServerRejectedError.ts
new file mode 100644
index 0000000..ccd3667
--- /dev/null
+++ b/src/errors/ServerRejectedError.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class ServerRejectedError extends Error {
+ public code: ErrorCode;
+ public response?: Response;
+
+ constructor(message = "server rejected the request") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_SERVER_REJECTED;
+ }
+}
diff --git a/src/errors/ServerTimeoutError.ts b/src/errors/ServerTimeoutError.ts
new file mode 100644
index 0000000..f310d64
--- /dev/null
+++ b/src/errors/ServerTimeoutError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class ServerTimeoutError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "server failed to respond in time") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_SERVER_TIMEOUT;
+ }
+}
diff --git a/src/errors/TlsConnectionBrokenError.ts b/src/errors/TlsConnectionBrokenError.ts
new file mode 100644
index 0000000..ad98c3a
--- /dev/null
+++ b/src/errors/TlsConnectionBrokenError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class TlsConnectionBrokenError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "TLS connection was broken") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_TLS_CONNECTION_BROKEN;
+ }
+}
diff --git a/src/errors/TlsConnectionInsecureError.ts b/src/errors/TlsConnectionInsecureError.ts
new file mode 100644
index 0000000..9e2d739
--- /dev/null
+++ b/src/errors/TlsConnectionInsecureError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class TlsConnectionInsecureError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "TLS connection was insecure") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_TLS_CONNECTION_INSECURE;
+ }
+}
diff --git a/src/errors/TlsConnectionWeakError.ts b/src/errors/TlsConnectionWeakError.ts
new file mode 100644
index 0000000..d06d2f9
--- /dev/null
+++ b/src/errors/TlsConnectionWeakError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class TlsConnectionWeakError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "TLS connection was weak") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_TLS_CONNECTION_WEAK;
+ }
+}
diff --git a/src/errors/UnknownError.ts b/src/errors/UnknownError.ts
new file mode 100644
index 0000000..7144468
--- /dev/null
+++ b/src/errors/UnknownError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class UnknownError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "an unknown error occurred") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_UNKNOWN_ERROR;
+ }
+}
diff --git a/src/errors/UserCancelledError.ts b/src/errors/UserCancelledError.ts
new file mode 100644
index 0000000..b8d86c8
--- /dev/null
+++ b/src/errors/UserCancelledError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class UserCancelledError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "request was cancelled by the user") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_USER_CANCELLED;
+ }
+}
diff --git a/src/errors/UserTimeoutError.ts b/src/errors/UserTimeoutError.ts
new file mode 100644
index 0000000..1c637f0
--- /dev/null
+++ b/src/errors/UserTimeoutError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class UserTimeoutError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "user failed to respond in time") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_USER_TIMEOUT;
+ }
+}
diff --git a/src/errors/VersionInvalidError.ts b/src/errors/VersionInvalidError.ts
new file mode 100644
index 0000000..98c916c
--- /dev/null
+++ b/src/errors/VersionInvalidError.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+
+export default class VersionInvalidError extends Error {
+ public code: ErrorCode;
+
+ constructor(message = "invalid version string") {
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_VERSION_INVALID;
+ }
+}
diff --git a/src/errors/VersionMismatchError.ts b/src/errors/VersionMismatchError.ts
new file mode 100644
index 0000000..d4d4c58
--- /dev/null
+++ b/src/errors/VersionMismatchError.ts
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import ErrorCode from "./ErrorCode";
+import Versions from "../models/Versions";
+import RequiresUpdate from "../models/RequiresUpdate";
+
+function tmpl(strings: TemplateStringsArray, requiresUpdate: string): string {
+ return `Update required for Web-eID ${requiresUpdate}`;
+}
+
+export default class VersionMismatchError extends Error {
+ public requiresUpdate: RequiresUpdate;
+ public code: ErrorCode;
+ public versions?: Versions;
+ public nativeApp?: string;
+ public extension?: string;
+ public library?: string;
+
+ constructor(message: string | undefined, versions: Versions, requiresUpdate: RequiresUpdate) {
+ if (!message) {
+ if (!requiresUpdate) {
+ message = "requiresUpdate not provided";
+ } else if (requiresUpdate.extension && requiresUpdate.nativeApp) {
+ message = tmpl`${"extension and native app"}`;
+ } else if (requiresUpdate.extension) {
+ message = tmpl`${"extension"}`;
+ } else if (requiresUpdate.nativeApp) {
+ message = tmpl`${"native app"}`;
+ }
+ }
+
+ super(message);
+
+ this.name = this.constructor.name;
+ this.code = ErrorCode.ERR_WEBEID_VERSION_MISMATCH;
+ this.requiresUpdate = requiresUpdate;
+
+ if (versions) {
+ const { library, extension, nativeApp } = versions;
+
+ Object.assign(this, { library, extension, nativeApp });
+ }
+ }
+}
diff --git a/src/models/Action.ts b/src/models/Action.ts
new file mode 100644
index 0000000..0d6f0cd
--- /dev/null
+++ b/src/models/Action.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+enum Action {
+ STATUS = "web-eid:status",
+ STATUS_ACK = "web-eid:status-ack",
+ STATUS_SUCCESS = "web-eid:status-success",
+ STATUS_FAILURE = "web-eid:status-failure",
+
+ AUTHENTICATE = "web-eid:authenticate",
+ AUTHENTICATE_ACK = "web-eid:authenticate-ack",
+ AUTHENTICATE_SUCCESS = "web-eid:authenticate-success",
+ AUTHENTICATE_FAILURE = "web-eid:authenticate-failure",
+
+ SIGN = "web-eid:sign",
+ SIGN_ACK = "web-eid:sign-ack",
+ SIGN_SUCCESS = "web-eid:sign-success",
+ SIGN_FAILURE = "web-eid:sign-failure",
+}
+
+export default Action;
diff --git a/src/models/AuthenticateOptions.ts b/src/models/AuthenticateOptions.ts
new file mode 100644
index 0000000..3c161b3
--- /dev/null
+++ b/src/models/AuthenticateOptions.ts
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default interface AuthenticateOptions {
+ /**
+ * Authentication challenge GET request URL
+ *
+ * This URL should respond to a GET request with a cryptographic nonce.
+ * The request will be made by the browser extension. The extension will
+ * use this nonce to generate an authentication token.
+ *
+ * @example
+ * // Example response from the server
+ * {"nonce": ""}
+ */
+ getAuthChallengeUrl: string;
+
+ /**
+ * Authentication token POST request URL
+ *
+ * This URL should accept a JSON payload via a POST request which contains
+ * the authentication token generated by the browser extension.
+ *
+ * After the server validates the token,the server should respond
+ * with a 2xx status code and an optional JSON payload.
+ *
+ * If the provided token was invalid or the user should be forbidden access
+ * for a different reason, the server should respond with an appropriate
+ * HTTP error status code and an optional JSON payload.
+ *
+ * The authenticate method will resolve or reject with
+ * the optional JSON payload if the server chooses to provide it.
+ *
+ * @example
+ * // Example request payload
+ * {"token": ""}
+ */
+ postAuthTokenUrl: string;
+
+ /**
+ * Headers to append to the requests.
+ */
+ headers?: {
+ [key: string]: string;
+ };
+
+ /**
+ * Time in milliseconds before a user interaction, for example PIN entry, times out.
+ *
+ * When not specified, defaults to 2 minutes.
+ */
+ userInteractionTimeout?: number;
+
+ /**
+ * Time in milliseconds before a server request, for example auth challenge request, times out.
+ *
+ * When not specified, defaults to 20 seconds.
+ */
+ serverRequestTimeout?: number;
+}
diff --git a/src/models/HttpResponse.ts b/src/models/HttpResponse.ts
new file mode 100644
index 0000000..ca124e7
--- /dev/null
+++ b/src/models/HttpResponse.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default interface HttpResponse {
+ /**
+ * The HTTP request's response headers.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Response/headers
+ */
+ headers: object;
+
+ /**
+ * A boolean indicating whether the response
+ * was successful (status in the range 200–299) or not.
+ */
+ ok: boolean;
+
+ /**
+ * Indicates whether or not the response is the result of a redirect.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Response/redirected
+ */
+ redirected: boolean;
+
+ /**
+ * The status code of the response. (This will be 200 for a success).
+ */
+ status: number;
+
+ /**
+ * The status message corresponding to the status code. (e.g., OK for 200).
+ */
+ statusText: string;
+
+ /**
+ * The type of the response (e.g., basic, cors).
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Response/type
+ */
+ type: string;
+
+ /**
+ * The URL of the response.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Response/url
+ */
+ url: string;
+
+ /**
+ * Response body. Can be an object deserialized from JSON or plain text.
+ */
+ body: object | string;
+}
diff --git a/src/models/Message.ts b/src/models/Message.ts
new file mode 100644
index 0000000..7e4158d
--- /dev/null
+++ b/src/models/Message.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default interface Message {
+ action: string;
+
+ [key: string]: any;
+}
diff --git a/src/models/PendingMessage.ts b/src/models/PendingMessage.ts
new file mode 100644
index 0000000..215449e
--- /dev/null
+++ b/src/models/PendingMessage.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Message from "./Message";
+
+export default interface PendingMessage {
+ message: Message;
+ promise?: Promise;
+ resolve?: Function;
+ reject?: Function;
+ ackTimer?: number;
+ replyTimer?: number;
+}
diff --git a/src/models/RequiresUpdate.ts b/src/models/RequiresUpdate.ts
new file mode 100644
index 0000000..e06b7d7
--- /dev/null
+++ b/src/models/RequiresUpdate.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default interface RequiresUpdate {
+ nativeApp: boolean;
+ extension: boolean;
+}
diff --git a/src/models/ResponseAuthenticateFailure.ts b/src/models/ResponseAuthenticateFailure.ts
new file mode 100644
index 0000000..17a791c
--- /dev/null
+++ b/src/models/ResponseAuthenticateFailure.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Message from "./Message";
+import HttpResponse from "./HttpResponse";
+
+export default interface ResponseAuthenticateFailure extends Message {
+ code: string;
+ response?: HttpResponse;
+}
diff --git a/src/models/ResponseAuthenticateSuccess.ts b/src/models/ResponseAuthenticateSuccess.ts
new file mode 100644
index 0000000..0964c0b
--- /dev/null
+++ b/src/models/ResponseAuthenticateSuccess.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Message from "./Message";
+import HttpResponse from "./HttpResponse";
+
+export default interface ResponseAuthenticateSuccess extends Message {
+ response: HttpResponse;
+}
diff --git a/src/models/ResponseSignFailure.ts b/src/models/ResponseSignFailure.ts
new file mode 100644
index 0000000..9587c37
--- /dev/null
+++ b/src/models/ResponseSignFailure.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Message from "./Message";
+import HttpResponse from "./HttpResponse";
+
+export default interface ResponseSignFailure extends Message {
+ code: string;
+ response?: HttpResponse;
+}
diff --git a/src/models/ResponseSignSuccess.ts b/src/models/ResponseSignSuccess.ts
new file mode 100644
index 0000000..9fa6b95
--- /dev/null
+++ b/src/models/ResponseSignSuccess.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Message from "./Message";
+import HttpResponse from "./HttpResponse";
+
+export default interface ResponseSignSuccess extends Message {
+ response: HttpResponse;
+}
diff --git a/src/models/ResponseStatusFailure.ts b/src/models/ResponseStatusFailure.ts
new file mode 100644
index 0000000..5deefbb
--- /dev/null
+++ b/src/models/ResponseStatusFailure.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Message from "./Message";
+
+export default interface ResponseStatusFailure extends Message {
+ code: string;
+ message?: string;
+ extension: string;
+ nativeApp?: string;
+}
diff --git a/src/models/ResponseStatusSuccess.ts b/src/models/ResponseStatusSuccess.ts
new file mode 100644
index 0000000..4f2ac0c
--- /dev/null
+++ b/src/models/ResponseStatusSuccess.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Message from "./Message";
+
+export default interface ResponseStatusSuccess extends Message {
+ extension: string;
+ nativeApp: string;
+}
diff --git a/src/models/SignOptions.ts b/src/models/SignOptions.ts
new file mode 100644
index 0000000..b7ca2dc
--- /dev/null
+++ b/src/models/SignOptions.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default interface SignOptions {
+ /**
+ * Prepare document for signing POST request URL
+ *
+ * This request provides the signing certificate in the request body,
+ * the backend service should prepare the document for signing
+ * and return the document `hash` and `algorithm` of the hash, optionally arbitrary additional data.
+ */
+ postPrepareSigningUrl: string;
+
+ /**
+ * Signature POST request URL
+ *
+ * This request provides the document `hash`, `signature` and optionally additional data, the backend service should
+ * sign the document and optionally return any JSON payload to be returned by webeid.sign(...)
+ */
+ postFinalizeSigningUrl: string;
+
+ /**
+ * Headers to append to the requests.
+ */
+ headers?: {
+ [key: string]: string;
+ };
+
+ /**
+ * Time in milliseconds before a user interaction, for example PIN entry, times out.
+ *
+ * When not specified, defaults to 2 minutes.
+ */
+ userInteractionTimeout?: number;
+
+ /**
+ * Time in milliseconds before a server request, for example prepare signing request, times out.
+ *
+ * When not specified, defaults to 20 seconds.
+ */
+ serverRequestTimeout?: number;
+}
diff --git a/src/models/Versions.ts b/src/models/Versions.ts
new file mode 100644
index 0000000..ba57953
--- /dev/null
+++ b/src/models/Versions.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default interface Versions {
+ library: string;
+ nativeApp?: string;
+ extension?: string;
+}
diff --git a/src/services/WebExtensionService.ts b/src/services/WebExtensionService.ts
new file mode 100644
index 0000000..50a70c6
--- /dev/null
+++ b/src/services/WebExtensionService.ts
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import { deserializeError } from "../utils/errorSerializer";
+import config from "../config";
+import Message from "../models/Message";
+import PendingMessage from "../models/PendingMessage";
+import ActionPendingError from "../errors/ActionPendingError";
+import ActionTimeoutError from "../errors/ActionTimeoutError";
+import ContextInsecureError from "../errors/ContextInsecureError";
+import ExtensionUnavailableError from "../errors/ExtensionUnavailableError";
+
+export default class WebExtensionService {
+ private queue: PendingMessage[] = [];
+
+ constructor() {
+ window.addEventListener("message", (event) => this.receive(event));
+ }
+
+ private receive(event: { data: Message }): void {
+ const message = event.data;
+ const suffix = message.action?.match(/success$|failure$|ack$/)?.[0];
+ const initialAction = this.getInitialAction(message.action);
+ const pending = this.getPendingMessage(initialAction);
+
+ if (suffix === "ack") {
+ console.log("ack message", message);
+ console.log("ack pending", pending?.message.action);
+ console.log("ack queue", JSON.stringify(this.queue));
+ }
+
+ if (pending) {
+ switch (suffix) {
+ case "ack": {
+ clearTimeout(pending.ackTimer);
+
+ break;
+ }
+
+ case "success": {
+ pending.resolve?.(message);
+ this.removeFromQueue(initialAction);
+
+ break;
+ }
+
+ case "failure": {
+ pending.reject?.(message.error ? deserializeError(message.error) : message);
+ this.removeFromQueue(initialAction);
+
+ break;
+ }
+ }
+ }
+ }
+
+ send(message: Message, timeout: number): Promise {
+ if (this.getPendingMessage(message.action)) {
+ return Promise.reject(new ActionPendingError());
+
+ } else if (!window.isSecureContext) {
+ return Promise.reject(new ContextInsecureError());
+
+ } else {
+ const pending: PendingMessage = { message };
+
+ this.queue.push(pending);
+
+ pending.promise = new Promise((resolve, reject) => {
+ pending.resolve = resolve;
+ pending.reject = reject;
+ });
+
+ pending.ackTimer = setTimeout(
+ () => this.onAckTimeout(pending),
+ config.EXTENSION_HANDSHAKE_TIMEOUT,
+ );
+
+ pending.replyTimer = setTimeout(
+ () => this.onReplyTimeout(pending),
+ timeout,
+ );
+
+ window.postMessage(message, "*");
+
+ return pending.promise as Promise;
+ }
+ }
+
+ onReplyTimeout(pending: PendingMessage): void {
+ console.log("onReplyTimeout", pending.message.action);
+ pending.reject?.(new ActionTimeoutError());
+
+ this.removeFromQueue(pending.message.action);
+ }
+
+ onAckTimeout(pending: PendingMessage): void {
+ console.log("onAckTimeout", pending.message.action);
+ pending.reject?.(new ExtensionUnavailableError());
+
+ clearTimeout(pending.replyTimer);
+ }
+
+ getPendingMessage(action: string): PendingMessage | undefined {
+ return this.queue.find((pm) => {
+ return pm.message.action === action;
+ });
+ }
+
+ getSuccessAction(action: string): string {
+ return `${action}-success`;
+ }
+
+ getFailureAction(action: string): string {
+ return `${action}-failure`;
+ }
+
+ getInitialAction(action: string): string {
+ return action.replace(/-success$|-failure$|-ack$/, "");
+ }
+
+ removeFromQueue(action: string): void {
+ const pending = this.getPendingMessage(action);
+
+ clearTimeout(pending?.replyTimer);
+
+ this.queue = this.queue.filter((pending) => (
+ pending.message.action !== action
+ ));
+ }
+}
diff --git a/src/utils/defer.ts b/src/utils/defer.ts
new file mode 100644
index 0000000..0c7d57d
--- /dev/null
+++ b/src/utils/defer.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+export default function defer(): Promise {
+ return new Promise((resolve) => setTimeout(resolve));
+}
diff --git a/src/utils/errorSerializer.ts b/src/utils/errorSerializer.ts
new file mode 100644
index 0000000..06e5dd2
--- /dev/null
+++ b/src/utils/errorSerializer.ts
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import CertificateChangedError from "../errors/CertificateChangedError";
+import OriginMismatchError from "../errors/OriginMismatchError";
+import ContextInsecureError from "../errors/ContextInsecureError";
+import ExtensionUnavailableError from "../errors/ExtensionUnavailableError";
+import ActionPendingError from "../errors/ActionPendingError";
+import NativeFatalError from "../errors/NativeFatalError";
+import NativeUnavailableError from "../errors/NativeUnavailableError";
+import ServerRejectedError from "../errors/ServerRejectedError";
+import ErrorCode from "../errors/ErrorCode";
+import UserTimeoutError from "../errors/UserTimeoutError";
+import UserCancelledError from "../errors/UserCancelledError";
+import VersionMismatchError from "../errors/VersionMismatchError";
+import TlsConnectionBrokenError from "../errors/TlsConnectionBrokenError";
+import TlsConnectionInsecureError from "../errors/TlsConnectionInsecureError";
+import TlsConnectionWeakError from "../errors/TlsConnectionWeakError";
+import ProtocolInsecureError from "../errors/ProtocolInsecureError";
+import ActionTimeoutError from "../errors/ActionTimeoutError";
+import VersionInvalidError from "../errors/VersionInvalidError";
+import ServerTimeoutError from "../errors/ServerTimeoutError";
+import UnknownError from "../errors/UnknownError";
+
+const errorCodeToErrorClass: {[key: string]: any} = {
+ [ErrorCode.ERR_WEBEID_ACTION_PENDING]: ActionPendingError,
+ [ErrorCode.ERR_WEBEID_ACTION_TIMEOUT]: ActionTimeoutError,
+ [ErrorCode.ERR_WEBEID_CERTIFICATE_CHANGED]: CertificateChangedError,
+ [ErrorCode.ERR_WEBEID_ORIGIN_MISMATCH]: OriginMismatchError,
+ [ErrorCode.ERR_WEBEID_CONTEXT_INSECURE]: ContextInsecureError,
+ [ErrorCode.ERR_WEBEID_EXTENSION_UNAVAILABLE]: ExtensionUnavailableError,
+ [ErrorCode.ERR_WEBEID_NATIVE_FATAL]: NativeFatalError,
+ [ErrorCode.ERR_WEBEID_NATIVE_UNAVAILABLE]: NativeUnavailableError,
+ [ErrorCode.ERR_WEBEID_PROTOCOL_INSECURE]: ProtocolInsecureError,
+ [ErrorCode.ERR_WEBEID_SERVER_REJECTED]: ServerRejectedError,
+ [ErrorCode.ERR_WEBEID_SERVER_TIMEOUT]: ServerTimeoutError,
+ [ErrorCode.ERR_WEBEID_TLS_CONNECTION_BROKEN]: TlsConnectionBrokenError,
+ [ErrorCode.ERR_WEBEID_TLS_CONNECTION_INSECURE]: TlsConnectionInsecureError,
+ [ErrorCode.ERR_WEBEID_TLS_CONNECTION_WEAK]: TlsConnectionWeakError,
+ [ErrorCode.ERR_WEBEID_USER_CANCELLED]: UserCancelledError,
+ [ErrorCode.ERR_WEBEID_USER_TIMEOUT]: UserTimeoutError,
+ [ErrorCode.ERR_WEBEID_VERSION_INVALID]: VersionInvalidError,
+ [ErrorCode.ERR_WEBEID_VERSION_MISMATCH]: VersionMismatchError,
+};
+
+export function serializeError(error: any): any {
+ const {
+ message,
+ name,
+ fileName,
+ lineNumber,
+ columnNumber,
+ stack,
+ } = error;
+
+ return {
+ ...(
+ Object.fromEntries(
+ Object.getOwnPropertyNames(error)
+ .map((prop) => [prop, error[prop]])
+ )
+ ),
+
+ message,
+ name,
+ fileName,
+ lineNumber,
+ columnNumber,
+ stack,
+ };
+}
+
+export function deserializeError(errorObject: any): any {
+ let error;
+
+ if (typeof errorObject.code == "string" && errorObject.code in errorCodeToErrorClass) {
+ const CustomError = errorCodeToErrorClass[errorObject.code];
+
+ error = new CustomError();
+ } else {
+ error = new UnknownError();
+ }
+
+ for (const [key, value] of Object.entries(errorObject)) {
+ error[key] = value;
+ }
+
+ return error;
+}
diff --git a/src/utils/semver.ts b/src/utils/semver.ts
new file mode 100644
index 0000000..f215118
--- /dev/null
+++ b/src/utils/semver.ts
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import VersionInvalidError from "../errors/VersionInvalidError";
+
+const semverPattern = new RegExp(
+ "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)" +
+ "(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
+);
+
+export enum IdentifierDiff {
+ NEWER = 1,
+ SAME = 0,
+ OLDER = -1,
+}
+
+interface Semver {
+ major: number;
+ minor: number;
+ patch: number;
+ rc?: string;
+ build?: string;
+ string: string;
+}
+
+/**
+ * The difference can be -1, 0 or 1.
+ */
+interface SemverDiff {
+ major: IdentifierDiff;
+ minor: IdentifierDiff;
+ patch: IdentifierDiff;
+}
+
+export function parseSemver(string = ""): Semver {
+ const result = string.match(semverPattern);
+
+ const [, majorStr, minorStr, patchStr, rc, build] = result ? result : [];
+
+ const major = parseInt(majorStr, 10);
+ const minor = parseInt(minorStr, 10);
+ const patch = parseInt(patchStr, 10);
+
+ for (const indentifier of [major, minor, patch]) {
+ if (Number.isNaN(indentifier)) {
+ throw new VersionInvalidError(`Invalid SemVer string '${string}'`);
+ }
+ }
+
+ return { major, minor, patch, rc, build, string };
+}
+
+/**
+ * Compares two Semver objects.
+ *
+ * @param {Semver} a First SemVer object
+ * @param {Semver} b Second Semver object
+ *
+ * @returns {SemverDiff} Diff for major, minor and patch.
+ */
+export function compareSemver(a: Semver, b: Semver): SemverDiff {
+ return {
+ major: Math.sign(a.major - b.major),
+ minor: Math.sign(a.minor - b.minor),
+ patch: Math.sign(a.patch - b.patch),
+ };
+}
diff --git a/src/utils/version.ts b/src/utils/version.ts
new file mode 100644
index 0000000..bc0e3c7
--- /dev/null
+++ b/src/utils/version.ts
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import Versions from "../models/Versions";
+import { parseSemver, compareSemver, IdentifierDiff } from "./semver";
+import UpdateRequired from "../models/RequiresUpdate";
+
+/**
+ * Checks if update is required.
+ *
+ * @param version Object containing SemVer version strings for library, extension and native app.
+ *
+ * @returns Object which specifies if the extension or native app should be updated.
+ */
+export function checkCompatibility(version: Versions): UpdateRequired {
+ const library = parseSemver(version.library);
+ const extension = parseSemver(version.extension);
+ const nativeApp = parseSemver(version.nativeApp);
+
+ const extensionDiff = compareSemver(extension, library);
+ const nativeAppDiff = compareSemver(nativeApp, library);
+
+ return {
+ extension: extensionDiff.major === IdentifierDiff.OLDER,
+ nativeApp: nativeAppDiff.major === IdentifierDiff.OLDER,
+ };
+}
+
+/**
+ * Checks an object if 'library', 'extension' or 'nativeApp' properties are present.
+ * Values are not checked for SemVer validity.
+ *
+ * @param object Object which will be checked for version properties.
+ *
+ * @returns Were any of the version properties found in the provided object.
+ */
+export function hasVersionProperties(object: any): boolean {
+ if (typeof object === "object") {
+ for (const prop of ["library", "extension", "nativeApp"]) {
+ if (Object.hasOwnProperty.call(object, prop)) return true;
+ }
+ }
+
+ return false;
+}
diff --git a/src/web-eid.ts b/src/web-eid.ts
new file mode 100644
index 0000000..cea3119
--- /dev/null
+++ b/src/web-eid.ts
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2020 The Web eID Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import config from "./config";
+
+import ErrorCode from "./errors/ErrorCode";
+
+import Action from "./models/Action";
+import AuthenticateOptions from "./models/AuthenticateOptions";
+import SignOptions from "./models/SignOptions";
+import Versions from "./models/Versions";
+import ResponseAuthenticateSuccess from "./models/ResponseAuthenticateSuccess";
+import ResponseStatusSuccess from "./models/ResponseStatusSuccess";
+
+import WebExtensionService from "./services/WebExtensionService";
+
+import * as version from "./utils/version";
+import VersionMismatchError from "./errors/VersionMismatchError";
+import HttpResponse from "./models/HttpResponse";
+import MissingParameterError from "./errors/MissingParameterError";
+import defer from "./utils/defer";
+import ResponseSignSuccess from "./models/ResponseSignSuccess";
+
+
+const webExtensionService = new WebExtensionService();
+
+export async function status(): Promise {
+ await defer(); // Give chrome a moment to load the extension content script
+
+ let statusResponse;
+
+ const library = config.VERSION;
+
+ const timeout = config.EXTENSION_HANDSHAKE_TIMEOUT + config.NATIVE_APP_HANDSHAKE_TIMEOUT;
+ const message = { action: Action.STATUS };
+
+ try {
+ statusResponse = await webExtensionService.send(message, timeout);
+ } catch (error) {
+ error.library = library;
+
+ throw error;
+ }
+
+ const versions: Versions = { library, ...statusResponse };
+
+ const requiresUpdate = version.checkCompatibility(versions);
+
+ if (requiresUpdate.extension || requiresUpdate.nativeApp) {
+ throw new VersionMismatchError(undefined, versions, requiresUpdate);
+ }
+
+ return versions;
+}
+
+export async function authenticate(options: AuthenticateOptions): Promise {
+ await defer(); // Give chrome a moment to load the extension content script
+
+ if (typeof options != "object") {
+ throw new MissingParameterError("authenticate function requires an options object as parameter");
+ }
+
+ if (!options.getAuthChallengeUrl) {
+ throw new MissingParameterError("getAuthChallengeUrl missing from authenticate options");
+ }
+
+ if (!options.postAuthTokenUrl) {
+ throw new MissingParameterError("postAuthTokenUrl missing from authenticate options");
+ }
+
+ const timeout = (
+ config.EXTENSION_HANDSHAKE_TIMEOUT +
+ config.NATIVE_APP_HANDSHAKE_TIMEOUT +
+ (options.serverRequestTimeout || config.DEFAULT_SERVER_REQUEST_TIMEOUT) * 2 +
+ (options.userInteractionTimeout || config.DEFAULT_USER_INTERACTION_TIMEOUT)
+ );
+
+ const message = { ...options, action: Action.AUTHENTICATE };
+
+ const result = await webExtensionService.send(message, timeout);
+
+ return result.response;
+}
+
+export async function sign(options: SignOptions): Promise {
+ await defer(); // Give chrome a moment to load the extension content script
+
+ if (typeof options != "object") {
+ throw new MissingParameterError("sign function requires an options object as parameter");
+ }
+
+ if (!options.postPrepareSigningUrl) {
+ throw new MissingParameterError("postPrepareSigningUrl missing from sign options");
+ }
+
+ if (!options.postFinalizeSigningUrl) {
+ throw new MissingParameterError("postFinalizeSigningUrl missing from sign options");
+ }
+
+ const timeout = (
+ config.EXTENSION_HANDSHAKE_TIMEOUT +
+ config.NATIVE_APP_HANDSHAKE_TIMEOUT +
+ (options.serverRequestTimeout || config.DEFAULT_SERVER_REQUEST_TIMEOUT) * 2 +
+ (options.userInteractionTimeout || config.DEFAULT_USER_INTERACTION_TIMEOUT) * 2
+ );
+
+ const message = { ...options, action: Action.SIGN };
+
+ const result = await webExtensionService.send(message, timeout);
+
+ return result.response;
+}
+
+export { Action, ErrorCode };
+export { hasVersionProperties } from "./utils/version";
+export { config };
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..9810c96
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "module": "es6",
+ "target": "es2019",
+ "noImplicitAny": true,
+ "declaration": true,
+ "declarationMap": true,
+ "moduleResolution": "node",
+ "sourceMap": true,
+ "strict": true,
+ "outDir": "dist/node",
+ "baseUrl": "."
+ },
+ "include": ["src"],
+ "exclude": ["node_modules", "**/__tests__/*"]
+}