-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
node-web-eid-ws.js
98 lines (94 loc) · 3.05 KB
/
node-web-eid-ws.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
'use strict'
const trace = false
const WebSocket = require('ws')
const APPURL = 'wss://app.web-eid.com:42123'
const ORIGIN = 'https://example.com'
function getNonce (l) {
if (l === undefined) {
l = 24
}
var val = ''
var hex = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVXYZ'
for (var i = 0; i < l; i++) val += hex.charAt(Math.floor(Math.random() * hex.length))
return val
}
// Return a promise that resolves to an object
// that has a .send() method that returns a promise
// that resolves to the reply from app
function WSConnect (url, options) {
return new Promise(function (resolve, reject) {
var ws = {}
ws.socket = new WebSocket(APPURL, {origin: ORIGIN})
ws.promises = {}
ws.socket.onerror = function (event) {
reject(event)
}
ws.socket.onopen = function () {
ws.socket.onmessage = function (message) {
var msg = JSON.parse(message.data)
if (trace) { console.log('RECV', JSON.stringify(msg)) }
if (msg.id in ws.promises) {
if (!msg.error) {
ws.promises[msg.id].resolve(msg)
} else {
ws.promises[msg.id].reject(new Error('Web eID status: ' + msg.error))
}
delete ws.promises[msg.id]
}
}
ws.send = function (msg) {
return new Promise(function (resolve, reject) {
var id = getNonce()
msg.id = id
if (trace) { console.log('SEND', JSON.stringify(msg)) }
ws.socket.send(JSON.stringify(msg))
ws.promises[id] = {resolve: resolve, reject: reject}
})
}
ws.disconnect = function () {
ws.socket.close()
}
resolve(ws)
}
})
}
// app is a function that takes as an argument a function
// which takes an APDU an returns a promise that resolves to the APDU response
function runapp (app, atrs) {
// convert ATR-s
var baseatrs = []
// FIXME: fix this in test-node.js
for (var atr in atrs) {
baseatrs.push(Buffer.from(atrs[atr], 'hex').toString('base64'))
}
return WSConnect(APPURL, {}).then(function (ws) {
var readername
return ws.send({'SCardConnect': {'protocol': '*', 'atrs': baseatrs}}).then(function (reader) {
var atrbin = Buffer.from(reader.atr, 'base64')
if (baseatrs.indexOf(atrbin) === -1) {
console.log('This is not the card we wanted')
}
readername = reader.reader
// Reader is currently a dummy.
function transmit (apdu) {
return ws.send({'SCardTransmit': {'reader': readername, 'bytes': apdu.toString('base64')}}).then(function (response) {
return Buffer.from(response.bytes, 'base64')
})
}
return app(transmit)
}).then(function (blah) {
return ws.send({'SCardDisconnect': {reader: readername}}).then(function () {
readername = undefined
ws.disconnect()
})
}).catch(function (reason) {
if (readername) {
ws.send({'SCardDisconnect': {reader: readername}}).then(function () {
ws.disconnect()
})
}
throw reason
})
})
}
module.exports.run = runapp