-
Notifications
You must be signed in to change notification settings - Fork 906
/
api.js
85 lines (73 loc) · 2.59 KB
/
api.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
import * as request from 'd3-request';
import { sha256 } from 'js-sha256';
import Cookies from 'js-cookie';
import { isLocalhost, isProduction } from './environment';
import thirdPartyServices from '../services/thirdparty';
function isRemoteParam() {
return (new URLSearchParams(window.location.search)).get('remote') === 'true';
}
// Use local endpoint only if ALL of the following conditions are true:
// 1. The app is running on localhost
// 2. The `remote` search param hasn't been explicitly set to true
// 3. Document domain has a non-empty value
function isUsingLocalEndpoint() {
return isLocalhost() && !isRemoteParam() && document.domain !== '';
}
export function getEndpoint() {
return isUsingLocalEndpoint() ? 'http://localhost:9000' : 'https://api.electricitymap.org';
}
export function protectedJsonRequest(path) {
const url = getEndpoint() + path;
const token = isUsingLocalEndpoint() ? 'development' : ELECTRICITYMAP_PUBLIC_TOKEN;
const timestamp = new Date().getTime();
return new Promise((resolve, reject) => {
request.json(url)
.header('electricitymap-token', Cookies.get('electricitymap-token'))
.header('x-request-timestamp', timestamp)
.header('x-signature', sha256(token + path + timestamp))
.get(null, (err, res) => {
if (err) {
reject(err);
} else if (!res || !res.data) {
reject(new Error(`Empty response received for ${url}`));
} else {
resolve(res.data);
}
});
});
}
export function textRequest(path) {
const url = getEndpoint() + path;
return new Promise((resolve, reject) => {
request.text(url).get(null, (err, res) => {
if (err) {
reject(err);
} else if (!res) {
reject(new Error(`Empty response received for ${url}`));
} else {
resolve(res);
}
});
});
}
export function handleRequestError(err) {
if (err) {
if (err.target) {
const {
responseText,
responseURL,
status,
statusText,
} = err.target;
// Avoid catching HTTPError 0
// The error will be empty, and we can't catch any more info for security purposes.
// See http://stackoverflow.com/questions/4844643/is-it-possible-to-trap-cors-errors
if (!status) return;
// Also ignore 5xx errors as they are usually caused by server downtime and are not useful to track.
if (status >= 500 && status <= 599) return;
thirdPartyServices.trackError(new Error(`HTTPError ${status} ${statusText} at ${responseURL}: ${responseText}`));
} else {
thirdPartyServices.trackError(err);
}
}
}