Web: add haloGetDefaultMethod() and report the current method in statusCallback() (#192)

This commit is contained in:
Michał Leszczyński
2023-06-01 01:52:47 +02:00
committed by GitHub
parent 296f2e43dd
commit 06fc65469f
7 changed files with 53 additions and 14 deletions

View File

@@ -45,7 +45,7 @@ haloConvertSignature(digest, derSignature, publicKey);
**Example usage:**
```javascript
import {haloConvertSignature} from '@arx-research/libhalo';
import {execHaloCmdWeb, haloConvertSignature} from '@arx-research/libhalo';
const KEY_NO = 1;
@@ -101,7 +101,7 @@ haloRecoverPublicKey(digest, derSignature);
**Example usage:**
```javascript
import {haloRecoverPublicKey} from '@arx-research/libhalo';
import {execHaloCmdWeb, haloRecoverPublicKey} from '@arx-research/libhalo';
const KEY_NO = 1;
@@ -132,3 +132,26 @@ haloRecoverPublicKey(
'04e2b8ec92be2ed99962470555b31f094a1862d7fa3fb8a5de1f4d7f475bd93ffb27d7295e94ac11e8fa67b70582df375fc660c5e36078e83f7a1e9f7e6ae08142'
]
```
## haloGetDefaultMethod
For websites: detect the best command execution method for the current device.
Returns a string that could be passed directly as `options.method` key for `execHaloCmdWeb()` function.
```javascript
haloGetDefaultMethod();
```
**Example usage:**
```
import {execHaloCmdWeb, haloGetDefaultMethod} from '@arx-research/libhalo';
let signRes = await execHaloCmdWeb({
"name": "sign",
"message": "010203",
"keyNo": 1,
"legacySignCommand": true
}, {
"method": haloGetDefaultMethod()
});
```

View File

@@ -67,7 +67,7 @@ the command execution process is ongoing. This could be used to increase user's
Example callback:
```
statusCallback: (cause) => console.log(cause)
statusCallback: (cause, execMethod) => console.log(cause, execMethod)
```
The callback could be called with the following `cause` as a first argument:
@@ -80,6 +80,14 @@ The callback could be called with the following `cause` as a first argument:
the library is postprocessing the result, the frontend should ask the user to untap the tag
and wait a moment until the operation is completed;
The `execMethod` will be either:
* `credential` - if the credential prompt method is being used in order to scan the tag (mostly on iOS/Windows);
* `webnfc` - if the WebNFC method is used in order to scan the tag (mostly on Android);
The application's frontend could differentiate the UI behavior depending on the `execMethod` that is being used
by the library in order to provide better user experience.
#### options.debugCallback
```
options.debugCallback: null/function

View File

@@ -20,6 +20,10 @@ const {ERROR_CODES} = require("../halo/errors");
let isCallRunning = null;
/**
* Detect the best command execution method for the current device.
* @returns {string} Either "credential" or "webnfc".
*/
function detectMethod() {
try {
new NDEFReader();
@@ -137,5 +141,6 @@ async function execHaloCmdWeb(command, options) {
module.exports = {
execHaloCmdWeb,
execHaloCmd,
checkErrors
checkErrors,
detectMethod
};

View File

@@ -53,7 +53,7 @@ async function execCredential(request, options) {
let u2fRes;
options.statusCallback("init", "get-credential");
options.statusCallback("init", "credential", "get-credential");
options.debugCallback("get-credential");
try {
@@ -66,7 +66,7 @@ async function execCredential(request, options) {
}
}
options.statusCallback("scanned", "get-credential-done");
options.statusCallback("scanned", "credential", "get-credential-done");
options.debugCallback("get-credential-done");
let res = u2fRes.response.signature;

View File

@@ -58,9 +58,9 @@ async function execWebNFC(request, options) {
options.debugCallback(writeStatus);
if (writeStatus === "nfc-write") {
options.statusCallback("init", "nfc-write");
options.statusCallback("init", "webnfc", "nfc-write");
} else if (writeStatus === "nfc-write-error") {
options.statusCallback("retry", "nfc-write-error");
options.statusCallback("retry", "webnfc", "nfc-write-error");
}
await ndef.write({records: [{recordType: "unknown", data: request}]});
@@ -83,7 +83,7 @@ async function execWebNFC(request, options) {
return new Promise((resolve, reject) => {
ndef.onreadingerror = (event) => {
options.debugCallback("nfc-read-error");
options.statusCallback("retry", "nfc-read-error");
options.statusCallback("retry", "webnfc", "nfc-read-error");
};
ndef.onreading = (event) => {
@@ -114,7 +114,7 @@ async function execWebNFC(request, options) {
}
options.debugCallback("nfc-success");
options.statusCallback("scanned", "nfc-success");
options.statusCallback("scanned", "webnfc", "nfc-success");
ndef.onreading = () => null;
ndef.onreadingerror = () => null;
@@ -129,7 +129,7 @@ async function execWebNFC(request, options) {
}, 1);
} catch (e) {
options.debugCallback("nfc-parse-error");
options.statusCallback("retry", "nfc-parse-error");
options.statusCallback("retry", "webnfc", "nfc-parse-error");
}
};
});

View File

@@ -76,10 +76,12 @@
// all options are optional, you can use them to increase user's experience
let options = {
method: method,
statusCallback: (cause) => {
statusCallback: (cause, execMethod) => {
if (cause === "init") {
// explicitly ask the user to tap the tag
document.getElementById('statusText').innerText = 'Tap the tag to the back of your smartphone and hold it for a while.';
document.getElementById('statusText').innerText =
'Tap the tag to the back of your smartphone and hold it for a while. ' +
'Using execution method: ' + execMethod;
} else if (cause === "retry") {
// this callback is invoked when there is a communication error
// the executeNFCCommand() call will be still running and the frontend

View File

@@ -5,7 +5,7 @@
*/
const {
execHaloCmdWeb
execHaloCmdWeb, detectMethod
} = require("../drivers/common");
const {
HaloTagError,
@@ -34,6 +34,7 @@ module.exports = {
// for web usage
execHaloCmdWeb,
haloFindBridge,
haloGetDefaultMethod: detectMethod,
// for bridge demo
haloCreateWs,