@viibe/impulse-integration-js 2.3.5-alpha1 → 2.3.6

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/README.md CHANGED
@@ -132,7 +132,7 @@ Triggered when the user clicks on an ongoing call. The host app may open a modal
132
132
  - event `authentication:error`
133
133
  - handler payload: `error: string`
134
134
 
135
- Triggered when the user is not authenticated. The host app may display a login button in place of the iframe (`{host}/api/auth/login/{provider}`). Otherwise the iframe should display a "login" button with username / password method
135
+ Triggered when the user is not authenticated. The host app may display a login button in place of the iframe (`api-{host}/auth/login/{provider}`). Otherwise the iframe should display a "login" button with username / password method
136
136
 
137
137
  - event `authentication:token`
138
138
  - handler payload: `{token: string}`
package/dist/index.js CHANGED
@@ -1 +1 @@
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 a(t){return function(e){return Boolean(e.isTrusted&&0===e.origin.indexOf(t))}}function i(t){var e=new URL(t),n="".concat(e.protocol,"//").concat(e.host),o=window.screen.width/2-240,i=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(i),"left=".concat(o)];return new Promise((function(e,o){var i=window.open(t,"Authorization",r.join(", "));i||o("Failed to open window");var c=setInterval((function(){i.closed&&(s(),o("User closed window"))}),100);function s(){window.removeEventListener("message",u),clearInterval(c)}function u(t){if(!a(n)(t))return null;if(t.data.token&&(s(),e(t.data.token)),t.data.error&&(s(),o(t.data.error)),t.data&&t.data.event&&t.data.payload)switch(t.data.event){case"authentication:success":return s(),e(t.data);case"authentication:failure":return s(),o(t.data)}}window.addEventListener("message",u)}))}var r,c,s,u=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 i("https://".concat(this.host,"/auth/zendesk/login?subdomain=").concat(t))}}]),t}(),l=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=a(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,a=t.links,i=t.o2m,r=void 0!==i&&i,c=t.ticket,s=t.token,u=t.locale,l=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),a){var f=a instanceof Array?a.map((function(t){return"".concat(t.category,":").concat(t.value)})).join(","):String(a);h.set("links",f)}if(s&&h.set("token",s),u&&h.set("locale",u),o){var v=o instanceof Array?o.join(","):String(o);h.set("components",v)}return l&&h.set("standalone",Boolean(l)),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 i("".concat(this.origin,"/api/auth/login/").concat(t))}}]),t}();s=u,(c="Auth")in(r=l)?Object.defineProperty(r,c,{value:s,enumerable:!0,configurable:!0,writable:!0}):r.Auth=s,"undefined"!=typeof window&&(window.Viibe=l),t.exports=l}},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 a(t){return function(e){return Boolean(e.isTrusted&&0===e.origin.indexOf(t))}}function i(t){var e=new URL(t),n="".concat(e.protocol,"//").concat(e.host),o=window.screen.width/2-240,i=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(i),"left=".concat(o)];return new Promise((function(e,o){var i=window.open(t,"Authorization",r.join(", "));i||o("Failed to open window");var c=setInterval((function(){i.closed&&(s(),o("User closed window"))}),100);function s(){window.removeEventListener("message",u),clearInterval(c)}function u(t){if(!a(n)(t))return null;if(t.data.token&&(s(),e(t.data.token)),t.data.error&&(s(),o(t.data.error)),t.data&&t.data.event&&t.data.payload)switch(t.data.event){case"authentication:success":return s(),e(t.data);case"authentication:failure":return s(),o(t.data)}}window.addEventListener("message",u)}))}var r,c,s,u="auth.viibe.pro",l=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:u;e(this,t),this.host=n}return o(t,[{key:"loginZendesk",value:function(t){return i("https://".concat(this.host,"/auth/zendesk/login?subdomain=").concat(t))}}]),t}(),d=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=a(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,a=t.links,i=t.o2m,r=void 0!==i&&i,c=t.ticket,s=t.token,u=t.locale,l=t.standalone,d="".concat(this.origin,"/integration/features/ticket"),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),a){var f=a instanceof Array?a.map((function(t){return"".concat(t.category,":").concat(t.value)})).join(","):String(a);h.set("links",f)}if(s&&h.set("token",s),u&&h.set("locale",u),o){var v=o instanceof Array?o.join(","):String(o);h.set("components",v)}return l&&h.set("standalone",Boolean(l)),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 i("".concat(this.origin,"/api/auth/login/").concat(t))}}]),t}();s=l,(c="Auth")in(r=d)?Object.defineProperty(r,c,{value:s,enumerable:!0,configurable:!0,writable:!0}):r.Auth=s,"undefined"!=typeof window&&(window.Viibe=d),t.exports=d}},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})();
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@viibe/impulse-integration-js",
3
- "version": "2.3.5-alpha1",
3
+ "version": "2.3.6",
4
4
  "description": "ViiBE integration in js native",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
7
- "access":"public"
7
+ "access": "public"
8
8
  },
9
9
  "scripts": {
10
10
  "build": "webpack --mode production",
11
11
  "prepublish": "npm run build",
12
- "test": "echo \"Error: no test specified\" && exit 1",
12
+ "test": "npm run build && jest",
13
13
  "publish:dev": "npm publish --tag dev"
14
14
  },
15
15
  "author": "Viibe",
@@ -17,8 +17,11 @@
17
17
  "devDependencies": {
18
18
  "@babel/core": "^7.15.8",
19
19
  "@babel/preset-env": "^7.15.8",
20
+ "@types/jest": "^28.1.3",
20
21
  "babel-loader": "^8.2.2",
21
22
  "core-js": "^3.18.2",
23
+ "jest": "^28.1.1",
24
+ "jest-environment-jsdom": "^28.1.1",
22
25
  "webpack": "^5.58.1",
23
26
  "webpack-cli": "^4.9.0"
24
27
  }
package/src/index.js CHANGED
@@ -89,15 +89,17 @@ function openAuthPopup(src) {
89
89
  })
90
90
  }
91
91
 
92
+ const DEFAULT_AUTH_HOST = 'auth.viibe.pro'
93
+
92
94
  class ViibeAuth {
93
95
 
94
- // FIXME
95
- constructor(host = 'auth.viibe.tech') {
96
+ constructor(host = DEFAULT_AUTH_HOST) {
96
97
  this.host = host;
97
98
  }
98
99
 
99
100
  loginZendesk(subdomain) {
100
- const url = `https://${this.host}/auth/zendesk/login?subdomain=${subdomain}`;
101
+ const { origin } = document.location
102
+ const url = `https://${this.host}/auth/zendesk/login?subdomain=${subdomain}&origin=${origin}`;
101
103
  return openAuthPopup(url);
102
104
  }
103
105
  }
@@ -114,6 +116,12 @@ class Viibe {
114
116
  * @property {Function} func The function to trigger when an event is received
115
117
  */
116
118
 
119
+ /**
120
+ *
121
+ * @param {object} options
122
+ * @param {string} options.host Target ViiBE subdomain (e.g. test.viibe.tech)
123
+ * @param {string} options.source Integration source (e.g. zendesk)
124
+ */
117
125
  constructor(options) {
118
126
  /**
119
127
  * @type {Handler[]}
@@ -121,6 +129,7 @@ class Viibe {
121
129
  this.handlers = []
122
130
  this.host = options.host
123
131
  this.origin = /^localhost/.test(this.host) ? `http://${this.host}` : `https://${this.host}`
132
+ this.apiOrigin = /^localhost/.test(this.host) ? `http://${this.host}` : `https://api-${this.host}`
124
133
  this.source = options.source
125
134
 
126
135
  this.isViibeEvent = isFromOrigin(this.origin);
@@ -143,7 +152,7 @@ class Viibe {
143
152
  if (!this.host) throw new Error('fillHost')
144
153
  if (!this.source) throw new Error('fillSource')
145
154
 
146
- const src = this.createCallUrl(options)
155
+ const src = this.generateIframeSrc(options)
147
156
 
148
157
  const iframe = document.createElement('iframe')
149
158
  iframe.name = 'viibe-' + Math.floor(Math.random() * 10000)
@@ -156,7 +165,7 @@ class Viibe {
156
165
  return iframe
157
166
  }
158
167
 
159
- createCallUrl(options = {}) {
168
+ generateIframeSrc(options = {}) {
160
169
  const {
161
170
  clipboard = false,
162
171
  components,
@@ -168,11 +177,12 @@ class Viibe {
168
177
  standalone,
169
178
  } = options
170
179
 
171
- let src = `${this.origin}/integration/features/call`
180
+ let src = `${this.origin}/integration/features/ticket`
172
181
 
173
182
  const params = new URLSearchParams({
174
183
  resize: 'true',
175
184
  source: this.source,
185
+ origin: document.location.origin,
176
186
  });
177
187
 
178
188
  if (ticket && ticket.title) params.set('title', ticket.title)
@@ -288,7 +298,8 @@ class Viibe {
288
298
  * @returns
289
299
  */
290
300
  authenticate(provider) {
291
- const src = `${this.origin}/api/auth/login/${provider}`
301
+ const { protocol, host } = document.location
302
+ const src = `${protocol}//api-${host}/auth/login/${provider}?origin=${origin}`
292
303
 
293
304
  return openAuthPopup(src);
294
305
  }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ const Viibe = require('../dist');
6
+
7
+ describe('dist', () => {
8
+ test('exposes Viibe constructor', () => {
9
+ expect(typeof Viibe).toBe('function')
10
+ expect(() => new Viibe()).toThrowError()
11
+ expect(new Viibe({})).toBeInstanceOf(Viibe)
12
+ });
13
+
14
+ test('throws errors when host or source are not defined', () => {
15
+ const viibe = new Viibe({});
16
+ expect(() => viibe.createNotificationIframe()).toThrow('fillHost')
17
+ expect(() => viibe.createCallIframe()).toThrow('fillHost')
18
+
19
+ const viibeWithHost = new Viibe({host: 'clement.viibe.tech'})
20
+ expect(() => viibeWithHost.createNotificationIframe()).toThrow('fillSource')
21
+ expect(() => viibeWithHost.createCallIframe()).toThrow('fillSource')
22
+ })
23
+
24
+ test('constructor', () => {
25
+ const viibe = new Viibe({
26
+ host: 'clement.viibe.tech',
27
+ source: 'jest'
28
+ })
29
+ expect(viibe.host).toBe('clement.viibe.tech')
30
+ expect(viibe.source).toBe('jest')
31
+ expect(viibe.origin).toBe('https://clement.viibe.tech')
32
+
33
+ const viibeLocalhost = new Viibe({
34
+ host: 'localhost:6666'
35
+ })
36
+ expect(viibeLocalhost.origin).toBe('http://localhost:6666')
37
+ });
38
+
39
+ test('createNotificationIframe', () => {
40
+ const viibe = new Viibe({
41
+ host: 'clement.viibe.tech',
42
+ source: 'jest',
43
+ })
44
+ const iframe = viibe.createNotificationIframe()
45
+ expect(iframe).toBeInstanceOf(HTMLIFrameElement)
46
+ expect(iframe.name).toMatch(/^viibe-[0-9]{1,4}$/)
47
+ expect(iframe.style.border).toBe('0px')
48
+ expect(iframe.style.width).toBe('0px')
49
+ expect(iframe.src).toBe('https://clement.viibe.tech/integration/features/notifications')
50
+ })
51
+
52
+ test('createCallIframe', () => {
53
+ const viibe = new Viibe({
54
+ host: 'clement.viibe.tech',
55
+ source: 'jest',
56
+ })
57
+ const iframe = viibe.createCallIframe()
58
+ const callUrl = viibe.createCallUrl()
59
+ expect(iframe).toBeInstanceOf(HTMLIFrameElement)
60
+ expect(iframe.name).toMatch(/^viibe-[0-9]{1,4}$/)
61
+ expect(iframe.allow).toBe('geolocation;autoplay;microphone;camera;midi;encrypted-media;clipboard-write;')
62
+ expect(iframe.style.border).toBe('0px')
63
+ expect(iframe.style.margin).toBe('0.5rem')
64
+ expect(iframe.style.width).toBe('calc(100% - 1rem)')
65
+ expect(iframe.src).toEqual(callUrl)
66
+ })
67
+ });
@@ -1,2 +0,0 @@
1
- {
2
- }