-
Notifications
You must be signed in to change notification settings - Fork 0
/
signalk.mjs
99 lines (92 loc) · 2.89 KB
/
signalk.mjs
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
99
import fetch from 'node-fetch';
import { Bonjour } from 'bonjour-service';
let clientStatus = {};
export function setStatus(status) {
clientStatus = status;
}
export function getStatus(status) {
return clientStatus;
}
export function discover() {
const bonjour = new Bonjour();
return new Promise((resolve, reject) => {
bonjour.find({
type: 'signalk-http',
}, (service) => {
if (!service || !service.host) {
reject(new Error('No service found'));
return;
}
resolve(service);
});
});
}
export function authenticate(skHost) {
if (clientStatus.accessToken) {
// We already have token, can continue
// TODO: Verify that token is still valid and has "admin" privs
return Promise.resolve();
}
if (!clientStatus.accessRequest) {
console.log('Requesting Signak K access token');
const url = `http://${skHost}/signalk/v1/access/requests`;
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
clientId,
description: clientDesc,
}),
})
.then((res) => res.json())
.then((accessRequest) => {
clientStatus.accessRequest = accessRequest.href;
return Promise.reject(new Error('Access token requested, please approve via Signal K admin interface'));
});
}
console.log('Checking Signal K access status');
const url = `http://${skHost}${clientStatus.accessRequest}`;
return fetch(url)
.then((res) => res.json())
.then((requestStatus) => {
console.log(requestStatus);
if (requestStatus.state === 'PENDING') {
return Promise.reject(new Error('Access token request is pending, please approve via Signal K admin interface'));
}
if (requestStatus.state !== 'COMPLETED') {
return Promise.reject(new Error(`Unknown request state ${requestStatus.state}`));
}
if (requestStatus.statusCode !== 200) {
delete clientStatus.accessRequest;
return Promise.reject(new Error(`Access request failed with code ${requestStatus.statusCode}`));
}
if (requestStatus.accessRequest.permission === 'DENIED') {
delete clientStatus.accessRequest;
return Promise.reject(new Errot('Access request has been denied in Signal K'));
}
delete clientStatus.accessRequest;
clientStatus.accessToken = requestStatus.accessRequest.token;
return Promise.resolve();
});
}
export function request(url, headers = {}) {
const options = {
headers: {
...headers,
'Content-Type': 'application/json',
Authorization: `JWT ${clientStatus.accessToken}`,
},
};
return fetch(url, options)
.then((res) => {
if (!res.ok) {
return res.text()
.then((text) => {
throw new Error(`Request failed with ${res.status}: ${text}`);
});
}
return res.json();
});
}