Skip to content

Commit 7aa8b80

Browse files
pepfspiatrenka
andauthored
V6 Client (#57)
* 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 <siarhei@anyfin.com>
1 parent 6f42c33 commit 7aa8b80

14 files changed

+495
-35
lines changed

.gitignore

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# OS specific
22
.DS_Store
33

4+
# IDE
5+
.vscode
6+
.idea
7+
48
# Build directory
59
lib
610

@@ -37,9 +41,6 @@ build/Release
3741
node_modules
3842
jspm_packages
3943

40-
#
41-
*package-lock.json
42-
4344
# Optional npm cache directory
4445
.npm
4546

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,32 @@ npm install --save bankid
1111
yarn install bankid
1212
```
1313

14-
## Usage
14+
## Usage V6
15+
16+
```javascript
17+
import { BankIdClientV6 } from "bankid";
18+
19+
const client = new BankIdClientV6({
20+
production: false,
21+
});
22+
23+
const { autoStartToken, orderRef } = await client.authenticate({
24+
endUserIp: "127.0.0.1",
25+
});
26+
27+
// Generate deep link from autoStarttoken and try to open BankID app
28+
// See ./examples
29+
30+
client
31+
.awaitPendingCollect(orderRef)
32+
.then(res => {
33+
console.log(res.completionData)
34+
})
35+
36+
```
37+
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)
38+
39+
## Usage V5
1540

1641
```javascript
1742
import { BankIdClient } from "bankid";

examples/auth-simple.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {BankIdClient} from "../lib/bankid.js";
1+
import { BankIdClient } from "../lib/bankid.js";
22

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

66
bankid
7-
.authenticateAndCollect({endUserIp: "127.0.0.1", personalNumber})
7+
.authenticateAndCollect({ endUserIp: "127.0.0.1", personalNumber })
88
.then(res => console.log(res.completionData.user))
99
.catch(err => console.error(err));

examples/cancel.mjs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import {BankIdClient} from "../lib/bankid.js";
1+
import { BankIdClient } from "../lib/bankid.js";
22

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

66
async function testCancelation() {
7-
const { orderRef } = await bankid.authenticate({endUserIp: "127.0.0.1", personalNumber});
7+
const { orderRef } = await bankid.authenticate({
8+
endUserIp: "127.0.0.1",
9+
personalNumber,
10+
});
811
await bankid
9-
.cancel({orderRef})
12+
.cancel({ orderRef })
1013
.then(() => console.log("success"))
1114
.catch(console.error);
1215
}

examples/collect.mjs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
import {BankIdClient} from "../lib/bankid.js";
1+
import { BankIdClient } from "../lib/bankid.js";
22

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

66
bankid
7-
.sign({endUserIp: "127.0.0.1", personalNumber, userVisibleData: "visible", userNonVisibleData: "invisible"})
7+
.sign({
8+
endUserIp: "127.0.0.1",
9+
personalNumber,
10+
userVisibleData: "visible",
11+
userNonVisibleData: "invisible",
12+
})
813
.then(res => {
914
const timer = setInterval(() => {
1015
const done = () => clearInterval(timer);
1116

1217
bankid
13-
.collect({orderRef: res.orderRef})
18+
.collect({ orderRef: res.orderRef })
1419
.then(res => {
1520
console.log(res.status);
1621

examples/index.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<head>
3+
<title>BankID QR code</title>
4+
<script src="https://cdn.jsdelivr.net/npm/qrcode@1.5.0/build/qrcode.js"></script>
5+
</head>
6+
<body>
7+
<canvas id="canvas" width="500", height="500"></canvas>
8+
9+
<script>
10+
const params = new URLSearchParams(window.location.search)
11+
const qrString = params.get("code");
12+
if (qrString) {
13+
QRCode.toCanvas(document.getElementById('canvas'), qrString, {scale: 10}, function (error) {
14+
if (error) console.error(error)
15+
console.log('success!');
16+
})
17+
}
18+
</script>
19+
</body>
20+
</html>

examples/v6-autostart.mjs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { exec } from "node:child_process";
2+
import { promisify } from "node:util";
3+
import { BankIdClientV6 } from "../lib/bankid.js";
4+
5+
const execPromise = promisify(exec);
6+
7+
const bankid = new BankIdClientV6({
8+
production: false,
9+
});
10+
11+
const tryOpenBankIDDesktop = async (autoStartToken, redirectUrl) => {
12+
const deepLink = `bankid:///?autostarttoken=${autoStartToken}&redirect=${redirectUrl}`;
13+
await execPromise(`open "${deepLink}"`);
14+
};
15+
16+
/**
17+
* The main function initiates a BankID authentication flow.
18+
* It automatically starts the BankID application on the user's device if installed.
19+
*/
20+
const main = async () => {
21+
const { autoStartToken, orderRef } = await bankid.authenticate({
22+
endUserIp: "127.0.0.1",
23+
});
24+
const redirectUrl = `https://www.google.com`;
25+
console.log(`Trying to trigger bankid on your current device..`);
26+
await tryOpenBankIDDesktop(autoStartToken, redirectUrl);
27+
console.log("Awaiting sign..");
28+
const resp = await bankid.awaitPendingCollect(orderRef);
29+
console.log("Succes!", resp);
30+
};
31+
32+
main().catch(err => console.error(err));

examples/v6-qrcode-customcache.mjs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* This script uses the BankId API to authenticate. Results are logged to the console.
3+
* The script will keep generating new QR codes for authentification for a
4+
* maximum of 20 seconds, while continuously checking the order status.
5+
* In case the order status still has not turned "complete" after 20 seconds,
6+
* the script will timeout
7+
*/
8+
import { exec } from "node:child_process";
9+
import { promisify } from "node:util";
10+
import { BankIdClientV6 } from "../lib/bankid.js";
11+
import { cwd } from "node:process";
12+
13+
const execPromise = promisify(exec);
14+
15+
const customCache = {
16+
cache: {},
17+
get(key) {
18+
console.log("get called! ", key);
19+
return this.cache[key];
20+
},
21+
set(key, value) {
22+
console.log("set called!");
23+
this.cache[key] = value;
24+
},
25+
};
26+
27+
const bankid = new BankIdClientV6({
28+
production: false,
29+
qrOptions: { customCache },
30+
});
31+
32+
const tryOpenQRCodeInBrowser = async code => {
33+
// Apple way of opening html files with GET params
34+
await execPromise(
35+
`osascript -e 'tell application "Google Chrome" to open location "file://${cwd()}/index.html?code=${encodeURIComponent(
36+
code,
37+
)}"'`,
38+
);
39+
};
40+
41+
const main = async () => {
42+
const { orderRef, qr } = await bankid.authenticate({
43+
endUserIp: "127.0.0.1",
44+
});
45+
46+
let success = false;
47+
// Generate new QR code for 20 seconds, check status of the order on each cycle
48+
for await (const newQrCode of qr.nextQr(orderRef, { timeout: 20 })) {
49+
tryOpenQRCodeInBrowser(newQrCode);
50+
const resp = await bankid.collect({ orderRef });
51+
console.log({ orderRef, newQrCode });
52+
if (resp.status === "complete") {
53+
// Check for success ?
54+
success = true;
55+
console.log("Succes!", resp);
56+
return;
57+
} else if (resp.status === "failed") {
58+
throw new Error(resp);
59+
}
60+
61+
await new Promise(r => setTimeout(r, 2000));
62+
}
63+
if (!success) {
64+
console.log("Timeout! Nothing happened");
65+
}
66+
};
67+
68+
main().catch(err => console.error(err));

examples/v6-qrcode.mjs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* This script uses the BankId API to authenticate. Results are logged to the console.
3+
* The script will keep generating new QR codes for authentification for a
4+
* maximum of 20 seconds, while continuously checking the order status.
5+
* In case the order status still has not turned "complete" after 20 seconds,
6+
* the script will timeout
7+
*/
8+
import { exec } from "node:child_process";
9+
import { promisify } from "node:util";
10+
import { BankIdClientV6 } from "../lib/bankid.js";
11+
import { cwd } from "node:process";
12+
13+
const execPromise = promisify(exec);
14+
15+
const bankid = new BankIdClientV6({ production: false });
16+
17+
const tryOpenQRCodeInBrowser = async code => {
18+
// Apple way of opening html files with GET params
19+
await execPromise(
20+
`osascript -e 'tell application "Google Chrome" to open location "file://${cwd()}/index.html?code=${encodeURIComponent(
21+
code,
22+
)}"'`,
23+
);
24+
};
25+
26+
const main = async () => {
27+
const { orderRef, qr } = await bankid.authenticate({
28+
endUserIp: "127.0.0.1",
29+
});
30+
31+
let success = false;
32+
// Generate new QR code for 20 seconds, check status of the order on each cycle
33+
for await (const newQrCode of qr.nextQr(orderRef, { timeout: 20 })) {
34+
tryOpenQRCodeInBrowser(newQrCode);
35+
const resp = await bankid.collect({ orderRef });
36+
if (resp.status === "complete") {
37+
// Check for success ?
38+
success = true;
39+
console.log("Succes!", resp);
40+
return;
41+
} else if (resp.status === "failed") {
42+
throw new Error(resp);
43+
}
44+
45+
await new Promise(r => setTimeout(r, 2000));
46+
}
47+
if (!success) {
48+
console.log("Timeout! Nothing happened");
49+
}
50+
};
51+
52+
main().catch(err => console.error(err));

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
"bankid",
77
"authentication"
88
],
9-
"version": "3.1.4",
10-
"main": "lib/bankid.js",
9+
"version": "3.2.0",
10+
"main": "lib/index.js",
1111
"repository": {
1212
"type": "git",
1313
"url": "git+https://github.com/anyfin/bankid.git"
1414
},
1515
"scripts": {
16+
"dev": "tsc --watch",
1617
"build": "tsc",
1718
"prepublishOnly": "yarn build",
18-
"format": "prettier --write \"./**/*.{js,ts,json,md}\""
19+
"format": "prettier --write \"./**/*.{mjs,js,ts,json,md}\""
1920
},
2021
"author": "Sven Perkmann",
2122
"license": "MIT",

0 commit comments

Comments
 (0)