@smileid/web-components 1.4.6 → 1.5.0

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.
@@ -9,12 +9,25 @@ import packageJson from '../../../package.json';
9
9
 
10
10
  const COMPONENTS_VERSION = packageJson.version;
11
11
 
12
+ const smartCameraWeb = document.querySelector('smart-camera-web');
13
+
12
14
  async function getPermissions(captureScreen) {
13
15
  try {
14
- await SmartCamera.getMedia({
16
+ const stream = await SmartCamera.getMedia({
15
17
  audio: false,
16
18
  video: SmartCamera.environmentOptions,
17
19
  });
20
+ const devices = await navigator.mediaDevices.enumerateDevices();
21
+ const videoDevice = devices.find(
22
+ (device) =>
23
+ device.kind === 'videoinput' &&
24
+ stream.getVideoTracks()[0].getSettings().deviceId === device.deviceId,
25
+ );
26
+ smartCameraWeb?.dispatchEvent(
27
+ new CustomEvent('metadata.camera-name', {
28
+ detail: { cameraName: videoDevice?.label },
29
+ }),
30
+ );
18
31
  captureScreen.removeAttribute('data-camera-error');
19
32
  captureScreen.setAttribute('data-camera-ready', true);
20
33
  } catch (error) {
@@ -30,6 +43,8 @@ class DocumentCaptureScreens extends HTMLElement {
30
43
  constructor() {
31
44
  super();
32
45
  this.activeScreen = null;
46
+ this.smartCameraWeb = this.closest('smart-camera-web');
47
+ smartCameraWeb?.dispatchEvent(new CustomEvent('metadata.initialize'));
33
48
  }
34
49
 
35
50
  connectedCallback() {
@@ -107,6 +122,14 @@ class DocumentCaptureScreens extends HTMLElement {
107
122
  this.documentInstruction.addEventListener(
108
123
  'document-capture-instructions.capture',
109
124
  async () => {
125
+ smartCameraWeb?.dispatchEvent(
126
+ new CustomEvent('metadata.document-front-capture-start'),
127
+ );
128
+ smartCameraWeb?.dispatchEvent(
129
+ new CustomEvent('metadata.document-front-origin', {
130
+ detail: { imageOrigin: 'camera_manual_capture' },
131
+ }),
132
+ );
110
133
  this.setActiveScreen(this.idCapture);
111
134
  await getPermissions(this.idCapture);
112
135
  },
@@ -114,6 +137,11 @@ class DocumentCaptureScreens extends HTMLElement {
114
137
  this.documentInstruction.addEventListener(
115
138
  'document-capture-instructions.upload',
116
139
  async (event) => {
140
+ smartCameraWeb?.dispatchEvent(
141
+ new CustomEvent('metadata.document-front-origin', {
142
+ detail: { imageOrigin: 'gallery' },
143
+ }),
144
+ );
117
145
  this.idReview.setAttribute('data-image', event.detail.previewImage);
118
146
  this._data.images.push({
119
147
  image: event.detail.image.split(',')[1],
@@ -124,6 +152,9 @@ class DocumentCaptureScreens extends HTMLElement {
124
152
  );
125
153
 
126
154
  this.idCapture.addEventListener('document-capture.publish', (event) => {
155
+ smartCameraWeb?.dispatchEvent(
156
+ new CustomEvent('metadata.document-front-capture-end'),
157
+ );
127
158
  this.idReview.setAttribute('data-image', event.detail.previewImage);
128
159
  this._data.images.push({
129
160
  image: event.detail.image.split(',')[1],
@@ -144,6 +175,9 @@ class DocumentCaptureScreens extends HTMLElement {
144
175
  this.idReview.addEventListener(
145
176
  'document-capture-review.rejected',
146
177
  async () => {
178
+ smartCameraWeb?.dispatchEvent(
179
+ new CustomEvent('metadata.document-front-capture-retry'),
180
+ );
147
181
  this.idReview.removeAttribute('data-image');
148
182
  this._data.images.pop();
149
183
  if (this.hideInstructions) {
@@ -172,6 +206,14 @@ class DocumentCaptureScreens extends HTMLElement {
172
206
  this.documentInstructionBack.addEventListener(
173
207
  'document-capture-instructions.capture',
174
208
  async () => {
209
+ smartCameraWeb?.dispatchEvent(
210
+ new CustomEvent('metadata.document-back-capture-start'),
211
+ );
212
+ smartCameraWeb?.dispatchEvent(
213
+ new CustomEvent('metadata.document-back-origin', {
214
+ detail: { imageOrigin: 'camera_manual_capture' },
215
+ }),
216
+ );
175
217
  this.setActiveScreen(this.idCaptureBack);
176
218
  await getPermissions(this.idCaptureBack);
177
219
  },
@@ -194,6 +236,11 @@ class DocumentCaptureScreens extends HTMLElement {
194
236
  this.documentInstructionBack.addEventListener(
195
237
  'document-capture-instructions.upload',
196
238
  async (event) => {
239
+ smartCameraWeb?.dispatchEvent(
240
+ new CustomEvent('metadata.document-back-origin', {
241
+ detail: { imageOrigin: 'gallery' },
242
+ }),
243
+ );
197
244
  this.backOfIdReview.setAttribute('data-image', event.detail.image);
198
245
  this._data.images.push({
199
246
  image: event.detail.image.split(',')[1],
@@ -203,6 +250,9 @@ class DocumentCaptureScreens extends HTMLElement {
203
250
  },
204
251
  );
205
252
  this.idCaptureBack.addEventListener('document-capture.publish', (event) => {
253
+ smartCameraWeb?.dispatchEvent(
254
+ new CustomEvent('metadata.document-back-capture-end'),
255
+ );
206
256
  this.backOfIdReview.setAttribute('data-image', event.detail.previewImage);
207
257
  this._data.images.push({
208
258
  image: event.detail.image.split(',')[1],
@@ -227,6 +277,9 @@ class DocumentCaptureScreens extends HTMLElement {
227
277
  this.backOfIdReview.addEventListener(
228
278
  'document-capture-review.rejected',
229
279
  async () => {
280
+ smartCameraWeb?.dispatchEvent(
281
+ new CustomEvent('metadata.document-back-capture-retry'),
282
+ );
230
283
  this.backOfIdReview.removeAttribute('data-image');
231
284
  this._data.images.pop();
232
285
  if (this.hideInstructions) {
@@ -7,12 +7,25 @@ import packageJson from '../../../package.json';
7
7
 
8
8
  const COMPONENTS_VERSION = packageJson.version;
9
9
 
10
+ const smartCameraWeb = document.querySelector('smart-camera-web');
11
+
10
12
  async function getPermissions(captureScreen, facingMode = 'user') {
11
13
  try {
12
- await SmartCamera.getMedia({
14
+ const stream = await SmartCamera.getMedia({
13
15
  audio: false,
14
16
  video: { facingMode },
15
17
  });
18
+ const devices = await navigator.mediaDevices.enumerateDevices();
19
+ const videoDevice = devices.find(
20
+ (device) =>
21
+ device.kind === 'videoinput' &&
22
+ stream.getVideoTracks()[0].getSettings().deviceId === device.deviceId,
23
+ );
24
+ smartCameraWeb?.dispatchEvent(
25
+ new CustomEvent('metadata.camera-name', {
26
+ detail: { cameraName: videoDevice?.label },
27
+ }),
28
+ );
16
29
  captureScreen.removeAttribute('data-camera-error');
17
30
  captureScreen.setAttribute('data-camera-ready', true);
18
31
  } catch (error) {
@@ -28,6 +41,7 @@ class SelfieCaptureScreens extends HTMLElement {
28
41
  constructor() {
29
42
  super();
30
43
  this.activeScreen = null;
44
+ smartCameraWeb?.dispatchEvent(new CustomEvent('metadata.initialize'));
31
45
  }
32
46
 
33
47
  connectedCallback() {
@@ -89,6 +103,19 @@ class SelfieCaptureScreens extends HTMLElement {
89
103
  await getPermissions(this.selfieCapture, this.getAgentMode()).then(() =>
90
104
  this.setActiveScreen(this.selfieCapture),
91
105
  );
106
+ smartCameraWeb?.dispatchEvent(
107
+ new CustomEvent('metadata.selfie-capture-start'),
108
+ );
109
+ smartCameraWeb?.dispatchEvent(
110
+ new CustomEvent('metadata.selfie-origin', {
111
+ detail: {
112
+ imageOrigin: {
113
+ environment: 'back_camera',
114
+ user: 'front_camera',
115
+ }[this.getAgentMode()],
116
+ },
117
+ }),
118
+ );
92
119
  },
93
120
  );
94
121
  this.selfieInstruction.addEventListener(
@@ -107,6 +134,9 @@ class SelfieCaptureScreens extends HTMLElement {
107
134
  });
108
135
 
109
136
  this.selfieCapture.addEventListener('selfie-capture.publish', (event) => {
137
+ smartCameraWeb?.dispatchEvent(
138
+ new CustomEvent('metadata.selfie-capture-end'),
139
+ );
110
140
  this.selfieReview.setAttribute('data-image', event.detail.referenceImage);
111
141
  this._data.images = event.detail.images;
112
142
  SmartCamera.stopMedia();
@@ -127,6 +157,9 @@ class SelfieCaptureScreens extends HTMLElement {
127
157
  this.selfieReview.addEventListener(
128
158
  'selfie-capture-review.rejected',
129
159
  async () => {
160
+ smartCameraWeb?.dispatchEvent(
161
+ new CustomEvent('metadata.selfie-capture-retry'),
162
+ );
130
163
  this.selfieReview.removeAttribute('data-image');
131
164
  this._data.images = [];
132
165
  if (this.hideInstructions) {
@@ -194,7 +227,10 @@ class SelfieCaptureScreens extends HTMLElement {
194
227
  }
195
228
 
196
229
  get hideBack() {
197
- return this.hasAttribute('hide-back-to-host') ? 'hide-back' : '';
230
+ return this.hasAttribute('hide-back-to-host') ||
231
+ this.hasAttribute('hide-back')
232
+ ? 'hide-back'
233
+ : '';
198
234
  }
199
235
 
200
236
  get disableImageTests() {
@@ -554,10 +554,21 @@ async function getPermissions(
554
554
  constraints = { facingMode: 'user' },
555
555
  ) {
556
556
  try {
557
- await SmartCamera.getMedia({
557
+ const stream = await SmartCamera.getMedia({
558
558
  audio: false,
559
559
  video: constraints,
560
560
  });
561
+ const devices = await navigator.mediaDevices.enumerateDevices();
562
+ const videoDevice = devices.find(
563
+ (device) =>
564
+ device.kind === 'videoinput' &&
565
+ stream.getVideoTracks()[0].getSettings().deviceId === device.deviceId,
566
+ );
567
+ window.dispatchEvent(
568
+ new CustomEvent('metadata.camera-name', {
569
+ detail: { cameraName: videoDevice?.label },
570
+ }),
571
+ );
561
572
  captureScreen?.removeAttribute('data-camera-error');
562
573
  captureScreen?.setAttribute('data-camera-ready', true);
563
574
  } catch (error) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smileid/signature-pad",
3
- "version": "1.4.6",
3
+ "version": "1.5.0",
4
4
  "private": "true",
5
5
  "exports": {
6
6
  ".": "./index.js"
@@ -224,7 +224,10 @@ class SmartCameraWeb extends HTMLElement {
224
224
  }
225
225
 
226
226
  get hideBackToHost() {
227
- return this.hasAttribute('hide-back-to-host') ? 'hide-back-to-host' : '';
227
+ return this.hasAttribute('hide-back-to-host') ||
228
+ this.hasAttribute('hide-back')
229
+ ? 'hide-back'
230
+ : '';
228
231
  }
229
232
 
230
233
  get allowAgentMode() {
@@ -0,0 +1,61 @@
1
+ describe('SmartCameraWeb', () => {
2
+ beforeEach(() => {
3
+ cy.visit('/capture-back-of-id-navigation');
4
+ });
5
+
6
+ it('shows attribution by default', () => {
7
+ cy.get('smart-camera-web')
8
+ .shadow()
9
+ .find('selfie-capture-instructions')
10
+ .should('be.visible');
11
+ cy.get('smart-camera-web')
12
+ .shadow()
13
+ .find('selfie-capture-instructions')
14
+ .shadow()
15
+ .should('contain.text', "Next, we'll take a quick selfie");
16
+ cy.get('smart-camera-web')
17
+ .shadow()
18
+ .find('selfie-capture-instructions')
19
+ .shadow()
20
+ .find('smileid-navigation')
21
+ .shadow()
22
+ .find('.back-button')
23
+ .should('be.visible');
24
+ cy.get('smart-camera-web')
25
+ .shadow()
26
+ .find('selfie-capture-instructions')
27
+ .shadow()
28
+ .find('#cancel')
29
+ .should('be.visible');
30
+ });
31
+
32
+ it('hides back exit and cancel button when `hide-back-to-host` attribute is passed', () => {
33
+ cy.get('smart-camera-web')
34
+ .invoke('attr', 'hide-back-to-host', 'true')
35
+ .should('have.attr', 'hide-back-to-host', 'true');
36
+
37
+ cy.get('smart-camera-web')
38
+ .shadow()
39
+ .find('selfie-capture-instructions')
40
+ .should('be.visible');
41
+ cy.get('smart-camera-web')
42
+ .shadow()
43
+ .find('selfie-capture-instructions')
44
+ .shadow()
45
+ .should('contain.text', "Next, we'll take a quick selfie");
46
+ cy.get('smart-camera-web')
47
+ .shadow()
48
+ .find('selfie-capture-instructions')
49
+ .shadow()
50
+ .find('smileid-navigation')
51
+ .shadow()
52
+ .get('.back-button')
53
+ .should('not.exist');
54
+ cy.get('smart-camera-web')
55
+ .shadow()
56
+ .find('selfie-capture-instructions')
57
+ .shadow()
58
+ .get('#cancel')
59
+ .should('not.exist');
60
+ });
61
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smileid/web-components",
3
- "version": "1.4.6",
3
+ "version": "1.5.0",
4
4
  "main": "index.js",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -14,7 +14,7 @@
14
14
  "./smart-camera-web": "./components/smart-camera-web/src/SmartCameraWeb.js"
15
15
  },
16
16
  "scripts": {
17
- "build": "NODE_ENV=development node esbuild.js",
17
+ "build": "cross-env NODE_ENV=development node esbuild.js",
18
18
  "clean": "rm -rf build dist",
19
19
  "lint:fix": "eslint . --ext .js --fix",
20
20
  "lint:html": "npx prettier --write $(git ls-files '*.html')",
@@ -33,6 +33,7 @@
33
33
  "validate.js": "^0.13.1"
34
34
  },
35
35
  "devDependencies": {
36
+ "cross-env": "^7.0.3",
36
37
  "cypress": "^13.15.0",
37
38
  "esbuild": "^0.24.0",
38
39
  "eslint": "^8.57.0",