@osimatic/helpers-js 1.0.33 → 1.0.36

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.
@@ -39,4 +39,10 @@ remplacer l'utilisation des variables httpHeaders / _httpHeaders par HTTPRequest
39
39
  FlashMessage.displayRequestFailure(status, exception, modal) -> FlashMessage.displayError(labelErrorOccured, modal)
40
40
  FormHelper.logRequestFailure(status, exception) -> HTTPRequest.logJqueryRequestFailure(jqxhr, status, exception) (le log de l'erreur est devenu inutile car fait de base dans la classe HTTPRequest)
41
41
 
42
- Location.checkCoordinates(...) -> GeographicCoordinates.check(...) (car Location est déjà défini en javascript natif)
42
+ Location.checkCoordinates(...) -> GeographicCoordinates.check(...) (car Location est déjà défini en javascript natif)
43
+
44
+ FormHelper.getFormErrorTextBis(...) -> FormHelper.getFormErrorText(...)
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/form_helper.js CHANGED
@@ -183,16 +183,6 @@ class FormHelper {
183
183
  }
184
184
 
185
185
  static getFormErrorText(errors) {
186
- let errorLabels = '';
187
- for (let property in errors) {
188
- if (typeof errors[property] != 'function') {
189
- errorLabels += '<span>' + errors[property] + '</span><br>';
190
- }
191
- }
192
- return errorLabels;
193
- }
194
-
195
- static getFormErrorTextBis(errors) {
196
186
  let errorLabels = '';
197
187
  for (let property in errors) {
198
188
  // console.log(property);
@@ -208,7 +198,7 @@ class FormHelper {
208
198
  }
209
199
 
210
200
  static displayFormErrors(form, btnSubmit, errors, errorWrapperDiv) {
211
- this.displayFormErrorsFromText(form, this.getFormErrorTextBis(errors), errorWrapperDiv);
201
+ this.displayFormErrorsFromText(form, this.getFormErrorText(errors), errorWrapperDiv);
212
202
  if (btnSubmit != null) {
213
203
  if (btnSubmit.buttonLoader != null) {
214
204
  btnSubmit.buttonLoader('reset');
@@ -218,10 +208,6 @@ class FormHelper {
218
208
  }
219
209
  }
220
210
 
221
- static displayFormErrorsFromXhr(form, btnSubmit, xhr) {
222
- this.displayFormErrors(form, btnSubmit, xhr.responseJSON);
223
- }
224
-
225
211
  static displayFormErrorsFromText(form, errorLabels, errorWrapperDiv) {
226
212
  let errorDiv = '<div class="alert alert-danger form_errors">'+errorLabels+'</div>';
227
213
 
@@ -292,6 +278,11 @@ class FormHelper {
292
278
  console.log('request failure. Status: '+status+' ; Exception: '+exception);
293
279
  }
294
280
 
281
+ /** @deprecated **/
282
+ static displayFormErrorsFromXhr(form, btnSubmit, xhr) {
283
+ this.displayFormErrors(form, btnSubmit, xhr.responseJSON);
284
+ }
285
+
295
286
  }
296
287
 
297
288
  module.exports = { FormHelper };
package/network.js CHANGED
@@ -1,24 +1,18 @@
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
  }
9
14
 
10
- static setHeader(key, value) {
11
- if (typeof this.headers == 'undefined') {
12
- this.headers = {};
13
- }
14
- this.headers[key] = value;
15
- }
16
-
17
15
  static getHeaders(asObject) {
18
- //if (typeof httpHeaders != 'undefined') {
19
- // return httpHeaders;
20
- //}
21
-
22
16
  if (typeof this.headers == 'undefined') {
23
17
  this.headers = {};
24
18
  }
@@ -31,9 +25,34 @@ class HTTPRequest {
31
25
  Object.entries(this.headers).forEach(([key, value]) => {
32
26
  httpHeaders.append(key, value);
33
27
  });
28
+
34
29
  return httpHeaders;
35
30
  }
36
31
 
32
+ static getHeader(key) {
33
+ if (typeof this.headers == 'undefined') {
34
+ this.headers = {};
35
+ }
36
+
37
+ return this.headers[key];
38
+ }
39
+
40
+ static setHeader(key, value) {
41
+ if (typeof this.headers == 'undefined') {
42
+ this.headers = {};
43
+ }
44
+
45
+ this.headers[key] = value;
46
+ }
47
+
48
+ static setAuthorizationHeader(accessToken) {
49
+ if (typeof this.headers == 'undefined') {
50
+ this.headers = {};
51
+ }
52
+
53
+ this.headers['Authorization'] = 'Bearer ' + accessToken;
54
+ }
55
+
37
56
  static formatQueryString(data) {
38
57
  if (data == null) {
39
58
  return '';
@@ -82,49 +101,52 @@ class HTTPRequest {
82
101
  //console.log(url, jsonData);
83
102
  //console.log(response.status, response.statusText, jsonData['error']);
84
103
 
85
- if (response.status == 401 && (response.statusText === "Expired JWT Token" || typeof jsonData['error'] != 'undefined' && jsonData['error'] === 'expired_token')) {
104
+ if (response.status == 401 && (response.statusText === 'Expired JWT Token' || typeof jsonData['error'] != 'undefined' && jsonData['error'] === 'expired_token')) {
86
105
  HTTPRequest.refreshToken(() => HTTPRequest.get(url, data, successCallback, errorCallback));
87
106
  return;
88
107
  }
89
108
 
90
109
  if (response.ok) {
91
- successCallback(jsonData);
110
+ successCallback(jsonData, response);
92
111
  return;
93
112
  }
94
113
  }
95
114
  catch (e) {
96
115
  console.error(e);
97
116
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
98
- errorCallback(response, response.status, e);
117
+ errorCallback(response);
99
118
  }
100
119
  return;
101
120
  }
102
121
 
103
122
  HTTPRequest.logRequestFailure(response, jsonData);
104
123
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
105
- errorCallback(response, response.status, null, jsonData);
124
+ errorCallback(response, jsonData);
106
125
  }
107
126
  return;
108
127
  }
109
128
 
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');
129
+ //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
130
  $.ajax({
113
131
  type: 'GET',
114
132
  url: url,
115
133
  headers: HTTPRequest.getHeaders(true),
116
134
  dataType: 'json',
117
135
  cache: false,
118
- success: (data) => successCallback(data),
136
+ success: (data, status, jqxhr) => {
137
+ if (typeof successCallback != 'undefined' && successCallback != null) {
138
+ successCallback(data, jqxhr);
139
+ }
140
+ },
119
141
  error: (jqxhr, status, errorThrown) => {
120
- if (typeof jqxhr.responseJSON != 'undefined' && jqxhr.responseJSON.code == 401 && (jqxhr.responseJSON.message === "Expired JWT Token" || (typeof jqxhr.responseJSON['error'] != 'undefined' && jqxhr.responseJSON['error'] === 'expired_token' ))) {
142
+ if (jqxhr.status == 401 && (jqxhr.statusText === 'Expired JWT Token' || (typeof jqxhr.responseJSON['message'] != 'undefined' && jqxhr.responseJSON['message'] === 'Expired JWT Token') || (typeof jqxhr.responseJSON['error'] != 'undefined' && jqxhr.responseJSON['error'] === 'expired_token' ))) {
121
143
  HTTPRequest.refreshToken(() => HTTPRequest.get(url, data, successCallback, errorCallback));
122
144
  return;
123
145
  }
124
146
 
125
147
  HTTPRequest.logJqueryRequestFailure(jqxhr, status, errorThrown);
126
148
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
127
- errorCallback(jqxhr, status, errorThrown);
149
+ errorCallback(jqxhr, jqxhr.responseJSON);
128
150
  }
129
151
  }
130
152
  });
@@ -157,7 +179,7 @@ class HTTPRequest {
157
179
  /*console.log(url);
158
180
  console.log(blobData);*/
159
181
 
160
- if (response.status == 401 && response.statusText === "Expired JWT Token") {
182
+ if (response.status == 401 && response.statusText === 'Expired JWT Token') {
161
183
  HTTPRequest.refreshToken(() => HTTPRequest.download(url, data, errorCallback, completeCallback, method));
162
184
  return;
163
185
  }
@@ -168,26 +190,23 @@ class HTTPRequest {
168
190
  else {
169
191
  HTTPRequest.logRequestFailure(response, null);
170
192
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
171
- errorCallback(response, response.status, null);
193
+ errorCallback(response);
172
194
  }
173
195
  }
174
196
  }
175
197
  catch (e) {
176
198
  console.error(e);
177
199
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
178
- errorCallback(response, response.status, e);
200
+ errorCallback(response);
179
201
  }
180
202
  }
181
203
  if (typeof completeCallback != 'undefined' && completeCallback != null) {
182
- completeCallback(response, response.status);
204
+ completeCallback(response);
183
205
  }
184
206
  return;
185
207
  }
186
208
 
187
- //l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
188
- console.error('fetch\'s polyfill used');
189
-
190
-
209
+ //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
191
210
  let ajaxOptions = {
192
211
  type: 'GET',
193
212
  url: url,
@@ -207,19 +226,19 @@ class HTTPRequest {
207
226
  $.ajax(Object.assign({...ajaxOptions}, {
208
227
  success: (data, status, jqxhr) => File.download(data, jqxhr.getResponseHeader('Content-Type'), jqxhr.getResponseHeader('Content-Disposition')),
209
228
  error: (jqxhr, status, errorThrown) => {
210
- if (typeof jqxhr.responseJSON != 'undefined' && jqxhr.responseJSON.code == 401 && (jqxhr.responseJSON.message === "Expired JWT Token" || (typeof jqxhr.responseJSON['error'] != 'undefined' && jqxhr.responseJSON['error'] === 'expired_token' ))) {
229
+ if (jqxhr.status == 401 && (jqxhr.statusText === 'Expired JWT Token' || (typeof jqxhr.responseJSON['message'] != 'undefined' && jqxhr.responseJSON['message'] === 'Expired JWT Token') || (typeof jqxhr.responseJSON['error'] != 'undefined' && jqxhr.responseJSON['error'] === 'expired_token' ))) {
211
230
  HTTPRequest.refreshToken(() => HTTPRequest.download(url, data, errorCallback, completeCallback, method));
212
231
  return;
213
232
  }
214
233
 
215
234
  HTTPRequest.logJqueryRequestFailure(jqxhr, status, errorThrown);
216
235
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
217
- errorCallback(jqxhr, status, errorThrown);
236
+ errorCallback(jqxhr);
218
237
  }
219
238
  },
220
- complete: (jqxhr, status) => {
239
+ complete: (jqxhr) => {
221
240
  if (typeof completeCallback != 'undefined' && completeCallback != null) {
222
- completeCallback(jqxhr, status);
241
+ completeCallback(jqxhr);
223
242
  }
224
243
  }
225
244
  }));
@@ -228,7 +247,7 @@ class HTTPRequest {
228
247
  static async post(url, formData, successCallback, errorCallback, formErrorCallback) {
229
248
  formData = this.formatFormData(formData);
230
249
 
231
- if (window.fetch && false) {
250
+ if (window.fetch) {
232
251
  const response = await fetch(url, {
233
252
  method: 'POST',
234
253
  body: formData,
@@ -239,43 +258,44 @@ class HTTPRequest {
239
258
 
240
259
  let jsonData = {};
241
260
  try {
242
- jsonData = await response.json();
261
+ if (response.statusText !== 'No Content') {
262
+ jsonData = await response.json();
263
+ }
243
264
  //console.log(url, jsonData);
244
265
 
245
- if (response.status == 401 && url !== HTTPRequest.refreshTokenUrl && (response.statusText === "Expired JWT Token" || (typeof jsonData['error'] != 'undefined' && jsonData['error'] === 'expired_token'))) {
266
+ if (response.status == 401 && url !== HTTPRequest.refreshTokenUrl && (response.statusText === 'Expired JWT Token' || (typeof jsonData['error'] != 'undefined' && jsonData['error'] === 'expired_token'))) {
246
267
  HTTPRequest.refreshToken(() => HTTPRequest.post(url, formData, successCallback, errorCallback, formErrorCallback));
247
268
  return;
248
269
  }
249
270
 
250
271
  if (response.ok) {
251
272
  if (typeof successCallback != 'undefined' && successCallback != null) {
252
- successCallback(jsonData);
273
+ successCallback(jsonData, response);
253
274
  }
254
275
  return;
255
276
  }
256
277
 
257
278
  if (response.status == 400 && typeof formErrorCallback != 'undefined' && formErrorCallback != null) {
258
- formErrorCallback(response, response.status, jsonData);
279
+ formErrorCallback(jsonData, response);
259
280
  return;
260
281
  }
261
282
  }
262
283
  catch (e) {
263
284
  console.error(e);
264
285
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
265
- errorCallback(response, response.status, e);
286
+ errorCallback(response);
266
287
  }
267
288
  return;
268
289
  }
269
290
 
270
291
  HTTPRequest.logRequestFailure(response, jsonData);
271
292
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
272
- errorCallback(response, response.status, null, jsonData);
293
+ errorCallback(response, jsonData);
273
294
  }
274
295
  return;
275
296
  }
276
297
 
277
- //l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
278
- console.error('fetch\'s polyfill used');
298
+ //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
279
299
  $.ajax({
280
300
  type: 'POST',
281
301
  url: url,
@@ -285,24 +305,24 @@ class HTTPRequest {
285
305
  cache: false,
286
306
  contentType: false,
287
307
  processData: false,
288
- success: (data) => {
308
+ success: (data, status, jqxhr) => {
289
309
  if (typeof successCallback != 'undefined' && successCallback != null) {
290
- successCallback(data);
310
+ successCallback(data, jqxhr);
291
311
  }
292
312
  },
293
313
  error: (jqxhr, status, errorThrown) => {
294
- if (typeof jqxhr.responseJSON != 'undefined' && jqxhr.responseJSON.code == 401 && url !== HTTPRequest.refreshTokenUrl && (jqxhr.responseJSON.message === "Expired JWT Token" || (typeof jqxhr.responseJSON['error'] != 'undefined' && jqxhr.responseJSON['error'] === 'expired_token' ))) {
314
+ if (url !== HTTPRequest.refreshTokenUrl && jqxhr.status == 401 && (jqxhr.statusText === 'Expired JWT Token' || (typeof jqxhr.responseJSON['message'] != 'undefined' && jqxhr.responseJSON['message'] === 'Expired JWT Token') || (typeof jqxhr.responseJSON['error'] != 'undefined' && jqxhr.responseJSON['error'] === 'expired_token' ))) {
295
315
  HTTPRequest.refreshToken(() => HTTPRequest.post(url, formData, successCallback, errorCallback, formErrorCallback));
296
316
  return;
297
317
  }
298
318
  if (jqxhr.status == 400 && typeof formErrorCallback != 'undefined' && formErrorCallback != null) {
299
- formErrorCallback(jqxhr, status, errorThrown);
319
+ formErrorCallback(jqxhr.responseJSON, jqxhr);
300
320
  return;
301
321
  }
302
322
 
303
323
  HTTPRequest.logJqueryRequestFailure(jqxhr, status, errorThrown);
304
324
  if (typeof errorCallback != 'undefined' && errorCallback != null) {
305
- errorCallback(jqxhr, status, errorThrown);
325
+ errorCallback(jqxhr, jqxhr.responseJSON);
306
326
  }
307
327
  }
308
328
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osimatic/helpers-js",
3
- "version": "1.0.33",
3
+ "version": "1.0.36",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
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 };
@@ -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>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
- </component>
6
- </project>