@viibe/impulse-integration-js 2.3.1 → 2.3.4-alpha2

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.
@@ -1,3 +1,2 @@
1
1
  {
2
- "actions": []
3
2
  }
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (()=>{var t={579:t=>{function e(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}var n=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.handlers=[],this.host=e.host,this.origin=/^localhost/.test(this.host)?"http://".concat(this.host):"https://".concat(this.host),this.source=e.source,window.addEventListener("message",this.onMessage.bind(this))}var n,o;return n=t,o=[{key:"createCallIframe",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!this.host)throw new Error("fillHost");if(!this.source)throw new Error("fillSource");var e=this.createCallUrl(t),n=document.createElement("iframe");return n.name="viibe-"+Math.floor(1e4*Math.random()),n.style="border: 0;width: calc(100% - 1rem);margin: 0.5rem;",n.src=e,n.allow="geolocation;autoplay;microphone;camera;midi;encrypted-media;clipboard-write;",n}},{key:"createCallUrl",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.clipboard,n=void 0!==e&&e,o=t.components,a=t.links,i=t.o2m,r=void 0!==i&&i,s=t.ticket,c=t.token,l=t.locale,u="".concat(this.origin,"/integration/features/call"),d=new URLSearchParams({resize:"true",source:this.source});if(null!=s&&s.title&&d.set("title",s.title),null!=s&&s.integration&&d.set("thirdPartyId",s.integration.id),a){var h=a instanceof Array?a.map((function(t){return"".concat(t.category,":").concat(t.value)})).join(","):String(a);d.set("links",h)}if(c&&d.set("token",c),l&&d.set("locale",l),o){var f=o instanceof Array?o.join(","):String(o);d.set("components",f)}return d.set("clipboard",Boolean(n)),d.set("o2m",Boolean(r)),u+"?".concat(d)}},{key:"isViibeEvent",value:function(t){return Boolean(t.isTrusted&&0===t.origin.indexOf(this.origin))}},{key:"dispatch",value:function(t,e,n){return this.handlers.filter((function(e){return e.eventName===t&&(!e.windowName||e.windowName===n)})).map((function(t){return t.func(e)}))}},{key:"onMessage",value:function(t){return this.isViibeEvent(t)?t.data&&t.data.event&&t.data.payload?this.dispatch(t.data.event,t.data.payload,t.data.windowName):t.data&&t.data.token?this.dispatch("authentication:token",t.data.token):t.data&&t.data.error?this.dispatch("authentication:error",t.data.error):null:null}},{key:"on",value:function(t,e,n){"string"==typeof t&&"function"==typeof e&&void 0===n&&(n=e,e=t,t=null);var o={eventName:e,windowName:t?t.name:null,func:n};this.handlers.push(o)}},{key:"authenticate",value:function(t){var e=this,n="".concat(this.origin,"/api/auth/login/").concat(t),o=window.screen.width/2-240,a=window.screen.height/2-300,i=["toolbar=no","location=no","directories=no","status=no","menubar=no","scrollbars=no","resizable=no","copyhistory=no","width=".concat(480),"height=".concat(600),"top=".concat(a),"left=".concat(o)];return new Promise((function(t,o){var a=window.open(n,"Authorization",i.join(", "));a||o("Failed to open window");var r=setInterval((function(){a.closed&&(c(),s())}),100),s=function(){o("User closed window")},c=function(){window.removeEventListener("message",l),clearInterval(r)},l=function(n){if(!e.isViibeEvent(n))return null;n.data.token&&(c(),t(n.data.token)),n.data.error&&(c(),o(n.data.error))};window.addEventListener("message",l)}))}}],o&&e(n.prototype,o),t}();"undefined"!=typeof window&&(window.Viibe=n),t.exports=n}},e={},n=function n(o){var a=e[o];if(void 0!==a)return a.exports;var i=e[o]={exports:{}};return t[o](i,i.exports,n),i.exports}(579);module.exports=n})();
1
+ (()=>{var t={579:t=>{function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function o(t,e,o){return e&&n(t.prototype,e),o&&n(t,o),t}function i(t){return function(e){return Boolean(e.isTrusted&&0===e.origin.indexOf(t))}}function a(t){var e=new URL(t),n="".concat(e.protocol,"://").concat(e.host),o=window.screen.width/2-240,a=window.screen.height/2-300,r=["toolbar=no","location=no","directories=no","status=no","menubar=no","scrollbars=no","resizable=no","copyhistory=no","width=".concat(480),"height=".concat(600),"top=".concat(a),"left=".concat(o)];return new Promise((function(e,o){var a=window.open(t,"Authorization",r.join(", "));a||o("Failed to open window");var c=setInterval((function(){a.closed&&(l(),s())}),100),s=function(){o("User closed window")},l=function(){window.removeEventListener("message",u),clearInterval(c)},u=function(t){if(!i(n)(t))return null;t.data.token&&(l(),e(t.data.token)),t.data.error&&(l(),o(t.data.error))};window.addEventListener("message",u)}))}var r,c,s,l=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"auth.viibe.tech";e(this,t),this.host=n}return o(t,[{key:"loginZendesk",value:function(t){return a("https://".concat(this.host,"/auth/zendesk/login?subdomain=").concat(t))}}]),t}(),u=function(){function t(n){e(this,t),this.handlers=[],this.host=n.host,this.origin=/^localhost/.test(this.host)?"http://".concat(this.host):"https://".concat(this.host),this.source=n.source,this.isViibeEvent=i(this.origin),window.addEventListener("message",this.onMessage.bind(this))}return o(t,[{key:"createNotificationIframe",value:function(){if(!this.host)throw new Error("fillHost");if(!this.source)throw new Error("fillSource");var t=document.createElement("iframe");return t.name="viibe-"+Math.floor(1e4*Math.random()),t.style="border: 0;width: 0;",t.src="".concat(this.origin,"/integration/features/notifications"),t}},{key:"createCallIframe",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!this.host)throw new Error("fillHost");if(!this.source)throw new Error("fillSource");var n=this.createCallUrl(e),o=document.createElement("iframe");return o.name="viibe-"+Math.floor(1e4*Math.random()),o.style="border: 0;width: calc(100% - 1rem);margin: 0.5rem;",o.src=n,o.allow="geolocation;autoplay;microphone;camera;midi;encrypted-media;clipboard-write;",this.on(o,"document",(function(e){return t.onDocument(e)})),o}},{key:"createCallUrl",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.clipboard,n=void 0!==e&&e,o=t.components,i=t.links,a=t.o2m,r=void 0!==a&&a,c=t.ticket,s=t.token,l=t.locale,u=t.standalone,d="".concat(this.origin,"/integration/features/call"),h=new URLSearchParams({resize:"true",source:this.source});if(c&&c.title&&h.set("title",c.title),c&&c.integration&&h.set("thirdPartyId",c.integration.id),i){var f=i instanceof Array?i.map((function(t){return"".concat(t.category,":").concat(t.value)})).join(","):String(i);h.set("links",f)}if(s&&h.set("token",s),l&&h.set("locale",l),o){var v=o instanceof Array?o.join(","):String(o);h.set("components",v)}return u&&h.set("standalone",Boolean(u)),h.set("clipboard",Boolean(n)),h.set("o2m",Boolean(r)),d+"?".concat(h)}},{key:"dispatch",value:function(t,e,n){return this.handlers.filter((function(e){return e.eventName===t&&(!e.windowName||e.windowName===n)})).map((function(t){return t.func(e)}))}},{key:"onMessage",value:function(t){return this.isViibeEvent(t)?t.data&&t.data.event&&t.data.payload?this.dispatch(t.data.event,t.data.payload,t.data.windowName):t.data&&t.data.token?this.dispatch("authentication:token",t.data.token):t.data&&t.data.error?this.dispatch("authentication:error",t.data.error):null:null}},{key:"on",value:function(t,e,n){"string"==typeof t&&"function"==typeof e&&void 0===n&&(n=e,e=t,t=null);var o={eventName:e,windowName:t?t.name:null,func:n};this.handlers.push(o)}},{key:"onDocument",value:function(t){window.open(t.signed_url,"_blank")}},{key:"authenticate",value:function(t){return a("".concat(this.origin,"/api/auth/login/").concat(t))}}]),t}();s=l,(c="Auth")in(r=u)?Object.defineProperty(r,c,{value:s,enumerable:!0,configurable:!0,writable:!0}):r.Auth=s,"undefined"!=typeof window&&(window.Viibe=u),t.exports=u}},e={},n=function n(o){var i=e[o];if(void 0!==i)return i.exports;var a=e[o]={exports:{}};return t[o](a,a.exports,n),a.exports}(579);module.exports=n})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viibe/impulse-integration-js",
3
- "version": "2.3.1",
3
+ "version": "2.3.4-alpha2",
4
4
  "description": "ViiBE integration in js native",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
package/src/index.js CHANGED
@@ -1,5 +1,98 @@
1
+ function isFromOrigin(origin) {
2
+ return function (event) {
3
+ return Boolean(event.isTrusted && event.origin.indexOf(origin) === 0)
4
+ }
5
+ }
6
+
7
+ function openAuthPopup(src) {
8
+ const url = new URL(src);
9
+ const origin = `${url.protocol}://${url.host}`;
10
+
11
+ const width = 480
12
+ const height = 600
13
+ const TWO = 2
14
+
15
+ const left = (window.screen.width / TWO) - (width / TWO)
16
+ const top = (window.screen.height / TWO) - (height / TWO)
17
+ const windowParams = [
18
+ 'toolbar=no',
19
+ 'location=no',
20
+ 'directories=no',
21
+ 'status=no',
22
+ 'menubar=no',
23
+ 'scrollbars=no',
24
+ 'resizable=no',
25
+ 'copyhistory=no',
26
+ `width=${width}`,
27
+ `height=${height}`,
28
+ `top=${top}`,
29
+ `left=${left}`,
30
+ ]
31
+
32
+ return new Promise((resolve, reject) => {
33
+ const win = window.open(src, 'Authorization', windowParams.join(', '))
34
+
35
+ if (!win) {
36
+ reject('Failed to open window')
37
+ }
38
+
39
+ // pings the login window to check if it was closed
40
+ const closeCheck = setInterval(() => {
41
+ if (win.closed) {
42
+ destroy();
43
+ onClose();
44
+ }
45
+
46
+ }, 100)
47
+
48
+ // triggered if the window was closed
49
+ const onClose = () => {
50
+ reject('User closed window')
51
+ }
52
+
53
+ // completes the process, either because the user closes or because the authentication completed
54
+ // cleans intervals and event listeners
55
+ const destroy = () => {
56
+ window.removeEventListener('message', onMessage)
57
+ clearInterval(closeCheck)
58
+ }
59
+
60
+ // triggered when a message is received on the current window
61
+ const onMessage = event => {
62
+ if (!isFromOrigin(origin)(event)) {
63
+ return null
64
+ }
65
+ if (event.data.token) {
66
+ destroy();
67
+ resolve(event.data.token)
68
+ }
69
+ if (event.data.error) {
70
+ destroy();
71
+ reject(event.data.error)
72
+ }
73
+ }
74
+
75
+ window.addEventListener('message', onMessage)
76
+ })
77
+ }
78
+
79
+ class ViibeAuth {
80
+
81
+ // FIXME
82
+ constructor(host = 'auth.viibe.tech') {
83
+ this.host = host;
84
+ }
85
+
86
+ loginZendesk(subdomain) {
87
+ const url = `https://${this.host}/auth/zendesk/login?subdomain=${subdomain}`;
88
+ return openAuthPopup(url);
89
+ }
90
+ }
91
+
1
92
  class Viibe {
2
93
 
94
+ static Auth = ViibeAuth;
95
+
3
96
  /**
4
97
  * @typedef Handler
5
98
  * @type {object}
@@ -17,9 +110,22 @@ class Viibe {
17
110
  this.origin = /^localhost/.test(this.host) ? `http://${this.host}` : `https://${this.host}`
18
111
  this.source = options.source
19
112
 
113
+ this.isViibeEvent = isFromOrigin(this.origin);
114
+
20
115
  window.addEventListener('message', this.onMessage.bind(this))
21
116
  }
22
117
 
118
+ createNotificationIframe() {
119
+ if (!this.host) throw new Error('fillHost')
120
+ if (!this.source) throw new Error('fillSource')
121
+
122
+ const iframe = document.createElement('iframe')
123
+ iframe.name = 'viibe-' + Math.floor(Math.random() * 10000)
124
+ iframe.style = 'border: 0;width: 0;'
125
+ iframe.src = `${this.origin}/integration/features/notifications`
126
+ return iframe
127
+ }
128
+
23
129
  createCallIframe(options = {}) {
24
130
  if (!this.host) throw new Error('fillHost')
25
131
  if (!this.source) throw new Error('fillSource')
@@ -32,6 +138,8 @@ class Viibe {
32
138
  iframe.src = src
33
139
  iframe.allow = 'geolocation;autoplay;microphone;camera;midi;encrypted-media;clipboard-write;'
34
140
 
141
+ this.on(iframe, 'document', event => this.onDocument(event))
142
+
35
143
  return iframe
36
144
  }
37
145
 
@@ -43,7 +151,8 @@ class Viibe {
43
151
  o2m = false,
44
152
  ticket,
45
153
  token,
46
- locale
154
+ locale,
155
+ standalone,
47
156
  } = options
48
157
 
49
158
  let src = `${this.origin}/integration/features/call`
@@ -53,8 +162,8 @@ class Viibe {
53
162
  source: this.source,
54
163
  });
55
164
 
56
- if (ticket?.title) params.set('title', ticket.title)
57
- if (ticket?.integration) params.set('thirdPartyId', ticket.integration.id)
165
+ if (ticket && ticket.title) params.set('title', ticket.title)
166
+ if (ticket && ticket.integration) params.set('thirdPartyId', ticket.integration.id)
58
167
 
59
168
  if (links) {
60
169
  let linksParams = (links instanceof Array)
@@ -76,6 +185,9 @@ class Viibe {
76
185
  params.set('components', componentsParams)
77
186
  }
78
187
 
188
+ if (standalone) params.set('standalone', Boolean(standalone))
189
+
190
+
79
191
  params.set('clipboard', Boolean(clipboard))
80
192
  params.set('o2m', Boolean(o2m))
81
193
 
@@ -84,23 +196,19 @@ class Viibe {
84
196
  return src
85
197
  }
86
198
 
87
- isViibeEvent(event) {
88
- return Boolean(event.isTrusted && event.origin.indexOf(this.origin) === 0)
89
- }
90
-
91
199
  /**
92
200
  * Dispatches an event ie calls handlers corresponding to that event.
93
201
  * Handlers with not windowName will be triggered regardless of the origin windowName
94
202
  * Otherwise, the event will be triggered only if the handler windowName and the event windowName correspond
95
- *
96
- * @param {string} eventName
97
- * @param {any} payload
98
- * @param {string} windowName
99
- * @returns
203
+ *
204
+ * @param {string} eventName
205
+ * @param {any} payload
206
+ * @param {string} windowName
207
+ * @returns
100
208
  */
101
209
  dispatch(eventName, payload, windowName) {
102
210
  return this.handlers
103
- .filter(handler =>
211
+ .filter(handler =>
104
212
  handler.eventName === eventName
105
213
  && (!handler.windowName || (handler.windowName === windowName))
106
214
  )
@@ -109,8 +217,8 @@ class Viibe {
109
217
 
110
218
  /**
111
219
  * Handles postMessages / events received on the current window
112
- * @param {any} event
113
- * @returns
220
+ * @param {any} event
221
+ * @returns
114
222
  */
115
223
  onMessage(event) {
116
224
  if (!this.isViibeEvent(event)) {
@@ -134,16 +242,16 @@ class Viibe {
134
242
 
135
243
  /**
136
244
  * Registers an event handler.
137
- * Can be either called with 2 arguments (eventName and handler) to catch events from all iframes
245
+ * Can be either called with 2 arguments (eventName and handler) to catch events from all iframes
138
246
  * or with 3 arguments (iframe, eventName, handler) to catch events from only that iframe
139
- * @param {HTMLIFrameElement} [iframe]
140
- * @param {string} eventName
141
- * @param {Function} handler
247
+ * @param {HTMLIFrameElement} [iframe]
248
+ * @param {string} eventName
249
+ * @param {Function} handler
142
250
  */
143
251
  on(iframe, eventName, func) {
144
- if (typeof iframe === 'string'
145
- && typeof eventName === 'function'
146
- && typeof func === 'undefined') {
252
+ if (typeof iframe === 'string'
253
+ && typeof eventName === 'function'
254
+ && typeof func === 'undefined') {
147
255
  func = eventName;
148
256
  eventName = iframe;
149
257
  iframe = null;
@@ -157,80 +265,19 @@ class Viibe {
157
265
  this.handlers.push(handler);
158
266
  }
159
267
 
268
+ onDocument(document) {
269
+ window.open(document.signed_url, '_blank')
270
+ }
271
+
160
272
  /**
161
273
  * Initiates an oauth login in a popup using the passed provider
162
274
  * @param {string} provider A strategy name from the Viibe API (see /strategies API)
163
- * @returns
275
+ * @returns
164
276
  */
165
277
  authenticate(provider) {
166
278
  const src = `${this.origin}/api/auth/login/${provider}`
167
- const width = 480
168
- const height = 600
169
- const TWO = 2
170
-
171
- const left = (window.screen.width / TWO) - (width / TWO)
172
- const top = (window.screen.height / TWO) - (height / TWO)
173
- const windowParams = [
174
- 'toolbar=no',
175
- 'location=no',
176
- 'directories=no',
177
- 'status=no',
178
- 'menubar=no',
179
- 'scrollbars=no',
180
- 'resizable=no',
181
- 'copyhistory=no',
182
- `width=${width}`,
183
- `height=${height}`,
184
- `top=${top}`,
185
- `left=${left}`,
186
- ]
187
-
188
- return new Promise((resolve, reject) => {
189
- const win = window.open(src, 'Authorization', windowParams.join(', '))
190
-
191
- if (!win) {
192
- reject('Failed to open window')
193
- }
194
-
195
- // pings the login window to check if it was closed
196
- const closeCheck = setInterval(() => {
197
- if (win.closed) {
198
- destroy();
199
- onClose();
200
- }
201
-
202
- }, 100)
203
-
204
- // triggered if the window was closed
205
- const onClose = () => {
206
- reject('User closed window')
207
- }
208
-
209
- // completes the process, either because the user closes or because the authentication completed
210
- // cleans intervals and event listeners
211
- const destroy = () => {
212
- window.removeEventListener('message', onMessage)
213
- clearInterval(closeCheck)
214
- }
215
-
216
- // triggered when a message is received on the current window
217
- const onMessage = event => {
218
- if (!this.isViibeEvent(event)) {
219
- return null
220
- }
221
- if (event.data.token) {
222
- destroy();
223
- resolve(event.data.token)
224
- }
225
- if (event.data.error) {
226
- destroy();
227
- reject(event.data.error)
228
- }
229
- }
230
-
231
- window.addEventListener('message', onMessage)
232
- })
233
279
 
280
+ return openAuthPopup(src);
234
281
  }
235
282
 
236
283
  }
@@ -240,4 +287,4 @@ if (typeof window !== 'undefined') {
240
287
  }
241
288
  if (typeof module !== 'undefined') {
242
289
  module.exports = Viibe
243
- }
290
+ }