web-eid.js
— add secure 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.
More information about the Web eID project is available on the project website.
Complete the three steps below to add secure 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.
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/web-eid-library
Configure the web server to expose node_modules/web-eid/dist/es/web-eid.js
See below for alternative installation options.
To use Web eID securely, CSRF protection must be enabled. Enable and configure CSRF protection in your web application and include the CSRF token in the POST requests as in the code examples below.
Use the following code as an example when implementing authentication. For an in-depth description, refer to the Authenticate section of the API documentation.
<p>
<button id="webeid-auth-button">Authenticate</button>
</p>
<script type="module">
import * as webeid from 'web-eid.js';
const lang = navigator.language.substr(0, 2);
const authButton = document.querySelector("#webeid-auth-button");
authButton.addEventListener("click", async () => {
try {
const challengeResponse = await fetch("/auth/challenge", {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
if (!challengeResponse.ok) {
throw new Error("GET /auth/challenge server error: " +
challengeResponse.status);
}
const {nonce} = await challengeResponse.json();
const authToken = await webeid.authenticate(nonce, {lang});
const authTokenResponse = await fetch("/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
[csrfHeaderName]: csrfToken
},
body: JSON.stringify({authToken})
});
if (!authTokenResponse.ok) {
throw new Error("POST /auth/login server error: " +
authTokenResponse.status);
}
const authTokenResult = await authTokenResponse.json();
console.log("Authentication successful! Result:", authTokenResult);
window.location.href = "/welcome";
} catch (error) {
console.log("Authentication failed! Error:", error);
throw error;
}
});
</script>
Copy the following code to the digital signing page of your web application,
customizing CSRF token code, the user language setting and fetch
URLs according to your application configuration:
<p>
<button id="webeid-sign-button">Sign document</button>
</p>
<script type="module">
import * as webeid from 'web-eid.js';
const lang = navigator.language.substr(0, 2);
const signButton = document.querySelector("#webeid-sign-button");
signButton.addEventListener("click", async () => {
try {
const {
certificate,
supportedSignatureAlgorithms
} = await webeid.getSigningCertificate({lang});
const prepareSigningResponse = await fetch("/sign/prepare", {
method: "POST",
headers: {
"Content-Type": "application/json",
[csrfHeaderName]: csrfToken
},
body: JSON.stringify({certificate, supportedSignatureAlgorithms}),
});
if (!prepareSigningResponse.ok) {
throw new Error("POST /sign/prepare server error: " +
prepareSigningResponse.status);
}
const {
hash,
hashFunction
} = await prepareSigningResponse.json();
const {
signature,
signatureAlgorithm
} = await webeid.sign(certificate, hash, hashFunction, {lang});
const finalizeSigningResponse = await fetch("/sign/finalize", {
method: "POST",
headers: {
"Content-Type": "application/json",
[csrfHeaderName]: csrfToken
},
body: JSON.stringify({signature, signatureAlgorithm}),
});
if (!finalizeSigningResponse.ok) {
throw new Error("POST /sign/finalize server error: " +
finalizeSigningResponse.status);
}
const signResult = await finalizeSigningResponse.json();
console.log("Signing successful! Response:", response);
// display successful signing message to user
} catch (error) {
console.log("Signing failed! Error:", error);
throw error;
}
});
</script>
A stable pre-built version of the library can be downloaded from the latest release assets.
Use the dist/iife build. It exposes the webeid
object globally.
<script src="https://github.com/web-eid/web-eid.js/raw/main/web-eid.min.js"></script>
<script>
// Library registered globally
webeid.authenticate(...).then(...).catch(...);
</script>
When using a build tool like WebPack, Babel, Rollup or the TypeScript compiler:
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/web-eid-library
Import the module:
// Import the Web-eID library
import * as webeid from '@web-eid/web-eid-library/web-eid';
// ...or only what you need
import {
status,
authenticate,
Action,
ErrorCode
} from '@web-eid/web-eid-library/web-eid';
// If you need TypeScript interfaces, they are also available!
import ActionOptions from '@web-eid/web-eid-library/models/ActionOptions';
node_modules/web-eid/dist/es/web-eid.js
// Import the Web-eID library
import * as webeid from 'web-eid.js';
Use the dist/umd build.
CommonJS
var webeid = require("web-eid");
AMD
define(["web-eid"], function(webeid) {
...
});
To use Web eID securely, CSRF protection must be enabled in the web application back end and the CSRF token must be included in all POST requests. The CSRF token is commonly passed to the back end in a request header using the headers
parameter of fetch()
.
ActionOptions
Object that configures the common options of the authenticate
, getSigningCertificate
and sign
actions.
Name | Type | Default | Description |
---|---|---|---|
options.userInteractionTimeout |
number |
120000 |
Optional user interaction timeout in milliseconds |
options.lang |
string |
Optional ISO 639-1 two-letter language code to specify the Web-eID native application's user interface language |
When the website allows users to specify their preferred website language,
the lang
option may be used to display the Web eID native application's dialogs in the same language as the user's preferred website language.
When the status check fails, in addition to the usual name
, message
and stack
properties, the error object contains the additional error code field code
. See Known errors below for error code
options.
status(): Promise<LibraryStatusResponse>
To verify that the user has a valid extension and native application version, a status check can be performed.
Version check is performed automatically by the extension when the authenticate, get-signing-certificate or sign actions fail.
Promise<LibraryStatusResponse>
LibraryStatusResponse {
// SemVer string in the format x.y.z
library: string;
// SemVer string in the format x.y.z
extension: string;
// SemVer string in the format x.y.z
nativeApp: string;
}
try {
const status = await webeid.status();
// HANDLE SUCCESS
} catch (error) {
// HANDLE FAILURE
}
The result of a status check is the status object which contains SemVer strings for the library, browser extension and native application.
{
library: "1.2.3",
nativeApp: "1.2.3",
extension: "1.2.3"
}
When the status check fails, when possible, in addition to the usual error object properties name
, message
and stack
, the error object contains additional info about the library, extension and native application versions and if the extension or native application require an update.
{
// 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(challengeNonce: string, options?: ActionOptions): Promise<LibraryAuthenticateResponse>
Requests the Web-eID browser extension to authenticate the user. The challengeNonce
must be recently retrieved from the back end. The result contains the Web eID authentication token that must be sent to the back end for validation.
Name | Type | Description |
---|---|---|
challengeNonce |
string |
Required challenge nonce received from the back end |
options |
object |
Optional action options object, see ActionOptions above |
challengeNonce
must be a base64-encoded cryptographic nonce, generated by the server, with at least 256 bits of entropy.
For every authentication attempt, the challengeNonce
must be unique and time-limited.
Promise<LibraryAuthenticateResponse> // contains the Web eID authentication token
interface LibraryAuthenticateResponse {
/**
* The base64-encoded DER-encoded authentication certificate of the eID user
*
* The public key contained in this certificate should be used to verify the signature.
* The certificate cannot be trusted as it is received from client side and the client can submit a malicious certificate.
* To establish trust, it must be verified that the certificate is signed by a trusted certificate authority.
*/
unverifiedCertificate: string;
/**
* The algorithm used to produce the authentication signature
*
* The allowed values are the algorithms specified in JWA RFC8 sections 3.3, 3.4 and 3.5
* @see https://www.ietf.org/rfc/rfc7518.html
*/
algorithm:
| "ES256" | "ES384" | "ES512" // ECDSA
| "PS256" | "PS384" | "PS512" // RSASSA-PSS
| "RS256" | "RS384" | "RS512"; // RSASSA-PKCS1-v1_5,
/**
* The base64-encoded signature of the token
*/
signature: string;
/**
* The type identifier and version of the token format separated by a colon character
*
* @example "web-eid:1.0"
*/
format: string;
/**
* The URL identifying the name and version of the application that issued the token
*
* @example "https://web-eid.eu/web-eid-app/releases/2.0.0+0"
*/
appVersion: string;
}
try {
const challengeResponse = await fetch("/auth/challenge", {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
// HANDLE challengeResponse ERRORS
const {challengeNonce} = await challengeResponse.json();
const authToken = await webeid.authenticate(challengeNonce, {lang});
const authTokenResponse = await fetch("/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
[csrfHeaderName]: csrfToken
},
body: JSON.stringify({authToken})
});
// HANDLE authTokenResponse ERRORS
const authTokenResult = await authTokenResponse.json();
// HANDLE SUCCESS
} catch (error) {
// HANDLE FAILURE
}
The result of the authentication action is the object that contains the Web eID authentication token.
{
"algorithm": "ES384",
"appVersion": "https://web-eid.eu/web-eid-app/releases/2.0.0+0",
"format": "web-eid:1",
"signature": "tbMTrZD4CKUj6atjNCHZruIeyPFAEJk2htziQ1t08BSTyA5wKKqmNmzsJ7562hWQ6+tJd6nlidHGE5jVVJRKmPtNv3f9gbT2b7RXcD4t5Pjn8eUCBCA4IX99Af32Z5ln",
"unverifiedCertificate": "MIIEAzCCA2WgAwIBAgIQHWbVWxCkcYxbzz9nBzGrDzAKBggqhkjOPQQDBDBgMQswCQYDVQQGEwJFRTEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFTMRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UEAwwSVEVTVCBvZiBFU1RFSUQyMDE4MB4XDTE4MTAyMzE1MzM1OVoXDTIzMTAyMjIxNTk1OVowfzELMAkGA1UEBhMCRUUxKjAoBgNVBAMMIUrDlUVPUkcsSkFBSy1LUklTVEpBTiwzODAwMTA4NTcxODEQMA4GA1UEBAwHSsOVRU9SRzEWMBQGA1UEKgwNSkFBSy1LUklTVEpBTjEaMBgGA1UEBRMRUE5PRUUtMzgwMDEwODU3MTgwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQ/u+9IncarVpgrACN6aRgUiT9lWC9H7llnxoEXe8xoCI982Md8YuJsVfRdeG5jwVfXe0N6KkHLFRARspst8qnACULkqFNat/Kj+XRwJ2UANeJ3Gl5XBr+tnLNuDf/UiR6jggHDMIIBvzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIDiDBHBgNVHSAEQDA+MDIGCysGAQQBg5EhAQIBMCMwIQYIKwYBBQUHAgEWFWh0dHBzOi8vd3d3LnNrLmVlL0NQUzAIBgYEAI96AQIwHwYDVR0RBBgwFoEUMzgwMDEwODU3MThAZWVzdGkuZWUwHQYDVR0OBBYEFOTddHnA9rJtbLwhBNyn0xZTQGCMMGEGCCsGAQUFBwEDBFUwUzBRBgYEAI5GAQUwRzBFFj9odHRwczovL3NrLmVlL2VuL3JlcG9zaXRvcnkvY29uZGl0aW9ucy1mb3ItdXNlLW9mLWNlcnRpZmljYXRlcy8TAkVOMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAfBgNVHSMEGDAWgBTAhJkpxE6fOwI09pnhClYACCk+ezBzBggrBgEFBQcBAQRnMGUwLAYIKwYBBQUHMAGGIGh0dHA6Ly9haWEuZGVtby5zay5lZS9lc3RlaWQyMDE4MDUGCCsGAQUFBzAChilodHRwOi8vYy5zay5lZS9UZXN0X29mX0VTVEVJRDIwMTguZGVyLmNydDAKBggqhkjOPQQDBAOBiwAwgYcCQgHYElkX4vn821JR41akI/lpexCnJFUf4GiOMbTfzAxpZma333R8LNrmI4zbzDp03hvMTzH49g1jcbGnaCcbboS8DAJBObenUp++L5VqldHwKAps61nM4V+TiLqD0jILnTzl+pV+LexNL3uGzUfvvDNLHnF9t6ygi8+Bsjsu3iHHyM1haKM="
}
getSigningCertificate(options?: ActionOptions): Promise<LibraryGetSigningCertificateResponse>
Requests the Web-eID browser extension to retrieve the signing certificate of the user. The certificate must be sent to the back end for preparing the digital signature container and passed to sign()
as the first parameter.
Name | Type | Description |
---|---|---|
options |
object |
Optional action options object, see ActionOptions above |
Promise<LibraryGetSigningCertificateResponse>
interface LibraryGetSigningCertificateResponse {
// The Base64-encoded DER-encoded signing certificate of the eID user
certificate: string;
// The supported signature algorithm options
supportedSignatureAlgorithms: Array<SignatureAlgorithm>;
}
interface SignatureAlgorithm {
hashFunction: SignatureHashFunction; // enum of strings
paddingScheme: SignaturePaddingScheme; // enum of strings
cryptoAlgorithm: SignatureCryptoAlgorithm; // enum of strings
}
try {
const {
certificate,
supportedSignatureAlgorithms
} = await webeid.getSigningCertificate({lang});
// HANDLE SUCCESS
} catch (error) {
// HANDLE FAILURE
}
{
"certificate":"MIID7DCCA02gAwIBAgIQOZYpcFbeurZbzz9ngqCZsTAKBggqhkjOPQQDBDBgMQswCQYDVQQGEwJFRTEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFTMRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UEAwwSVEVTVCBvZiBFU1RFSUQyMDE4MB4XDTE4MTAyMzE1MzM1OVoXDTIzMTAyMjIxNTk1OVowfzELMAkGA1UEBhMCRUUxKjAoBgNVBAMMIUrDlUVPUkcsSkFBSy1LUklTVEpBTiwzODAwMTA4NTcxODEQMA4GA1UEBAwHSsOVRU9SRzEWMBQGA1UEKgwNSkFBSy1LUklTVEpBTjEaMBgGA1UEBRMRUE5PRUUtMzgwMDEwODU3MTgwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASKvaAJSGYBrLcvq0KjgM1sOAS9vbtqeSS2OkqyY4i5AazaetYmCtXKOqUUeljOJUGBUzljDFlAEPHs5Fn+vFT7+cGkOVCA93PBYKVsA9avcWyMwgQQJoW6kA4ZN9yD/mijggGrMIIBpzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIGQDBIBgNVHSAEQTA/MDIGCysGAQQBg5EhAQIBMCMwIQYIKwYBBQUHAgEWFWh0dHBzOi8vd3d3LnNrLmVlL0NQUzAJBgcEAIvsQAECMB0GA1UdDgQWBBRYwsjA5GJ7HWPvD8ByThPTZ6j3PDCBigYIKwYBBQUHAQMEfjB8MAgGBgQAjkYBATAIBgYEAI5GAQQwEwYGBACORgEGMAkGBwQAjkYBBgEwUQYGBACORgEFMEcwRRY/aHR0cHM6Ly9zay5lZS9lbi9yZXBvc2l0b3J5L2NvbmRpdGlvbnMtZm9yLXVzZS1vZi1jZXJ0aWZpY2F0ZXMvEwJFTjAfBgNVHSMEGDAWgBTAhJkpxE6fOwI09pnhClYACCk+ezBzBggrBgEFBQcBAQRnMGUwLAYIKwYBBQUHMAGGIGh0dHA6Ly9haWEuZGVtby5zay5lZS9lc3RlaWQyMDE4MDUGCCsGAQUFBzAChilodHRwOi8vYy5zay5lZS9UZXN0X29mX0VTVEVJRDIwMTguZGVyLmNydDAKBggqhkjOPQQDBAOBjAAwgYgCQgDBTN1LM08SeH18xKQplqAmV8AQhVvrOxRELCmYp54Qr0XTi2i7kMw0k8gVOV84RlPQP6/ayjs4+ytRbIdkBZK1vQJCARF17/gWYUu7bmy/AXT6fWgyuDV5j2UC2cWDFhPUYyS99rdLGSfP10rP9mPK87Y+4HkfJB/qDyENnJYPa5mUsuFK",
"supportedSignatureAlgorithms":[
{
"cryptoAlgorithm":"ECC",
"hashFunction":"SHA-224",
"paddingScheme":"NONE"
},
{
"cryptoAlgorithm":"ECC",
"hashFunction":"SHA-256",
"paddingScheme":"NONE"
},
{
"cryptoAlgorithm":"ECC",
"hashFunction":"SHA-384",
"paddingScheme":"NONE"
},
{
"cryptoAlgorithm":"ECC",
"hashFunction":"SHA-512",
"paddingScheme":"NONE"
}
]
}
sign(certificate: string, hash: string, hashFunction: string, options?: ActionOptions): Promise<LibrarySignResponse>
Requests the Web-eID browser extension to sign a document hash. The certificate must be retrieved using getSigningCertificate()
and the hash must be retrieved from the back end.
Name | Type | Description |
---|---|---|
certificate |
string |
Required the base64-encoded signing certificate of the user |
hash |
string |
Required the base64-encoded hash of the data to be signed |
hashFunction |
string |
Required the name of the function that was used for computing the hash |
options |
object |
Optional action options object, see ActionOptions above |
The allowed hashFunction
values are SHA-224, SHA-256, SHA-384, SHA-512, SHA3-224, SHA3-256, SHA3-384 and SHA3-512.
Promise<LibrarySignResponse>
interface LibrarySignResponse {
// Signature algorithm
signatureAlgorithm: SignatureAlgorithm;
// The base64-encoded signature
signature: string;
}
try {
// certificate, supportedSignatureAlgorithms previously
// retrieved with getSigningCertificate()
const prepareSigningResponse = await fetch("/sign/prepare", {
method: "POST",
headers: {
"Content-Type": "application/json",
[csrfHeaderName]: csrfToken
},
body: JSON.stringify({certificate, supportedSignatureAlgorithms}),
});
// HANDLE prepareSigningResponse ERRORS
const {
hash,
hashFunction
} = await prepareSigningResponse.json();
const {
signature,
signatureAlgorithm
} = await webeid.sign(certificate, hash, hashFunction, {lang});
const finalizeSigningResponse = await fetch("/sign/finalize", {
method: "POST",
headers: {
"Content-Type": "application/json",
[csrfHeaderName]: csrfToken
},
body: JSON.stringify({signature, signatureAlgorithm}),
});
// HANDLE finalizeSigningResponse ERRORS
const signResult = await finalizeSigningResponse.json();
// HANDLE SUCCESS
} catch (error) {
// HANDLE FAILURE
}
{
"signature":"W1r4zf+7LkLs8Dy40nR+UOwZ7pkagywNSUxzB5/RJHdeYUZrmnAjGILdt+ek5vfHLBz9bF7B3UCRZWqZS61uNp2xJvjl7SuxpuAeo0lZrwZlvpuC2lT8mcvz9Eqso391",
"signatureAlgorithm":{
"cryptoAlgorithm":"ECC",
"hashFunction":"SHA-256",
"paddingScheme":"NONE"
}
}
In web-eid.js
API version 1, the authenticate()
and sign()
functions took URLs as parameters and the network requests to the website back end were performed inside the extension. This had many benefits, including reduced surface for XSS attacks, additional internal security checks and control over the interaction flow with the user. However, the network requests indirectly caused a Cross-Origin Resource Sharing (CORS) vulnerability in Firefox.
Since version 85 of Chrome (and other Chromium-based browsers), CORS rules are applied to all extension content scripts and access to any other domain B from origin domain A will be blocked, unless explicitly allowed with the Access-Control-Allow-Origin
header. However, Firefox currently allows access to any origin without cross-origin restrictions, as the Web eID extension requests loading of the extension on all websites with the *://*/*
host match pattern. Thus, in Firefox, malicious websites were potentially able to bypass CORS rules and misuse the headers
parameter and URL parameters of the authenticate()
and sign()
network requests to send arbitrary URL parameters and headers to arbitrary websites.
To mitigate the CORS vulnerability in Firefox, the web-eid.js
API version 2 no longer handles network requests internally; the website developer is expected to perform the requests instead.
To upgrade from API version 1 to version 2,
fetch()
, pass it as parameter into the authenticate()
call and send the resulting authentication token to the back end using fetch()
,getSigningCertificate()
call, sent both to the back end using fetch()
to prepare the digital signature container and retrieve the hash and hash function from the response, pass the hash and hash function as parameters into the sign()
call and, finally, send the resulting signature and signature algorithm to the back end using fetch()
.Also, handle fetch()
result Response
errors, assure that CSRF support is enabled and include the CSRF token in all POST requests.
See the code examples above.
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 have a code
property which contains the programmatic error code.
To avoid typos, you can use the ErrorCode
enum to refer to the codes.
Example
try {
const {
certificate,
supportedSignatureAlgorithms,
} = await webeid.getSigningCertificate({lang});
// HANDLE SUCCESS
} catch (error) {
switch (error.code) {
case webeid.ErrorCode.ERR_WEBEID_USER_TIMEOUT: {
showError("Signing certificate retrieval timed out, please try again!");
break;
}
// other cases
default: {
showError(
"An unknown error occurred. " +
"Please try again and contact support if the problem persists!"
)
}
}
}
ERR_WEBEID_ACTION_TIMEOUT
ERR_WEBEID_USER_TIMEOUT
ERR_WEBEID_VERSION_MISMATCH
requiresUpdate
might be attached to the error object.
The user can be instructed to update the required component.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
ERR_WEBEID_EXTENSION_UNAVAILABLE
ERR_WEBEID_NATIVE_UNAVAILABLE
ERR_WEBEID_UNKNOWN_ERROR
ERR_WEBEID_CONTEXT_INSECURE
ERR_WEBEID_USER_CANCELLED
ERR_WEBEID_NATIVE_INVALID_ARGUMENT
ERR_WEBEID_NATIVE_FATAL
nativeException
attribute for details.ERR_WEBEID_ACTION_PENDING
authenticateButton.disabled = true;
try {
const response = await authenticate(options);
...
} catch (error) {
...
} finally {
authenticateButton.disabled = false;
}
ERR_WEBEID_MISSING_PARAMETER
You are welcome to create pull requests for the Web-eID library!
.editorconfig
file.npm install
to install dependencies.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 |
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.
npm link
You can use npm link
to link the Web-eID library source directory to a another project.
Example
cd ~/workspace/web-eid-library
npm run build
cd ~/workspace/example-website
npm link ~/workspace/web-eid-library
Pros
Cons
web-eid/dist/node/
instead of directly under web-eid/
.
import AuthenticateOptions from 'web-eid/dist/node/models/AuthenticateOptions';
npm pack
You can use npm pack
to generate a package and install the package archive.
Example
cd ~/workspace/web-eid-library
npm run build
npm package
cd ~/workspace/example-website
npm install ~/workspace/web-eid-library/web-eid-*.tgz
Pros
import AuthenticateOptions from 'web-eid/models/AuthenticateOptions';
Cons