@osimatic/helpers-js 1.0.34 → 1.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{changelog.txt → CHANGELOG} +4 -1
- package/network.js +8 -7
- package/package.json +1 -1
- package/web_rtc.js +103 -0
- package/.idea/helpers-js.iml +0 -8
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
|
@@ -42,4 +42,7 @@ FormHelper.logRequestFailure(status, exception) -> HTTPRequest.logJqueryRequestF
|
|
|
42
42
|
Location.checkCoordinates(...) -> GeographicCoordinates.check(...) (car Location est déjà défini en javascript natif)
|
|
43
43
|
|
|
44
44
|
FormHelper.getFormErrorTextBis(...) -> FormHelper.getFormErrorText(...)
|
|
45
|
-
FormHelper.displayFormErrorsFromXhr(form, btnSubmit, xhr) -> FormHelper.displayFormErrors(form, btnSubmit, xhr.responseJSON)
|
|
45
|
+
FormHelper.displayFormErrorsFromXhr(form, btnSubmit, xhr) -> FormHelper.displayFormErrors(form, btnSubmit, xhr.responseJSON)
|
|
46
|
+
|
|
47
|
+
1.0.35 :
|
|
48
|
+
ajout méthode HTTPRequest.init() (charge le polyfill de fetch)
|
package/network.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
|
|
2
2
|
class HTTPRequest {
|
|
3
|
+
static init(){
|
|
4
|
+
require('whatwg-fetch'); //fetch polyfill loaded in window.fetch
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
static setRefreshTokenUrl(url) {
|
|
4
8
|
this.refreshTokenUrl = url;
|
|
5
9
|
}
|
|
10
|
+
|
|
6
11
|
static setRefreshTokenCallback(callback) {
|
|
7
12
|
this.refreshTokenCallback = callback;
|
|
8
13
|
}
|
|
@@ -107,8 +112,7 @@ class HTTPRequest {
|
|
|
107
112
|
return;
|
|
108
113
|
}
|
|
109
114
|
|
|
110
|
-
//l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
|
|
111
|
-
console.error('fetch\'s polyfill used');
|
|
115
|
+
//l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé dans la méthode init
|
|
112
116
|
$.ajax({
|
|
113
117
|
type: 'GET',
|
|
114
118
|
url: url,
|
|
@@ -188,9 +192,7 @@ class HTTPRequest {
|
|
|
188
192
|
return;
|
|
189
193
|
}
|
|
190
194
|
|
|
191
|
-
//l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
|
|
192
|
-
console.error('fetch\'s polyfill used');
|
|
193
|
-
|
|
195
|
+
//l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé dans la méthode init
|
|
194
196
|
let ajaxOptions = {
|
|
195
197
|
type: 'GET',
|
|
196
198
|
url: url,
|
|
@@ -279,8 +281,7 @@ class HTTPRequest {
|
|
|
279
281
|
return;
|
|
280
282
|
}
|
|
281
283
|
|
|
282
|
-
//l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
|
|
283
|
-
console.error('fetch\'s polyfill used');
|
|
284
|
+
//l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé dans la méthode init
|
|
284
285
|
$.ajax({
|
|
285
286
|
type: 'POST',
|
|
286
287
|
url: url,
|
package/package.json
CHANGED
package/web_rtc.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
class WebRTC {
|
|
2
|
+
static init (turnSecret, turnUrl, stunUrl) {
|
|
3
|
+
this.turnSecret = turnSecret;
|
|
4
|
+
this.turnUrl = turnUrl;
|
|
5
|
+
this.stunUrl = stunUrl;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
static offer(stream, onICECandidateCallback) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
try {
|
|
11
|
+
let { username, password } = this.getTurnCredentials();
|
|
12
|
+
let peerConn = new RTCPeerConnection(
|
|
13
|
+
{
|
|
14
|
+
iceServers: [
|
|
15
|
+
{ urls: this.turnUrl, username: username, credential: password },
|
|
16
|
+
{ urls: this.stunUrl }
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
stream.getTracks().forEach(track => peerConn.addTrack(track, stream));
|
|
22
|
+
|
|
23
|
+
peerConn.onicecandidate = (event) => onICECandidateCallback(event);
|
|
24
|
+
|
|
25
|
+
peerConn.createOffer()
|
|
26
|
+
.then(sdp => peerConn.setLocalDescription(sdp))
|
|
27
|
+
.then(() => resolve(peerConn));
|
|
28
|
+
} catch (error) {
|
|
29
|
+
reject(error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static answer (remoteDescription, onTrackCallback, onICECandidateCallback) {
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
try {
|
|
37
|
+
let { username, password } = this.getTurnCredentials();
|
|
38
|
+
let peerConn = new RTCPeerConnection(
|
|
39
|
+
{
|
|
40
|
+
iceServers: [
|
|
41
|
+
{ urls: this.turnUrl, username: username, credential: password },
|
|
42
|
+
{ urls: this.stunUrl }
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
peerConn.ontrack = event => onTrackCallback(event);
|
|
48
|
+
peerConn.onicecandidate = event => onICECandidateCallback(event);
|
|
49
|
+
|
|
50
|
+
peerConn.setRemoteDescription(remoteDescription)
|
|
51
|
+
.then(() => peerConn.createAnswer())
|
|
52
|
+
.then(sdp => peerConn.setLocalDescription(sdp))
|
|
53
|
+
.then(() => resolve(peerConn));
|
|
54
|
+
} catch (error) {
|
|
55
|
+
reject(error);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static disconnectPeer(peerConn) {
|
|
61
|
+
if (peerConn) {
|
|
62
|
+
peerConn.onicecandidate = null;
|
|
63
|
+
peerConn.ontrack = null;
|
|
64
|
+
|
|
65
|
+
if (peerConn.signalingState != 'closed') {
|
|
66
|
+
peerConn.getSenders().forEach(sender => peerConn.removeTrack(sender));
|
|
67
|
+
peerConn.close();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
peerConn = null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return peerConn;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/*
|
|
77
|
+
The idea is that WebRTC (or other) clients receive temporary TURN credentials where the user name is comprised of the (Unix)
|
|
78
|
+
expiry timestamp and the password is derived from a secret shared between the service generating those credentials and eturnal.
|
|
79
|
+
The service offering the credentials performs a Base64(HMAC-SHA1($secret, $timestamp)) operation to generate the ephemeral password,
|
|
80
|
+
and eturnal does the same to verify it.
|
|
81
|
+
|
|
82
|
+
https://eturnal.net/documentation/
|
|
83
|
+
https://datatracker.ietf.org/doc/html/draft-uberti-behave-turn-rest-00
|
|
84
|
+
https://stackoverflow.com/questions/35766382/coturn-how-to-use-turn-rest-api
|
|
85
|
+
*/
|
|
86
|
+
static getTurnCredentials() {
|
|
87
|
+
try {
|
|
88
|
+
let crypto = require('crypto');
|
|
89
|
+
let username = String(parseInt(Date.now() / 1000) + 24 * 3600);
|
|
90
|
+
let hmac = crypto.createHmac('sha1', this.turnSecret);
|
|
91
|
+
|
|
92
|
+
hmac.setEncoding('base64');
|
|
93
|
+
hmac.write(username);
|
|
94
|
+
hmac.end();
|
|
95
|
+
|
|
96
|
+
return { username: username, password: hmac.read() };
|
|
97
|
+
} catch(error) {
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
module.exports = { WebRTC };
|
package/.idea/helpers-js.iml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="WEB_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager">
|
|
4
|
-
<content url="file://$MODULE_DIR$" />
|
|
5
|
-
<orderEntry type="inheritedJdk" />
|
|
6
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
7
|
-
</component>
|
|
8
|
-
</module>
|
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/helpers-js.iml" filepath="$PROJECT_DIR$/.idea/helpers-js.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|