@authme/util 2.4.2 → 2.4.4-rc.7

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/index.cjs CHANGED
@@ -20,6 +20,7 @@ require('core-js/modules/es.string.match.js');
20
20
  require('core-js/modules/es.string.replace.js');
21
21
  require('core-js/modules/web.url-search-params.js');
22
22
  require('core-js/modules/es.string.search.js');
23
+ require('core-js/modules/es.typed-array.uint32-array.js');
23
24
  var Lottie = require('lottie-web');
24
25
  require('core-js/modules/es.array.sort.js');
25
26
  require('core-js/modules/es.array.includes.js');
@@ -185,6 +186,7 @@ exports.ErrorCode = void 0;
185
186
  ErrorCode[ErrorCode["USER_CANCEL"] = 903] = "USER_CANCEL";
186
187
  ErrorCode[ErrorCode["CAMERA_NOT_SUPPORT"] = 904] = "CAMERA_NOT_SUPPORT";
187
188
  ErrorCode[ErrorCode["SERVER_ERROR"] = 905] = "SERVER_ERROR";
189
+ ErrorCode[ErrorCode["EVENT_NAME_WRONG"] = 906] = "EVENT_NAME_WRONG";
188
190
  })(exports.ErrorCode || (exports.ErrorCode = {}));
189
191
 
190
192
  function decodeToken(token) {
@@ -483,6 +485,98 @@ function debugLog(message, ...others) {
483
485
  console.log(message, ...others);
484
486
  }
485
487
  }
488
+ function generateUniqueId(length = 32) {
489
+ if (length <= 0) {
490
+ throw new Error('Length should be a positive integer.');
491
+ }
492
+ // 定義可能的字元
493
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
494
+ const charactersLength = characters.length;
495
+ const randomValues = new Uint32Array(length);
496
+ // 使用window.crypto.getRandomValues取得真正的隨機值
497
+ window.crypto.getRandomValues(randomValues);
498
+ let result = '';
499
+ for (let i = 0; i < length; i++) {
500
+ result += characters[randomValues[i] % charactersLength];
501
+ }
502
+ return result;
503
+ }
504
+ function downloadObjectAsJson(exportObj, exportName) {
505
+ const dataStr = `data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=${exportName}.json,${encodeURIComponent(JSON.stringify(exportObj, null, 4))}`;
506
+ //'data:text/json;charset=utf-8,' +
507
+ const downloadAnchorNode = document.createElement('a');
508
+ downloadAnchorNode.setAttribute('href', dataStr);
509
+ downloadAnchorNode.setAttribute('download', exportName + '.json');
510
+ document.body.appendChild(downloadAnchorNode); // required for firefox
511
+ downloadAnchorNode.click();
512
+ downloadAnchorNode.remove();
513
+ }
514
+ function debugTools(config) {
515
+ const debugLogs = [];
516
+ let currentRoundId = generateUniqueId(8);
517
+ let currentType = null;
518
+ function pushNewDebugLog(logParams) {
519
+ var _a;
520
+ if (!config.debugMode) return;
521
+ const now = new Date();
522
+ const _logParams = JSON.parse(JSON.stringify(logParams));
523
+ if (_logParams.result) {
524
+ (_a = _logParams.result) === null || _a === void 0 ? true : delete _a.imageData;
525
+ }
526
+ const newDebugLog = Object.assign({
527
+ time: now.getTime(),
528
+ dateTime: now.toLocaleString(),
529
+ roundId: currentRoundId,
530
+ type: currentType !== null && currentType !== void 0 ? currentType : undefined
531
+ }, _logParams);
532
+ debugLogs.push(newDebugLog);
533
+ }
534
+ function functionLogging(func, logParams) {
535
+ return new Promise((resolve, reject) => {
536
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
537
+ status: 'run-start'
538
+ }));
539
+ func().then(result => {
540
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
541
+ status: 'run-end',
542
+ roundId: currentRoundId,
543
+ result
544
+ }));
545
+ resolve(result);
546
+ }).catch(error => {
547
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
548
+ status: 'run-error',
549
+ roundId: currentRoundId,
550
+ result: error
551
+ }));
552
+ reject(error);
553
+ });
554
+ });
555
+ }
556
+ return {
557
+ pushNewDebugLog,
558
+ getDebugLogs: () => debugLogs,
559
+ getDebugLogsLength: () => debugLogs.length,
560
+ modifyDeubgLog: (index, logParams) => {
561
+ if (!config.debugMode) return;
562
+ debugLogs[index] = Object.assign(Object.assign({}, debugLogs[index]), logParams);
563
+ },
564
+ downloadDebugLogs: () => {
565
+ if (!config.debugMode) return;
566
+ downloadObjectAsJson(debugLogs, `debugLog${new Date().getTime().toString()}`);
567
+ },
568
+ functionLogging,
569
+ nextDebugRound: type => {
570
+ if (!config.debugMode) return;
571
+ currentRoundId = generateUniqueId(8);
572
+ if (type) currentType = type;
573
+ },
574
+ modifyDebugType: type => {
575
+ if (!config.debugMode) return;
576
+ currentType = type;
577
+ }
578
+ };
579
+ }
486
580
 
487
581
  exports.TIME_UNIT = void 0;
488
582
  (function (TIME_UNIT) {
@@ -587,7 +681,7 @@ function cropByRatio(width, height, ratio) {
587
681
  };
588
682
  }
589
683
 
590
- function startSpinner(text) {
684
+ function startSpinner(text, backgroundOpaque) {
591
685
  const loadingLottie = Storage.getItem(exports.STORAGE_KEY.LOADING_LOTTIE);
592
686
  const body = document.querySelector('.authme-container');
593
687
  if (loadingLottie) {
@@ -611,6 +705,9 @@ function startSpinner(text) {
611
705
  loadingSDKText.textContent = text;
612
706
  loadingSDKContent.appendChild(loadingSDKText);
613
707
  }
708
+ if (backgroundOpaque) {
709
+ loadingSDKOuter.classList.add('authme-loading-sdk-outer--opaque');
710
+ }
614
711
  return;
615
712
  }
616
713
  const spinnerOuter = document.createElement('div');
@@ -624,6 +721,9 @@ function startSpinner(text) {
624
721
  spinnerText.textContent = text;
625
722
  spinnerOuter.appendChild(spinnerText);
626
723
  }
724
+ if (backgroundOpaque) {
725
+ spinnerOuter.classList.add('loading-outer--opaque');
726
+ }
627
727
  body === null || body === void 0 ? void 0 : body.appendChild(spinnerOuter);
628
728
  }
629
729
  function stopSpinner() {
@@ -644,7 +744,7 @@ exports.Icon = void 0;
644
744
  Icon["PictureIcon"] = "data:image/png;base64,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";
645
745
  })(exports.Icon || (exports.Icon = {}));
646
746
 
647
- function showErrorMessage(text, showRetryBtn, callback) {
747
+ function showErrorMessage(text, showRetryBtn, callback, buttonText, _titleText) {
648
748
  return __awaiter(this, void 0, void 0, function* () {
649
749
  const target = document.querySelector('.authme-container');
650
750
  if (!target) {
@@ -663,7 +763,39 @@ function showErrorMessage(text, showRetryBtn, callback) {
663
763
  if (showRetryBtn) {
664
764
  const retryText = document.createElement('div');
665
765
  retryText.className = 'retry-text';
666
- retryText.textContent = '重試';
766
+ retryText.textContent = buttonText !== null && buttonText !== void 0 ? buttonText : '重試';
767
+ errorMessagePanel.appendChild(retryText);
768
+ if (callback) {
769
+ retryText.addEventListener('click', e => {
770
+ target.removeChild(errorMessagePanel);
771
+ callback(e);
772
+ });
773
+ }
774
+ }
775
+ target === null || target === void 0 ? void 0 : target.appendChild(errorMessagePanel);
776
+ });
777
+ }
778
+ function showErrorMessageEventName(text, showRetryBtn, callback, buttonText, titleText) {
779
+ return __awaiter(this, void 0, void 0, function* () {
780
+ const target = document.querySelector('.authme-container');
781
+ if (!target) {
782
+ return;
783
+ }
784
+ const errorMessagePanel = document.createElement('div');
785
+ errorMessagePanel.classList.add('error-message-panel');
786
+ errorMessagePanel.classList.add('event-name');
787
+ const errorText = document.createElement('div');
788
+ errorText.className = 'error-text';
789
+ errorText.textContent = text;
790
+ const title = document.createElement('div');
791
+ title.className = 'error-title';
792
+ title.textContent = titleText !== null && titleText !== void 0 ? titleText : 'error';
793
+ errorMessagePanel.appendChild(title);
794
+ errorMessagePanel.appendChild(errorText);
795
+ if (showRetryBtn) {
796
+ const retryText = document.createElement('div');
797
+ retryText.className = 'retry-text';
798
+ retryText.textContent = buttonText !== null && buttonText !== void 0 ? buttonText : '重試';
667
799
  errorMessagePanel.appendChild(retryText);
668
800
  if (callback) {
669
801
  retryText.addEventListener('click', e => {
@@ -682,14 +814,17 @@ function hideErrorMessage() {
682
814
  body === null || body === void 0 ? void 0 : body.removeChild(errorMessagePanel);
683
815
  }
684
816
  }
685
- function asyncShowErrorMessage(text, showRetryBtn) {
817
+ function asyncShowErrorMessage(text, showRetryBtn, options) {
818
+ var _a;
686
819
  return __awaiter(this, void 0, void 0, function* () {
820
+ const _showErrorMessage = (_a = options === null || options === void 0 ? void 0 : options.showErrorMessageHandler) !== null && _a !== void 0 ? _a : showErrorMessage;
687
821
  return new Promise((res, rej) => {
822
+ var _a;
688
823
  const callback = () => {
689
824
  res(true);
690
825
  hideErrorMessage();
691
826
  };
692
- showErrorMessage(text, showRetryBtn, callback);
827
+ _showErrorMessage(text, showRetryBtn, (_a = options === null || options === void 0 ? void 0 : options.callback) !== null && _a !== void 0 ? _a : callback, options === null || options === void 0 ? void 0 : options.buttonText, options === null || options === void 0 ? void 0 : options.titleText);
693
828
  });
694
829
  });
695
830
  }
@@ -771,6 +906,7 @@ var BROWSER_CAMERA_ERRORS;
771
906
  BROWSER_CAMERA_ERRORS["NOT_ALLOWED_ERROR"] = "NotAllowedError";
772
907
  BROWSER_CAMERA_ERRORS["NOT_FOUND_ERROR"] = "NotFoundError";
773
908
  })(BROWSER_CAMERA_ERRORS || (BROWSER_CAMERA_ERRORS = {}));
909
+ let stream;
774
910
  const videoConstraintsFactory = (isPC, facingMode) => {
775
911
  return isPC ? {
776
912
  video: {
@@ -851,6 +987,43 @@ function arrayFromAsync(asyncIterable) {
851
987
  return result;
852
988
  });
853
989
  }
990
+ function switchCamera(deviceId, video) {
991
+ return __awaiter(this, void 0, void 0, function* () {
992
+ try {
993
+ if (stream) {
994
+ stream.getTracks().forEach(track => track.stop());
995
+ }
996
+ const constraints = {
997
+ video: {
998
+ // 推測依然需要使用 width & height 的限制條件,
999
+ // 否則即使是高解析度相機,也有可能拿到低解析度的圖片。(待驗證)
1000
+ width: {
1001
+ min: 1280,
1002
+ ideal: 1920,
1003
+ max: 1920
1004
+ },
1005
+ height: {
1006
+ min: 720,
1007
+ ideal: 1080,
1008
+ max: 1080
1009
+ },
1010
+ focusMode: 'auto',
1011
+ deviceId: deviceId
1012
+ }
1013
+ };
1014
+ stream = yield navigator.mediaDevices.getUserMedia(constraints);
1015
+ video.srcObject = stream;
1016
+ yield video.play();
1017
+ // Note: Fix Safari 15 video not showing bug
1018
+ video.srcObject = null;
1019
+ setTimeout(() => {
1020
+ video.srcObject = stream;
1021
+ }, 10);
1022
+ } catch (e) {
1023
+ throw new AuthmeError(exports.ErrorCode.CAMERA_NOT_SUPPORT, e);
1024
+ }
1025
+ });
1026
+ }
854
1027
  function _requestCamera(video, facingMode) {
855
1028
  var _a;
856
1029
  return __awaiter(this, void 0, void 0, function* () {
@@ -925,39 +1098,14 @@ function _requestCamera(video, facingMode) {
925
1098
  if (!deviceId) {
926
1099
  throw BROWSER_CAMERA_ERRORS.NO_CAMERA;
927
1100
  }
928
- const constraints = {
929
- video: {
930
- // 推測依然需要使用 width & height 的限制條件,
931
- // 否則即使是高解析度相機,也有可能拿到低解析度的圖片。(待驗證)
932
- width: {
933
- min: 1280,
934
- ideal: 1920,
935
- max: 1920
936
- },
937
- height: {
938
- min: 720,
939
- ideal: 1080,
940
- max: 1080
941
- },
942
- focusMode: 'auto',
943
- deviceId: {
944
- exact: deviceId
945
- }
946
- }
1101
+ if (stream) {
1102
+ stream.getTracks().forEach(track => track.stop());
1103
+ }
1104
+ yield switchCamera(deviceId, video);
1105
+ return {
1106
+ facingMode: firstDevice.meta.facingMode,
1107
+ deviceMetas: deviceMetas
947
1108
  };
948
- debugLog('camera info', {
949
- firstDevice,
950
- deviceMetas
951
- });
952
- const stream = yield navigator.mediaDevices.getUserMedia(constraints);
953
- video.srcObject = stream;
954
- yield video.play();
955
- // Note: Fix Safari 15 video not showing bug
956
- video.srcObject = null;
957
- setTimeout(() => {
958
- video.srcObject = stream;
959
- }, 10);
960
- return firstDevice.meta.facingMode;
961
1109
  });
962
1110
  }
963
1111
  function isOverconstrainedError(error) {
@@ -969,6 +1117,9 @@ function isOverconstrainedError(error) {
969
1117
  }
970
1118
  return 'constraint' in error;
971
1119
  }
1120
+ function sleep(ms) {
1121
+ return new Promise(resolve => setTimeout(resolve, ms));
1122
+ }
972
1123
  function requestCamera({
973
1124
  video,
974
1125
  facingMode,
@@ -977,7 +1128,29 @@ function requestCamera({
977
1128
  }) {
978
1129
  return __awaiter(this, void 0, void 0, function* () {
979
1130
  try {
980
- return yield _requestCamera(video, facingMode);
1131
+ let perm = yield navigator.permissions.query({
1132
+ name: 'camera'
1133
+ });
1134
+ if (perm.state == 'prompt') {
1135
+ for (let i = 0; i < 5; ++i) {
1136
+ try {
1137
+ //for ios 17.4.1 hack, if you call getUserMedia too early will only get not allowed.
1138
+ yield sleep(1000);
1139
+ return yield _requestCamera(video, facingMode);
1140
+ } catch (error) {
1141
+ if ((error === null || error === void 0 ? void 0 : error.name) === BROWSER_CAMERA_ERRORS.NOT_ALLOWED_ERROR) {
1142
+ perm = yield navigator.permissions.query({
1143
+ name: 'camera'
1144
+ });
1145
+ } else {
1146
+ throw error;
1147
+ }
1148
+ }
1149
+ }
1150
+ return yield _requestCamera(video, facingMode);
1151
+ } else {
1152
+ return yield _requestCamera(video, facingMode);
1153
+ }
981
1154
  } catch (error) {
982
1155
  if (error === BROWSER_CAMERA_ERRORS.NOT_SUPPORT) {
983
1156
  showMessage(translate('camera.error.notFound'));
@@ -1987,7 +2160,7 @@ function RGBToLottieColor(color) {
1987
2160
  }
1988
2161
 
1989
2162
  var name = "@authme/util";
1990
- var version$1 = "2.4.2";
2163
+ var version$1 = "2.4.4-rc.7";
1991
2164
  var peerDependencies = {
1992
2165
  "core-js": "^3.6.0"
1993
2166
  };
@@ -2018,6 +2191,7 @@ exports.combineResult = combineResult;
2018
2191
  exports.cropByRatio = cropByRatio;
2019
2192
  exports.dataURItoBlob = dataURItoBlob;
2020
2193
  exports.debugLog = debugLog;
2194
+ exports.debugTools = debugTools;
2021
2195
  exports.decodeToken = decodeToken;
2022
2196
  exports.getCanvasSize = getCanvasSize;
2023
2197
  exports.getCssVariable = getCssVariable;
@@ -2037,12 +2211,14 @@ exports.resize = resize;
2037
2211
  exports.retryPromiseWithCondition = retryPromiseWithCondition;
2038
2212
  exports.showElement = showElement;
2039
2213
  exports.showErrorMessage = showErrorMessage;
2214
+ exports.showErrorMessageEventName = showErrorMessageEventName;
2040
2215
  exports.showPopup = showPopup;
2041
2216
  exports.splitResult = splitResult;
2042
2217
  exports.startLoadingSDK = startLoadingSDK;
2043
2218
  exports.startSpinner = startSpinner;
2044
2219
  exports.stopLoadingSDK = stopLoadingSDK;
2045
2220
  exports.stopSpinner = stopSpinner;
2221
+ exports.switchCamera = switchCamera;
2046
2222
  exports.useState = useState;
2047
2223
  exports.version = version;
2048
2224
  exports.videoConstraintsFactory = videoConstraintsFactory;
package/index.js CHANGED
@@ -16,6 +16,7 @@ import 'core-js/modules/es.string.match.js';
16
16
  import 'core-js/modules/es.string.replace.js';
17
17
  import 'core-js/modules/web.url-search-params.js';
18
18
  import 'core-js/modules/es.string.search.js';
19
+ import 'core-js/modules/es.typed-array.uint32-array.js';
19
20
  import Lottie from 'lottie-web';
20
21
  import 'core-js/modules/es.array.sort.js';
21
22
  import 'core-js/modules/es.array.includes.js';
@@ -176,6 +177,7 @@ var ErrorCode;
176
177
  ErrorCode[ErrorCode["USER_CANCEL"] = 903] = "USER_CANCEL";
177
178
  ErrorCode[ErrorCode["CAMERA_NOT_SUPPORT"] = 904] = "CAMERA_NOT_SUPPORT";
178
179
  ErrorCode[ErrorCode["SERVER_ERROR"] = 905] = "SERVER_ERROR";
180
+ ErrorCode[ErrorCode["EVENT_NAME_WRONG"] = 906] = "EVENT_NAME_WRONG";
179
181
  })(ErrorCode || (ErrorCode = {}));
180
182
 
181
183
  function decodeToken(token) {
@@ -474,6 +476,98 @@ function debugLog(message, ...others) {
474
476
  console.log(message, ...others);
475
477
  }
476
478
  }
479
+ function generateUniqueId(length = 32) {
480
+ if (length <= 0) {
481
+ throw new Error('Length should be a positive integer.');
482
+ }
483
+ // 定義可能的字元
484
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
485
+ const charactersLength = characters.length;
486
+ const randomValues = new Uint32Array(length);
487
+ // 使用window.crypto.getRandomValues取得真正的隨機值
488
+ window.crypto.getRandomValues(randomValues);
489
+ let result = '';
490
+ for (let i = 0; i < length; i++) {
491
+ result += characters[randomValues[i] % charactersLength];
492
+ }
493
+ return result;
494
+ }
495
+ function downloadObjectAsJson(exportObj, exportName) {
496
+ const dataStr = `data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=${exportName}.json,${encodeURIComponent(JSON.stringify(exportObj, null, 4))}`;
497
+ //'data:text/json;charset=utf-8,' +
498
+ const downloadAnchorNode = document.createElement('a');
499
+ downloadAnchorNode.setAttribute('href', dataStr);
500
+ downloadAnchorNode.setAttribute('download', exportName + '.json');
501
+ document.body.appendChild(downloadAnchorNode); // required for firefox
502
+ downloadAnchorNode.click();
503
+ downloadAnchorNode.remove();
504
+ }
505
+ function debugTools(config) {
506
+ const debugLogs = [];
507
+ let currentRoundId = generateUniqueId(8);
508
+ let currentType = null;
509
+ function pushNewDebugLog(logParams) {
510
+ var _a;
511
+ if (!config.debugMode) return;
512
+ const now = new Date();
513
+ const _logParams = JSON.parse(JSON.stringify(logParams));
514
+ if (_logParams.result) {
515
+ (_a = _logParams.result) === null || _a === void 0 ? true : delete _a.imageData;
516
+ }
517
+ const newDebugLog = Object.assign({
518
+ time: now.getTime(),
519
+ dateTime: now.toLocaleString(),
520
+ roundId: currentRoundId,
521
+ type: currentType !== null && currentType !== void 0 ? currentType : undefined
522
+ }, _logParams);
523
+ debugLogs.push(newDebugLog);
524
+ }
525
+ function functionLogging(func, logParams) {
526
+ return new Promise((resolve, reject) => {
527
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
528
+ status: 'run-start'
529
+ }));
530
+ func().then(result => {
531
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
532
+ status: 'run-end',
533
+ roundId: currentRoundId,
534
+ result
535
+ }));
536
+ resolve(result);
537
+ }).catch(error => {
538
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
539
+ status: 'run-error',
540
+ roundId: currentRoundId,
541
+ result: error
542
+ }));
543
+ reject(error);
544
+ });
545
+ });
546
+ }
547
+ return {
548
+ pushNewDebugLog,
549
+ getDebugLogs: () => debugLogs,
550
+ getDebugLogsLength: () => debugLogs.length,
551
+ modifyDeubgLog: (index, logParams) => {
552
+ if (!config.debugMode) return;
553
+ debugLogs[index] = Object.assign(Object.assign({}, debugLogs[index]), logParams);
554
+ },
555
+ downloadDebugLogs: () => {
556
+ if (!config.debugMode) return;
557
+ downloadObjectAsJson(debugLogs, `debugLog${new Date().getTime().toString()}`);
558
+ },
559
+ functionLogging,
560
+ nextDebugRound: type => {
561
+ if (!config.debugMode) return;
562
+ currentRoundId = generateUniqueId(8);
563
+ if (type) currentType = type;
564
+ },
565
+ modifyDebugType: type => {
566
+ if (!config.debugMode) return;
567
+ currentType = type;
568
+ }
569
+ };
570
+ }
477
571
 
478
572
  var TIME_UNIT;
479
573
  (function (TIME_UNIT) {
@@ -578,7 +672,7 @@ function cropByRatio(width, height, ratio) {
578
672
  };
579
673
  }
580
674
 
581
- function startSpinner(text) {
675
+ function startSpinner(text, backgroundOpaque) {
582
676
  const loadingLottie = Storage.getItem(STORAGE_KEY.LOADING_LOTTIE);
583
677
  const body = document.querySelector('.authme-container');
584
678
  if (loadingLottie) {
@@ -602,6 +696,9 @@ function startSpinner(text) {
602
696
  loadingSDKText.textContent = text;
603
697
  loadingSDKContent.appendChild(loadingSDKText);
604
698
  }
699
+ if (backgroundOpaque) {
700
+ loadingSDKOuter.classList.add('authme-loading-sdk-outer--opaque');
701
+ }
605
702
  return;
606
703
  }
607
704
  const spinnerOuter = document.createElement('div');
@@ -615,6 +712,9 @@ function startSpinner(text) {
615
712
  spinnerText.textContent = text;
616
713
  spinnerOuter.appendChild(spinnerText);
617
714
  }
715
+ if (backgroundOpaque) {
716
+ spinnerOuter.classList.add('loading-outer--opaque');
717
+ }
618
718
  body === null || body === void 0 ? void 0 : body.appendChild(spinnerOuter);
619
719
  }
620
720
  function stopSpinner() {
@@ -635,7 +735,7 @@ var Icon;
635
735
  Icon["PictureIcon"] = "data:image/png;base64,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";
636
736
  })(Icon || (Icon = {}));
637
737
 
638
- function showErrorMessage(text, showRetryBtn, callback) {
738
+ function showErrorMessage(text, showRetryBtn, callback, buttonText, _titleText) {
639
739
  return __awaiter(this, void 0, void 0, function* () {
640
740
  const target = document.querySelector('.authme-container');
641
741
  if (!target) {
@@ -654,7 +754,39 @@ function showErrorMessage(text, showRetryBtn, callback) {
654
754
  if (showRetryBtn) {
655
755
  const retryText = document.createElement('div');
656
756
  retryText.className = 'retry-text';
657
- retryText.textContent = '重試';
757
+ retryText.textContent = buttonText !== null && buttonText !== void 0 ? buttonText : '重試';
758
+ errorMessagePanel.appendChild(retryText);
759
+ if (callback) {
760
+ retryText.addEventListener('click', e => {
761
+ target.removeChild(errorMessagePanel);
762
+ callback(e);
763
+ });
764
+ }
765
+ }
766
+ target === null || target === void 0 ? void 0 : target.appendChild(errorMessagePanel);
767
+ });
768
+ }
769
+ function showErrorMessageEventName(text, showRetryBtn, callback, buttonText, titleText) {
770
+ return __awaiter(this, void 0, void 0, function* () {
771
+ const target = document.querySelector('.authme-container');
772
+ if (!target) {
773
+ return;
774
+ }
775
+ const errorMessagePanel = document.createElement('div');
776
+ errorMessagePanel.classList.add('error-message-panel');
777
+ errorMessagePanel.classList.add('event-name');
778
+ const errorText = document.createElement('div');
779
+ errorText.className = 'error-text';
780
+ errorText.textContent = text;
781
+ const title = document.createElement('div');
782
+ title.className = 'error-title';
783
+ title.textContent = titleText !== null && titleText !== void 0 ? titleText : 'error';
784
+ errorMessagePanel.appendChild(title);
785
+ errorMessagePanel.appendChild(errorText);
786
+ if (showRetryBtn) {
787
+ const retryText = document.createElement('div');
788
+ retryText.className = 'retry-text';
789
+ retryText.textContent = buttonText !== null && buttonText !== void 0 ? buttonText : '重試';
658
790
  errorMessagePanel.appendChild(retryText);
659
791
  if (callback) {
660
792
  retryText.addEventListener('click', e => {
@@ -673,14 +805,17 @@ function hideErrorMessage() {
673
805
  body === null || body === void 0 ? void 0 : body.removeChild(errorMessagePanel);
674
806
  }
675
807
  }
676
- function asyncShowErrorMessage(text, showRetryBtn) {
808
+ function asyncShowErrorMessage(text, showRetryBtn, options) {
809
+ var _a;
677
810
  return __awaiter(this, void 0, void 0, function* () {
811
+ const _showErrorMessage = (_a = options === null || options === void 0 ? void 0 : options.showErrorMessageHandler) !== null && _a !== void 0 ? _a : showErrorMessage;
678
812
  return new Promise((res, rej) => {
813
+ var _a;
679
814
  const callback = () => {
680
815
  res(true);
681
816
  hideErrorMessage();
682
817
  };
683
- showErrorMessage(text, showRetryBtn, callback);
818
+ _showErrorMessage(text, showRetryBtn, (_a = options === null || options === void 0 ? void 0 : options.callback) !== null && _a !== void 0 ? _a : callback, options === null || options === void 0 ? void 0 : options.buttonText, options === null || options === void 0 ? void 0 : options.titleText);
684
819
  });
685
820
  });
686
821
  }
@@ -762,6 +897,7 @@ var BROWSER_CAMERA_ERRORS;
762
897
  BROWSER_CAMERA_ERRORS["NOT_ALLOWED_ERROR"] = "NotAllowedError";
763
898
  BROWSER_CAMERA_ERRORS["NOT_FOUND_ERROR"] = "NotFoundError";
764
899
  })(BROWSER_CAMERA_ERRORS || (BROWSER_CAMERA_ERRORS = {}));
900
+ let stream;
765
901
  const videoConstraintsFactory = (isPC, facingMode) => {
766
902
  return isPC ? {
767
903
  video: {
@@ -842,6 +978,43 @@ function arrayFromAsync(asyncIterable) {
842
978
  return result;
843
979
  });
844
980
  }
981
+ function switchCamera(deviceId, video) {
982
+ return __awaiter(this, void 0, void 0, function* () {
983
+ try {
984
+ if (stream) {
985
+ stream.getTracks().forEach(track => track.stop());
986
+ }
987
+ const constraints = {
988
+ video: {
989
+ // 推測依然需要使用 width & height 的限制條件,
990
+ // 否則即使是高解析度相機,也有可能拿到低解析度的圖片。(待驗證)
991
+ width: {
992
+ min: 1280,
993
+ ideal: 1920,
994
+ max: 1920
995
+ },
996
+ height: {
997
+ min: 720,
998
+ ideal: 1080,
999
+ max: 1080
1000
+ },
1001
+ focusMode: 'auto',
1002
+ deviceId: deviceId
1003
+ }
1004
+ };
1005
+ stream = yield navigator.mediaDevices.getUserMedia(constraints);
1006
+ video.srcObject = stream;
1007
+ yield video.play();
1008
+ // Note: Fix Safari 15 video not showing bug
1009
+ video.srcObject = null;
1010
+ setTimeout(() => {
1011
+ video.srcObject = stream;
1012
+ }, 10);
1013
+ } catch (e) {
1014
+ throw new AuthmeError(ErrorCode.CAMERA_NOT_SUPPORT, e);
1015
+ }
1016
+ });
1017
+ }
845
1018
  function _requestCamera(video, facingMode) {
846
1019
  var _a;
847
1020
  return __awaiter(this, void 0, void 0, function* () {
@@ -916,39 +1089,14 @@ function _requestCamera(video, facingMode) {
916
1089
  if (!deviceId) {
917
1090
  throw BROWSER_CAMERA_ERRORS.NO_CAMERA;
918
1091
  }
919
- const constraints = {
920
- video: {
921
- // 推測依然需要使用 width & height 的限制條件,
922
- // 否則即使是高解析度相機,也有可能拿到低解析度的圖片。(待驗證)
923
- width: {
924
- min: 1280,
925
- ideal: 1920,
926
- max: 1920
927
- },
928
- height: {
929
- min: 720,
930
- ideal: 1080,
931
- max: 1080
932
- },
933
- focusMode: 'auto',
934
- deviceId: {
935
- exact: deviceId
936
- }
937
- }
1092
+ if (stream) {
1093
+ stream.getTracks().forEach(track => track.stop());
1094
+ }
1095
+ yield switchCamera(deviceId, video);
1096
+ return {
1097
+ facingMode: firstDevice.meta.facingMode,
1098
+ deviceMetas: deviceMetas
938
1099
  };
939
- debugLog('camera info', {
940
- firstDevice,
941
- deviceMetas
942
- });
943
- const stream = yield navigator.mediaDevices.getUserMedia(constraints);
944
- video.srcObject = stream;
945
- yield video.play();
946
- // Note: Fix Safari 15 video not showing bug
947
- video.srcObject = null;
948
- setTimeout(() => {
949
- video.srcObject = stream;
950
- }, 10);
951
- return firstDevice.meta.facingMode;
952
1100
  });
953
1101
  }
954
1102
  function isOverconstrainedError(error) {
@@ -960,6 +1108,9 @@ function isOverconstrainedError(error) {
960
1108
  }
961
1109
  return 'constraint' in error;
962
1110
  }
1111
+ function sleep(ms) {
1112
+ return new Promise(resolve => setTimeout(resolve, ms));
1113
+ }
963
1114
  function requestCamera({
964
1115
  video,
965
1116
  facingMode,
@@ -968,7 +1119,29 @@ function requestCamera({
968
1119
  }) {
969
1120
  return __awaiter(this, void 0, void 0, function* () {
970
1121
  try {
971
- return yield _requestCamera(video, facingMode);
1122
+ let perm = yield navigator.permissions.query({
1123
+ name: 'camera'
1124
+ });
1125
+ if (perm.state == 'prompt') {
1126
+ for (let i = 0; i < 5; ++i) {
1127
+ try {
1128
+ //for ios 17.4.1 hack, if you call getUserMedia too early will only get not allowed.
1129
+ yield sleep(1000);
1130
+ return yield _requestCamera(video, facingMode);
1131
+ } catch (error) {
1132
+ if ((error === null || error === void 0 ? void 0 : error.name) === BROWSER_CAMERA_ERRORS.NOT_ALLOWED_ERROR) {
1133
+ perm = yield navigator.permissions.query({
1134
+ name: 'camera'
1135
+ });
1136
+ } else {
1137
+ throw error;
1138
+ }
1139
+ }
1140
+ }
1141
+ return yield _requestCamera(video, facingMode);
1142
+ } else {
1143
+ return yield _requestCamera(video, facingMode);
1144
+ }
972
1145
  } catch (error) {
973
1146
  if (error === BROWSER_CAMERA_ERRORS.NOT_SUPPORT) {
974
1147
  showMessage(translate('camera.error.notFound'));
@@ -1978,7 +2151,7 @@ function RGBToLottieColor(color) {
1978
2151
  }
1979
2152
 
1980
2153
  var name = "@authme/util";
1981
- var version$1 = "2.4.2";
2154
+ var version$1 = "2.4.4-rc.7";
1982
2155
  var peerDependencies = {
1983
2156
  "core-js": "^3.6.0"
1984
2157
  };
@@ -1994,4 +2167,4 @@ const version = packageInfo.version;
1994
2167
  (_a = (_b = window)[_c = Symbol.for('authme-sdk')]) !== null && _a !== void 0 ? _a : _b[_c] = {};
1995
2168
  window[Symbol.for('authme-sdk')][packageInfo.name] = version;
1996
2169
 
1997
- export { AuthmeError, ErrorCode, Icon, RGBToLottieColor, STORAGE_KEY, Storage, TIME_UNIT, UintArrayToBlob, asyncOnLineShowErrorMessage, asyncShowErrorMessage, asyncShowPopup, checkOnlineStatus, clearCanvas, colorStringToRGB, colorToRGB, combineResult, cropByRatio, dataURItoBlob, debugLog, decodeToken, getCanvasSize, getCssVariable, getDeviceInfo, getImageData, getSystemInfo, getUserAgent, hexToRGB, hideElement, hideErrorMessage, hidePopup, isIphone14proOrProMax, isMobile, isMobileOrTablet, requestCamera, resize, retryPromiseWithCondition, showElement, showErrorMessage, showPopup, splitResult, startLoadingSDK, startSpinner, stopLoadingSDK, stopSpinner, useState, version, videoConstraintsFactory, waitTime };
2170
+ export { AuthmeError, ErrorCode, Icon, RGBToLottieColor, STORAGE_KEY, Storage, TIME_UNIT, UintArrayToBlob, asyncOnLineShowErrorMessage, asyncShowErrorMessage, asyncShowPopup, checkOnlineStatus, clearCanvas, colorStringToRGB, colorToRGB, combineResult, cropByRatio, dataURItoBlob, debugLog, debugTools, decodeToken, getCanvasSize, getCssVariable, getDeviceInfo, getImageData, getSystemInfo, getUserAgent, hexToRGB, hideElement, hideErrorMessage, hidePopup, isIphone14proOrProMax, isMobile, isMobileOrTablet, requestCamera, resize, retryPromiseWithCondition, showElement, showErrorMessage, showErrorMessageEventName, showPopup, splitResult, startLoadingSDK, startSpinner, stopLoadingSDK, stopSpinner, switchCamera, useState, version, videoConstraintsFactory, waitTime };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authme/util",
3
- "version": "2.4.2",
3
+ "version": "2.4.4-rc.7",
4
4
  "peerDependencies": {
5
5
  "core-js": "^3.6.0",
6
6
  "jwt-decode": "3.1.2",
@@ -26,5 +26,6 @@ export declare enum ErrorCode {
26
26
  HTTP_ERROR_RESPONSE = 902,
27
27
  USER_CANCEL = 903,
28
28
  CAMERA_NOT_SUPPORT = 904,
29
- SERVER_ERROR = 905
29
+ SERVER_ERROR = 905,
30
+ EVENT_NAME_WRONG = 906
30
31
  }
@@ -1 +1,27 @@
1
1
  export declare function debugLog(message?: any, ...others: any[]): void;
2
+ export interface DebugLog<T> {
3
+ image?: string;
4
+ resultOcrImg?: string;
5
+ result?: any;
6
+ report?: any;
7
+ status?: 'recognition' | 'confirm' | 'run-start' | 'run-end' | 'run-error';
8
+ runFunction?: string;
9
+ roundId?: string;
10
+ type?: T;
11
+ time?: number;
12
+ dateTime?: string;
13
+ message?: any;
14
+ isAntiFraud?: boolean;
15
+ }
16
+ export declare function debugTools<T>(config: {
17
+ debugMode: boolean;
18
+ }): {
19
+ pushNewDebugLog: (logParams: DebugLog<T>) => void;
20
+ getDebugLogs: () => DebugLog<T>[];
21
+ getDebugLogsLength: () => number;
22
+ modifyDeubgLog: (index: number, logParams: Partial<DebugLog<T>>) => void;
23
+ downloadDebugLogs: () => void;
24
+ functionLogging: <P>(func: () => Promise<P>, logParams?: Partial<DebugLog<T>>) => Promise<P>;
25
+ nextDebugRound: (type?: T) => void;
26
+ modifyDebugType: (type: T) => void;
27
+ };
@@ -1,3 +1,19 @@
1
+ export interface DeviceMeta {
2
+ device: MediaDeviceInfo;
3
+ meta: {
4
+ resolution: number;
5
+ facingMode: 'front' | 'back';
6
+ facingModeFromLabel: 'back';
7
+ facingModeFromapabilities: 'front' | 'back';
8
+ capabilities: MediaTrackCapabilities;
9
+ };
10
+ capabilities: MediaTrackCapabilities;
11
+ }
12
+ declare type FacingMode = 'front' | 'back';
13
+ interface RequestCamersResult {
14
+ facingMode: FacingMode;
15
+ deviceMetas: DeviceMeta[];
16
+ }
1
17
  export declare const videoConstraintsFactory: (isPC: boolean, facingMode: 'user' | 'environment') => {
2
18
  video: {
3
19
  width: {
@@ -27,9 +43,11 @@ export declare const videoConstraintsFactory: (isPC: boolean, facingMode: 'user'
27
43
  facingMode: "user" | "environment";
28
44
  };
29
45
  };
46
+ export declare function switchCamera(deviceId: string, video: HTMLVideoElement): Promise<void>;
30
47
  export declare function requestCamera({ video, facingMode, translate, showMessage, }: {
31
48
  video: HTMLVideoElement;
32
49
  facingMode: 'front' | 'back';
33
50
  translate: (key: string) => string;
34
51
  showMessage: (text: string) => void;
35
- }): Promise<'front' | 'back'>;
52
+ }): Promise<RequestCamersResult>;
53
+ export {};
@@ -1,5 +1,12 @@
1
- export declare function showErrorMessage(text: string, showRetryBtn?: boolean, callback?: (e: Event) => void): Promise<void>;
1
+ export declare function showErrorMessage(text: string, showRetryBtn?: boolean, callback?: (e: Event) => void, buttonText?: string, _titleText?: string): Promise<void>;
2
+ export declare function showErrorMessageEventName(text: string, showRetryBtn?: boolean, callback?: (e: Event) => void, buttonText?: string, titleText?: string): Promise<void>;
2
3
  export declare function hideErrorMessage(): void;
3
- export declare function asyncShowErrorMessage(text: string, showRetryBtn?: boolean): Promise<boolean>;
4
+ export declare function asyncShowErrorMessage(text: string, showRetryBtn?: boolean, options?: {
5
+ callback?: (e: Event) => void;
6
+ buttonText?: string;
7
+ titleText?: string;
8
+ errorTextHandler?: (text: Error) => string;
9
+ showErrorMessageHandler?: (text: string) => void;
10
+ }): Promise<boolean>;
4
11
  export declare function asyncOnLineShowErrorMessage(text: string, showRetryBtn?: boolean): Promise<boolean>;
5
12
  export declare function checkOnlineStatus(msg: string): Promise<void>;
@@ -1,2 +1,2 @@
1
- export declare function startSpinner(text?: string): void;
1
+ export declare function startSpinner(text?: string, backgroundOpaque?: boolean): void;
2
2
  export declare function stopSpinner(): void;