Skip to content

Commit

Permalink
V6 Client (#57)
Browse files Browse the repository at this point in the history
* Prettify examples

* ADD v6 api client.

Adds example usage code

* ADD watch mode

* Enhance V6 response with a QR generator

* ADD example flow for QR authentication

* ADDS qr caching layer

To help with managing state for qr
 on distributed backends.

* Control qr code generator trough client options

* UPDATES examples

* Clarify type for the customCache

* vv3.2.0-alpha.0

* Allow reading back from cache

Especially in places where the QrGenerator instance
was not available, e.g. across different requests.

* ADD barrel export

* FIX examples & update readme

* v3.2.0-alpha.1

* FIX api endpoints in v5&v6 classes

* chore: update package version, extend .gitignore with IDE files

---------

Co-authored-by: Sergey Petrenko <[email protected]>
  • Loading branch information
pepf and spiatrenka authored Feb 27, 2024
1 parent 6f42c33 commit 7aa8b80
Show file tree
Hide file tree
Showing 14 changed files with 495 additions and 35 deletions.
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# OS specific
.DS_Store

# IDE
.vscode
.idea

# Build directory
lib

Expand Down Expand Up @@ -37,9 +41,6 @@ build/Release
node_modules
jspm_packages

#
*package-lock.json

# Optional npm cache directory
.npm

Expand Down
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,32 @@ npm install --save bankid
yarn install bankid
```

## Usage
## Usage V6

```javascript
import { BankIdClientV6 } from "bankid";

const client = new BankIdClientV6({
production: false,
});

const { autoStartToken, orderRef } = await client.authenticate({
endUserIp: "127.0.0.1",
});

// Generate deep link from autoStarttoken and try to open BankID app
// See ./examples

client
.awaitPendingCollect(orderRef)
.then(res => {
console.log(res.completionData)
})

```
Acting on a session is done trough opening the app or trough scanning a QR Code, both examples are documented in detail [in the examples directory](./examples)

## Usage V5

```javascript
import { BankIdClient } from "bankid";
Expand Down
6 changes: 3 additions & 3 deletions examples/auth-simple.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {BankIdClient} from "../lib/bankid.js";
import { BankIdClient } from "../lib/bankid.js";

const personalNumber = process.argv[2];
const bankid = new BankIdClient({production: false});
const bankid = new BankIdClient({ production: false });

bankid
.authenticateAndCollect({endUserIp: "127.0.0.1", personalNumber})
.authenticateAndCollect({ endUserIp: "127.0.0.1", personalNumber })
.then(res => console.log(res.completionData.user))
.catch(err => console.error(err));
11 changes: 7 additions & 4 deletions examples/cancel.mjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {BankIdClient} from "../lib/bankid.js";
import { BankIdClient } from "../lib/bankid.js";

const personalNumber = process.argv[2];
const bankid = new BankIdClient({production: false});
const bankid = new BankIdClient({ production: false });

async function testCancelation() {
const { orderRef } = await bankid.authenticate({endUserIp: "127.0.0.1", personalNumber});
const { orderRef } = await bankid.authenticate({
endUserIp: "127.0.0.1",
personalNumber,
});
await bankid
.cancel({orderRef})
.cancel({ orderRef })
.then(() => console.log("success"))
.catch(console.error);
}
Expand Down
13 changes: 9 additions & 4 deletions examples/collect.mjs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import {BankIdClient} from "../lib/bankid.js";
import { BankIdClient } from "../lib/bankid.js";

const personalNumber = process.argv[2];
const bankid = new BankIdClient({production: false});
const bankid = new BankIdClient({ production: false });

bankid
.sign({endUserIp: "127.0.0.1", personalNumber, userVisibleData: "visible", userNonVisibleData: "invisible"})
.sign({
endUserIp: "127.0.0.1",
personalNumber,
userVisibleData: "visible",
userNonVisibleData: "invisible",
})
.then(res => {
const timer = setInterval(() => {
const done = () => clearInterval(timer);

bankid
.collect({orderRef: res.orderRef})
.collect({ orderRef: res.orderRef })
.then(res => {
console.log(res.status);

Expand Down
20 changes: 20 additions & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<head>
<title>BankID QR code</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/qrcode.js"></script>
</head>
<body>
<canvas id="canvas" width="500", height="500"></canvas>

<script>
const params = new URLSearchParams(window.location.search)
const qrString = params.get("code");
if (qrString) {
QRCode.toCanvas(document.getElementById('canvas'), qrString, {scale: 10}, function (error) {
if (error) console.error(error)
console.log('success!');
})
}
</script>
</body>
</html>
32 changes: 32 additions & 0 deletions examples/v6-autostart.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { exec } from "node:child_process";
import { promisify } from "node:util";
import { BankIdClientV6 } from "../lib/bankid.js";

const execPromise = promisify(exec);

const bankid = new BankIdClientV6({
production: false,
});

const tryOpenBankIDDesktop = async (autoStartToken, redirectUrl) => {
const deepLink = `bankid:///?autostarttoken=${autoStartToken}&redirect=${redirectUrl}`;
await execPromise(`open "${deepLink}"`);
};

/**
* The main function initiates a BankID authentication flow.
* It automatically starts the BankID application on the user's device if installed.
*/
const main = async () => {
const { autoStartToken, orderRef } = await bankid.authenticate({
endUserIp: "127.0.0.1",
});
const redirectUrl = `https://www.google.com`;
console.log(`Trying to trigger bankid on your current device..`);
await tryOpenBankIDDesktop(autoStartToken, redirectUrl);
console.log("Awaiting sign..");
const resp = await bankid.awaitPendingCollect(orderRef);
console.log("Succes!", resp);
};

main().catch(err => console.error(err));
68 changes: 68 additions & 0 deletions examples/v6-qrcode-customcache.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* This script uses the BankId API to authenticate. Results are logged to the console.
* The script will keep generating new QR codes for authentification for a
* maximum of 20 seconds, while continuously checking the order status.
* In case the order status still has not turned "complete" after 20 seconds,
* the script will timeout
*/
import { exec } from "node:child_process";
import { promisify } from "node:util";
import { BankIdClientV6 } from "../lib/bankid.js";
import { cwd } from "node:process";

const execPromise = promisify(exec);

const customCache = {
cache: {},
get(key) {
console.log("get called! ", key);
return this.cache[key];
},
set(key, value) {
console.log("set called!");
this.cache[key] = value;
},
};

const bankid = new BankIdClientV6({
production: false,
qrOptions: { customCache },
});

const tryOpenQRCodeInBrowser = async code => {
// Apple way of opening html files with GET params
await execPromise(
`osascript -e 'tell application "Google Chrome" to open location "file://${cwd()}/index.html?code=${encodeURIComponent(
code,
)}"'`,
);
};

const main = async () => {
const { orderRef, qr } = await bankid.authenticate({
endUserIp: "127.0.0.1",
});

let success = false;
// Generate new QR code for 20 seconds, check status of the order on each cycle
for await (const newQrCode of qr.nextQr(orderRef, { timeout: 20 })) {
tryOpenQRCodeInBrowser(newQrCode);
const resp = await bankid.collect({ orderRef });
console.log({ orderRef, newQrCode });
if (resp.status === "complete") {
// Check for success ?
success = true;
console.log("Succes!", resp);
return;
} else if (resp.status === "failed") {
throw new Error(resp);
}

await new Promise(r => setTimeout(r, 2000));
}
if (!success) {
console.log("Timeout! Nothing happened");
}
};

main().catch(err => console.error(err));
52 changes: 52 additions & 0 deletions examples/v6-qrcode.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* This script uses the BankId API to authenticate. Results are logged to the console.
* The script will keep generating new QR codes for authentification for a
* maximum of 20 seconds, while continuously checking the order status.
* In case the order status still has not turned "complete" after 20 seconds,
* the script will timeout
*/
import { exec } from "node:child_process";
import { promisify } from "node:util";
import { BankIdClientV6 } from "../lib/bankid.js";
import { cwd } from "node:process";

const execPromise = promisify(exec);

const bankid = new BankIdClientV6({ production: false });

const tryOpenQRCodeInBrowser = async code => {
// Apple way of opening html files with GET params
await execPromise(
`osascript -e 'tell application "Google Chrome" to open location "file://${cwd()}/index.html?code=${encodeURIComponent(
code,
)}"'`,
);
};

const main = async () => {
const { orderRef, qr } = await bankid.authenticate({
endUserIp: "127.0.0.1",
});

let success = false;
// Generate new QR code for 20 seconds, check status of the order on each cycle
for await (const newQrCode of qr.nextQr(orderRef, { timeout: 20 })) {
tryOpenQRCodeInBrowser(newQrCode);
const resp = await bankid.collect({ orderRef });
if (resp.status === "complete") {
// Check for success ?
success = true;
console.log("Succes!", resp);
return;
} else if (resp.status === "failed") {
throw new Error(resp);
}

await new Promise(r => setTimeout(r, 2000));
}
if (!success) {
console.log("Timeout! Nothing happened");
}
};

main().catch(err => console.error(err));
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
"bankid",
"authentication"
],
"version": "3.1.4",
"main": "lib/bankid.js",
"version": "3.2.0",
"main": "lib/index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/anyfin/bankid.git"
},
"scripts": {
"dev": "tsc --watch",
"build": "tsc",
"prepublishOnly": "yarn build",
"format": "prettier --write \"./**/*.{js,ts,json,md}\""
"format": "prettier --write \"./**/*.{mjs,js,ts,json,md}\""
},
"author": "Sven Perkmann",
"license": "MIT",
Expand Down
Loading

0 comments on commit 7aa8b80

Please sign in to comment.