@authme/util 2.4.2 → 2.4.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/index.js CHANGED
@@ -16,10 +16,13 @@ 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 Lottie from 'lottie-web';
20
- import 'core-js/modules/es.array.sort.js';
19
+ import 'core-js/modules/es.typed-array.uint32-array.js';
21
20
  import 'core-js/modules/es.array.includes.js';
22
21
  import 'core-js/modules/es.string.includes.js';
22
+ import { saveAs } from 'file-saver';
23
+ import JSZip from 'jszip';
24
+ import Lottie from 'lottie-web';
25
+ import 'core-js/modules/es.array.sort.js';
23
26
  import 'core-js/modules/es.parse-int.js';
24
27
  import 'core-js/modules/es.string.trim.js';
25
28
  import 'core-js/modules/es.string.starts-with.js';
@@ -176,6 +179,7 @@ var ErrorCode;
176
179
  ErrorCode[ErrorCode["USER_CANCEL"] = 903] = "USER_CANCEL";
177
180
  ErrorCode[ErrorCode["CAMERA_NOT_SUPPORT"] = 904] = "CAMERA_NOT_SUPPORT";
178
181
  ErrorCode[ErrorCode["SERVER_ERROR"] = 905] = "SERVER_ERROR";
182
+ ErrorCode[ErrorCode["EVENT_NAME_WRONG"] = 906] = "EVENT_NAME_WRONG";
179
183
  })(ErrorCode || (ErrorCode = {}));
180
184
 
181
185
  function decodeToken(token) {
@@ -469,11 +473,336 @@ const isIphone14proOrProMax = () => {
469
473
  return isIphone() && (screen.width === 430 && screen.height === 932 || screen.width === 393 && screen.height === 852);
470
474
  };
471
475
 
476
+ function fileSaverService() {
477
+ const filesQueue = [];
478
+ function pushFile(file) {
479
+ filesQueue.push(file);
480
+ }
481
+ function popAllFiles() {
482
+ filesQueue.splice(0, filesQueue.length);
483
+ }
484
+ function saveFiles(fileName, json) {
485
+ return __awaiter(this, void 0, void 0, function* () {
486
+ const zip = new JSZip();
487
+ filesQueue.forEach(fileItem => {
488
+ zip.file(fileItem.name, fileItem.file);
489
+ });
490
+ if (json) zip.file('data.json', JSON.stringify(json));
491
+ const content = yield zip.generateAsync({
492
+ type: 'blob'
493
+ });
494
+ saveAs(content, `${fileName}.zip`);
495
+ popAllFiles();
496
+ });
497
+ }
498
+ return {
499
+ pushFile,
500
+ saveFiles
501
+ };
502
+ }
503
+
504
+ const {
505
+ saveFiles,
506
+ pushFile
507
+ } = fileSaverService();
508
+ var RUN_FUNCTION_NAME;
509
+ (function (RUN_FUNCTION_NAME) {
510
+ RUN_FUNCTION_NAME["RECOGNITION"] = "service.recognition";
511
+ RUN_FUNCTION_NAME["ANTI_FARUD_RECOGNITION"] = "antiFraudInstance.recognition";
512
+ RUN_FUNCTION_NAME["API_REQUEST"] = "api.request";
513
+ })(RUN_FUNCTION_NAME || (RUN_FUNCTION_NAME = {}));
472
514
  function debugLog(message, ...others) {
473
515
  if (new URLSearchParams(location.search).get('authme-debug') === 'true') {
474
516
  console.log(message, ...others);
475
517
  }
476
518
  }
519
+ function generateUniqueId(length = 32) {
520
+ if (length <= 0) {
521
+ throw new Error('Length should be a positive integer.');
522
+ }
523
+ // 定義可能的字元
524
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
525
+ const charactersLength = characters.length;
526
+ const randomValues = new Uint32Array(length);
527
+ // 使用window.crypto.getRandomValues取得真正的隨機值
528
+ window.crypto.getRandomValues(randomValues);
529
+ let result = '';
530
+ for (let i = 0; i < length; i++) {
531
+ result += characters[randomValues[i] % charactersLength];
532
+ }
533
+ return result;
534
+ }
535
+ function debugTools() {
536
+ const debugMode = new URLSearchParams(location.search).get('authme-debug') === 'true';
537
+ const debugModeUI = new URLSearchParams(location.search).get('authme-debug-info') === 'true';
538
+ const shouldGetDebugImage = new URLSearchParams(location.search).get('authme-debug-get-image') === 'true';
539
+ const debugLogs = [];
540
+ const logInfo = {
541
+ userAgent: navigator.userAgent,
542
+ token: '',
543
+ message: ''
544
+ };
545
+ let currentRoundId = generateUniqueId(8);
546
+ let currentType = null;
547
+ const interiaTimeObj = {};
548
+ function pushNewDebugLog(logParams) {
549
+ var _a;
550
+ if (!debugMode) return;
551
+ const now = new Date();
552
+ const _logParams = JSON.parse(JSON.stringify(logParams));
553
+ if (_logParams.result) {
554
+ (_a = _logParams.result) === null || _a === void 0 ? true : delete _a.imageData;
555
+ }
556
+ const newDebugLog = Object.assign(Object.assign({
557
+ dateTime: now.toLocaleString(),
558
+ roundId: currentRoundId,
559
+ type: currentType !== null && currentType !== void 0 ? currentType : undefined
560
+ }, _logParams), {
561
+ time: now.getTime(),
562
+ _id: generateUniqueId()
563
+ });
564
+ debugLogs.push(newDebugLog);
565
+ return newDebugLog;
566
+ }
567
+ function pushNewDebugImage(image, log, options) {
568
+ var _a, _b;
569
+ if (!debugMode) return;
570
+ const newLog = pushNewDebugLog(log);
571
+ const recognitionFunctions = [RUN_FUNCTION_NAME.ANTI_FARUD_RECOGNITION, RUN_FUNCTION_NAME.RECOGNITION];
572
+ const currentRoundRecognitionResultItem = debugLogs.find(item => item.roundId === (newLog === null || newLog === void 0 ? void 0 : newLog.roundId) && item.status === 'run-end' && (item.runFunction ? recognitionFunctions.includes(item.runFunction) : false));
573
+ const imageStatus = (_a = currentRoundRecognitionResultItem === null || currentRoundRecognitionResultItem === void 0 ? void 0 : currentRoundRecognitionResultItem.result) === null || _a === void 0 ? void 0 : _a.eStatus;
574
+ pushFile({
575
+ name: `${(_b = options === null || options === void 0 ? void 0 : options.prefix) !== null && _b !== void 0 ? _b : ''}${newLog === null || newLog === void 0 ? void 0 : newLog.time}-${newLog === null || newLog === void 0 ? void 0 : newLog._id}${imageStatus ? `__${imageStatus}` : ''}.jpeg`,
576
+ file: image
577
+ });
578
+ }
579
+ function functionLogging(func, logParams) {
580
+ return new Promise((resolve, reject) => {
581
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
582
+ status: 'run-start'
583
+ }));
584
+ func().then(result => {
585
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
586
+ status: 'run-end',
587
+ roundId: currentRoundId,
588
+ result
589
+ }));
590
+ resolve(result);
591
+ }).catch(error => {
592
+ pushNewDebugLog(Object.assign(Object.assign({}, logParams), {
593
+ status: 'run-error',
594
+ roundId: currentRoundId,
595
+ result: error
596
+ }));
597
+ reject(error);
598
+ });
599
+ });
600
+ }
601
+ function renderDebugTips() {
602
+ if (document.getElementById('debug-tips')) {
603
+ return;
604
+ }
605
+ const debugTips = document.createElement('div');
606
+ debugTips.style.position = 'fixed';
607
+ debugTips.style.top = '50px';
608
+ debugTips.style.right = '0';
609
+ debugTips.style.zIndex = '999';
610
+ debugTips.innerHTML = 'Debug Mode';
611
+ debugTips.style.color = 'red';
612
+ debugTips.style.fontWeight = 'bold';
613
+ debugTips.setAttribute('id', 'debug-tips');
614
+ document.body.appendChild(debugTips);
615
+ }
616
+ function renderDebugUI() {
617
+ if (document.getElementById('debug-ui')) {
618
+ return;
619
+ }
620
+ const debugUI = document.createElement('div');
621
+ debugUI.style.position = 'fixed';
622
+ debugUI.style.top = '0';
623
+ debugUI.style.right = '0';
624
+ debugUI.style.zIndex = '777';
625
+ debugUI.style.backgroundColor = 'black';
626
+ debugUI.style.color = 'white';
627
+ debugUI.style.padding = '10px';
628
+ debugUI.style.paddingRight = '150px';
629
+ debugUI.style.fontSize = '12px';
630
+ debugUI.style.opacity = '0.7';
631
+ debugUI.style.boxSizing = 'border-box';
632
+ debugUI.style.width = '100%';
633
+ debugUI.style.maxHeight = '50vh';
634
+ debugUI.style.overflow = 'auto';
635
+ debugUI.setAttribute('id', 'debug-ui');
636
+ const closeUI = document.createElement('button');
637
+ closeUI.style.position = 'fixed';
638
+ closeUI.style.top = '0';
639
+ closeUI.style.right = '100px';
640
+ closeUI.innerHTML = 'close';
641
+ closeUI.addEventListener('click', () => {
642
+ debugUI.style.display = 'none';
643
+ });
644
+ debugUI.appendChild(closeUI);
645
+ const accordionUI = document.createElement('button');
646
+ accordionUI.style.position = 'fixed';
647
+ accordionUI.style.top = '0';
648
+ accordionUI.style.right = '0';
649
+ accordionUI.innerHTML = '收合/展開';
650
+ accordionUI.addEventListener('click', () => {
651
+ if (debugUI.style.maxHeight === '50vh') {
652
+ debugUI.style.maxHeight = '5vh';
653
+ } else {
654
+ debugUI.style.maxHeight = '50vh';
655
+ }
656
+ });
657
+ debugUI.appendChild(accordionUI);
658
+ document.body.appendChild(debugUI);
659
+ }
660
+ function setTimeStart(behavior) {
661
+ if (!debugModeUI) {
662
+ return;
663
+ }
664
+ const dStart = new Date();
665
+ const nStart = dStart.getTime();
666
+ if (interiaTimeObj && interiaTimeObj[behavior]) {
667
+ console.error('debugmode: setTimeStart duplicate', behavior);
668
+ return false;
669
+ }
670
+ interiaTimeObj[behavior] = {
671
+ behavior,
672
+ start: nStart / 1000,
673
+ duration: 0,
674
+ end: 0
675
+ };
676
+ // console.log(interiaTimeObj[behavior])
677
+ renderTimeInfo(behavior);
678
+ return interiaTimeObj[behavior];
679
+ }
680
+ function setTimeEnd(behavior) {
681
+ if (!debugModeUI) {
682
+ return;
683
+ }
684
+ const dEnd = new Date();
685
+ const nEnd = dEnd.getTime();
686
+ if (!interiaTimeObj[behavior]) {
687
+ console.error('debugmode: setTimeEnd not found', behavior);
688
+ return false;
689
+ }
690
+ interiaTimeObj[behavior].end = nEnd / 1000;
691
+ interiaTimeObj[behavior].duration = interiaTimeObj[behavior].end - interiaTimeObj[behavior].start;
692
+ // console.log(interiaTimeObj[behavior])
693
+ renderTimeInfo(behavior);
694
+ return interiaTimeObj[behavior];
695
+ }
696
+ function setTimeDuration(behavior) {
697
+ const ts = Date.now();
698
+ setTimeStart(`${behavior}_${ts}`);
699
+ return {
700
+ end: () => {
701
+ setTimeEnd(`${behavior}_${ts}`);
702
+ }
703
+ };
704
+ }
705
+ function renderTimeInfo(behavior) {
706
+ const dom = document.querySelector(`#debug-ui-${behavior}`);
707
+ const info = `{"behavior":<span style="color:green;">"${behavior}"</span>, "start": ${interiaTimeObj[behavior].start}, "duration": ${interiaTimeObj[behavior].duration}, "end": ${interiaTimeObj[behavior].end}}`;
708
+ // const info = `<span style="color:green;">${behavior}</span>: Duration: ${interiaTimeObj[behavior].duration}s`;
709
+ if (dom) {
710
+ dom.innerHTML = info;
711
+ return;
712
+ }
713
+ const debugUI = document.getElementById('debug-ui');
714
+ const div = document.createElement('div');
715
+ div.setAttribute('class', 'debug-ui-item');
716
+ div.setAttribute('id', `debug-ui-${behavior}`);
717
+ div.innerHTML = info;
718
+ debugUI.appendChild(div);
719
+ }
720
+ function functionRunTime() {
721
+ const arr = [];
722
+ const items = document.querySelectorAll('.debug-ui-item');
723
+ items.forEach(item => {
724
+ arr.push(JSON.parse(item.innerText));
725
+ });
726
+ return arr;
727
+ }
728
+ if (debugMode) {
729
+ renderDebugTips();
730
+ // setRequestLoggingFunc(functionLogging)
731
+ }
732
+
733
+ if (debugModeUI) {
734
+ console.log('debugModeUI Init');
735
+ renderDebugUI();
736
+ }
737
+ function saveDebugImage({
738
+ getDebugImageData,
739
+ data,
740
+ width,
741
+ height,
742
+ result,
743
+ type
744
+ }) {
745
+ return __awaiter(this, void 0, void 0, function* () {
746
+ if (!debugMode || !shouldGetDebugImage) return;
747
+ const debugImage = yield getDebugImageData(data);
748
+ // 創建一個虛擬的 canvas
749
+ const canvas = document.createElement('canvas');
750
+ const ctx = canvas.getContext('2d');
751
+ // 設置 canvas 的尺寸
752
+ canvas.width = width;
753
+ canvas.height = height;
754
+ // 使用 Uint8ClampedArray 將圖像數據繪製到 canvas 上
755
+ const imgData = ctx === null || ctx === void 0 ? void 0 : ctx.createImageData(width, height);
756
+ if (imgData) {
757
+ imgData.data.set(debugImage);
758
+ ctx === null || ctx === void 0 ? void 0 : ctx.putImageData(imgData, 0, 0);
759
+ canvas.toBlob(blob => {
760
+ if (blob) {
761
+ pushNewDebugImage(blob, {
762
+ result: result,
763
+ status: 'recognition',
764
+ type: type
765
+ }, {
766
+ prefix: 'debugImage_'
767
+ });
768
+ }
769
+ }, 'image/jpeg');
770
+ }
771
+ });
772
+ }
773
+ return {
774
+ debugMode,
775
+ debugModeUI,
776
+ pushNewDebugLog,
777
+ getDebugLogs: () => debugLogs,
778
+ getDebugLogsLength: () => debugLogs.length,
779
+ modifyDeubgLog: (index, logParams) => {
780
+ if (!debugMode) return;
781
+ debugLogs[index] = Object.assign(Object.assign({}, debugLogs[index]), logParams);
782
+ },
783
+ downloadDebugLogs: () => {
784
+ if (!debugMode) return;
785
+ saveFiles(`debugLog${new Date().getTime().toString()}`, {
786
+ info: logInfo,
787
+ logs: debugLogs,
788
+ functionRunTime: functionRunTime()
789
+ });
790
+ },
791
+ functionLogging,
792
+ nextDebugRound: type => {
793
+ if (!debugMode) return;
794
+ currentRoundId = generateUniqueId(8);
795
+ if (type) currentType = type;
796
+ },
797
+ modifyDebugType: type => {
798
+ if (!debugMode) return;
799
+ currentType = type;
800
+ },
801
+ pushNewDebugImage,
802
+ setTimeDuration: setTimeDuration,
803
+ saveDebugImage
804
+ };
805
+ }
477
806
 
478
807
  var TIME_UNIT;
479
808
  (function (TIME_UNIT) {
@@ -578,7 +907,7 @@ function cropByRatio(width, height, ratio) {
578
907
  };
579
908
  }
580
909
 
581
- function startSpinner(text) {
910
+ function startSpinner(text, backgroundOpaque) {
582
911
  const loadingLottie = Storage.getItem(STORAGE_KEY.LOADING_LOTTIE);
583
912
  const body = document.querySelector('.authme-container');
584
913
  if (loadingLottie) {
@@ -602,6 +931,9 @@ function startSpinner(text) {
602
931
  loadingSDKText.textContent = text;
603
932
  loadingSDKContent.appendChild(loadingSDKText);
604
933
  }
934
+ if (backgroundOpaque) {
935
+ loadingSDKOuter.classList.add('authme-loading-sdk-outer--opaque');
936
+ }
605
937
  return;
606
938
  }
607
939
  const spinnerOuter = document.createElement('div');
@@ -615,6 +947,9 @@ function startSpinner(text) {
615
947
  spinnerText.textContent = text;
616
948
  spinnerOuter.appendChild(spinnerText);
617
949
  }
950
+ if (backgroundOpaque) {
951
+ spinnerOuter.classList.add('loading-outer--opaque');
952
+ }
618
953
  body === null || body === void 0 ? void 0 : body.appendChild(spinnerOuter);
619
954
  }
620
955
  function stopSpinner() {
@@ -635,7 +970,7 @@ var Icon;
635
970
  Icon["PictureIcon"] = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAt9SURBVHgB7VxdTFRJFq7q23/Q0NC6IKDGhrgiG4mSGAejmyDoToxri5F1ZV9Gk0lWn8CnyY4Pgw9rsk+LT2M2k+juw+KOGBU3cUYjsoljNDFRA1llZwNNEJVGpIFu+v/W1mmmtar63u6G/pHu7e9Fq/rem3s/vlPnVNU5hVAeeeSRx/8vMPqImGntLEWFfisKBZs0RNpAELIiRLaFfyTwfwYY2RHBTvqDE2P8VMahMYQ1Ty2XLwygj4iMExgmzbBwHMuaQ4tk4VKUPAYo+X9FEhqghNpRBpERAnnSUBNKL8JkWq5cuIQygLQSCMRp9N4OQkhnipS2FNgxRpdkDSUzjapMC4FLIS4gYcecVjM0p5NG3DrJMaXXOFxajftHc8Eke93P5zxrioKyqcwvl6/yBasLg6EaU4BU6wgpR7ERJrLk2wtnURqQcgJnjp1swjK6GOUEGFCChqaM2odDJYZHIlFLxcZ5b3ndvH9Lpdu/lxK8JcaldoLl05Zv/3IdpRApI3BRdb6vFlUXjRDG7skCbV9/RXGfw6B1ozQAyNw95W4v9sv1asrEmHTL/oKzluvdTpQCpIRAqjorVd09JdVlgjgR5b6g6ZcOV0uVO2BTIdJOJLQnFWNj0gSGTTZErimNdVMFur7vK4t7YhFXWVlpqqurq1m7dm11aWlpjclkqtZqtSadTsd9eCAQcPh8Pgf91z09PT04MTEx2t/fP4hiIKLIVb5QS/Sv2ElkdMJy9eukTDopAmd/+/sOIuNusT+AsePJ6sLz98tMih8IpG3fvr1+8+bNtoKCgmpJkkxoGQiFQu65ubkhSubDK1eu3FW7DojcPzF/TkmNRINPW/7xdTdaJpZN4OzRk3S8Q11ifyzVAXEHDhywVVVV2ZZLmhpAoZTMwdu3b19+8eJFlGMCs/709Vx7mSdoE3+jXrpruV56WQSqKW+0SP/NtfWlfWJ/OolTwvj4eM/9+/f7lYg8NjbTXrUQaBf7l6vEJRM4c+RUK9bAmMfjP2bj+X+uNUeZ0aFDhz7ZunVrZyaIYwGKHB4e7lEy7V9PzLVsmvN2iP3UovZYepc2t14SgWFvGyJPRIdxb42p88kq0wjbB6prbW1tr6iosKGPiDdv3vRdv3695/Xr19yQ0vDOXbNn0i0ojjoWiTQsxTsnTCDEeVjvfSKGKkrKo161nJL3pdForEErAKDG3t7eM6JJqyjRTgLGhkTjRA1KEBAki+S9KtT1KJF35MiRcyuFPACERG1tbX+kXn8N2w/vPkbHbeFyq0bv+QolCCmRi2aOnmqlAwQnd/C2f7da/sb2RcgTY7iVABiDKYGNDofj0du3b9+b8/MS4/BGt89kCsq1H67GjV/8Yvu//vTvx/Z4z01IgRiRP7NtiPMgVGH7VjJ5Eagp8ftKcw98E9tHQ5uL4WW4OIhLIMR7oul+V1V0ho3zwGGsdPIigHc8fPjwH+CdI33wLRD4C5dakd7bGe95MQkEr0sXJ4+zfe8M0l1xBQW8bTaQFwGMz/DObB/MmqbonJ3twwR3xFNhTAI1MvqMVR/I/IefFV5mrzl69Gjzxw5VlgN454MHDzayfWDKsPjxoYeUxlNhTAJF9b006fpY9cG4t2nTpt+hLEVDQ0OHaMqTS1ShKoEzvzl5PEp95SVcyLJr166WbDJdEeCZ9+/fz1kPLLtFqdDgO672DFUCaYT9Gdue12sGHYYPDwb1rV+/vh1lOdatW2eLq0KZHFK7X5FAcB5I2D0Tx759+/ZlPXkANRUKlzWpmbGyAkM8ebCHIXpes9lcj3IESipc0Er8WqaKGSsSKJrvq0I9N/aB583msU8EqHDHjh3chtSkUXrEttXMWG0MbGIbw8W6IbZN/2KNKMdQW1vLmfFgqfEhfwXepmTGUQTCHgfbBu8rmm9RUVHOmG8EEFyzZvzfYqODn96RxTweAdEKJPI2tunVYW6dr7m5uT7Ti6OZAHwTbG6xfRB5cBeFSJN4XzSBssbKPUQrjbJt2D1DOQrx22Z1/LcjmVjFe6IIpA5kK9ueNug4BZaVlcXa/c9q0MiCUyCkmgiXWMV7FJwIv1w/bdBwD6FSL0I5CkqglW1P6bX8EpcgLkA0gZhwBM5LeIFtGwyGnAlfRIjimNdhV7x7FJwIL1PRA+dS/CdC/DbwxMIlVvGehPdE8lBGnsAkkScwSSg4EWRnm5AZyrZhjxXlKMRvg6Qk4RK7eE9cBRaHSCHbhowolKOA9Dm2XRwgQshGojbbleLAp2xrtU/m/goul2sE5SioOLiwpcwfFBSI4xNICBlj20WBIGfCTqdzFOUopqamuFUnSGZn23SP6Jl4T7QCNbKdbZYGQtz0BjJDUY5C/DZqwvy8X4Pt4j0KiwnaAbZZ5Ocz358/fz6Si+MgfJOYMmwM8uKhqzFPxfuiCQzo7exgCWmxrCeGNDGv15tz4yAd2znyNs4HysWUYKXcwSgCF9O6eEeyZdb3CdumKryJcgzj4+PcEn7dvEdcdRpQuk8xjCEa+QbbXuMNcQQ+fvx4MJfMGOI/MZO10uXfy7bDxYwKUI4DfYWX2GZhMFRf7iPvV6HBjF++fNmHcgSzs7NR5lsUEqqepCUo8KfsTO6G5jdObtPl1q1bfbmiwjt37nB73rsdLnHPW7WMVnUmEmXGnqAtF1U4NjbWw6b+QjlEcSDIbZqpmS9AfSoXNuMP3lgixKSkwmyeG8O7P3jwoJ/t2/XG1SJ4X3us2mNVAsGMCcZc0qGSCp89e/YNylJAGQSrPhj71nkCnEgIUVcfIPZigt/YLarwVxNObny4efPmQyglQFkGeGfR88LYJ6oPadGlWM+JSaCSCst9AdvuKTc3RkAdBl3JyJrgGkwX3pntA/Wt8ge4okRQX7yakfgLqqBCYY2wYXqhQzTla9euncuG8TBSM8IW3sC37J9wnhMutdOZR1e858UlMKxCGZ1g+0DmoinT2Ynj6tWrX65kEtUKbj6dmBFNFxEZn07kmQnViUC9xBd12y0Yo/dJRaaQXFvhDbhflBiHI31Qf0GXhB7W1tY2rrT0DzXyjtln2iu8wTa2jwrmvOXqhYQKDxPfEwkZu0RTrnb5P4dyKbZvJSoRFj8US73G51qqPFGVm/bwtyaIFBUbFnc+WVWQZcWGnpo9k/OCyoiTSDg9xYYRzLSdbKKmfE/sVyt3hWRMyOTP9IY8TDNpjNp948aNR+JvoLxNLoVyVxkfXuoRAMsquJ5pO9WJMV/+BXhVoOu5bLX0iP2QkL5z586WDRs2pD2vGoiDKSbMkkTVAQ6POW3VC/7PxX5C8GlLbwYKriOgSuyiSoyqanQYdH2315b2sBn9EQCRe/fubS8pKalPtSLjEQehCnjbMl90yT+N984mErIoIalDJ9SUCJmd31WVnPnRrFc9VAdMu6qqaqfZbN6SzKETHo9nlDqHPlijVCIOAIE/xK6Kh04sU3kRJH/sSfgIAPmi0rEn7/S6uz+UmS7HIhIAWa+Q3Lh69WpQpgkywJSOPQHC6NL7KN0ZHIENINifUSMNEEt1YYdB6JjXm9zxeWk/eAfUCCViUOWkZNbpABDX/NppW+MN2mD+rnDJyjl4J4JwBrvk7cIa1KH0OxA5r9MOJqLI5SIB4sJBMsR5K+roJxZhk5bouBjr8DFJM/TKpL87XGwcSpZM2DGETa8yT7Axahmeh506ixPJmqyItJ0fGPbSGr5cVgmgTI+kGXXpNSPvDNpRSKt1aZHK8XfIBOkWpkCo3OwL1ZiD8pb4x9+Fx7rzKGjsTpXqWKT3AEaouQui44kQmXqkl7gIMnaGKpTP/lRC1oTSi4Hwfg7dkkgncRFkjMAIwqoMoabUkUnCiQCZJI1FxgkUAXNrJMnboMBnsYyAxpNQKaB0DHIY5Ck1zbFwEpRMBlDAZM80aXnkkUceeSzif3+l5taU5LriAAAAAElFTkSuQmCC";
636
971
  })(Icon || (Icon = {}));
637
972
 
638
- function showErrorMessage(text, showRetryBtn, callback) {
973
+ function showErrorMessage(text, showRetryBtn, callback, buttonText, _titleText) {
639
974
  return __awaiter(this, void 0, void 0, function* () {
640
975
  const target = document.querySelector('.authme-container');
641
976
  if (!target) {
@@ -654,7 +989,40 @@ function showErrorMessage(text, showRetryBtn, callback) {
654
989
  if (showRetryBtn) {
655
990
  const retryText = document.createElement('div');
656
991
  retryText.className = 'retry-text';
657
- retryText.textContent = '重試';
992
+ retryText.textContent = buttonText !== null && buttonText !== void 0 ? buttonText : '重試';
993
+ errorMessagePanel.appendChild(retryText);
994
+ if (callback) {
995
+ retryText.addEventListener('click', e => {
996
+ callback(e, {
997
+ hideErrorMessage
998
+ });
999
+ });
1000
+ }
1001
+ }
1002
+ target === null || target === void 0 ? void 0 : target.appendChild(errorMessagePanel);
1003
+ });
1004
+ }
1005
+ function showErrorMessageEventName(text, showRetryBtn, callback, buttonText, titleText) {
1006
+ return __awaiter(this, void 0, void 0, function* () {
1007
+ const target = document.querySelector('.authme-container');
1008
+ if (!target) {
1009
+ return;
1010
+ }
1011
+ const errorMessagePanel = document.createElement('div');
1012
+ errorMessagePanel.classList.add('error-message-panel');
1013
+ errorMessagePanel.classList.add('event-name');
1014
+ const errorText = document.createElement('div');
1015
+ errorText.className = 'error-text';
1016
+ errorText.textContent = text;
1017
+ const title = document.createElement('div');
1018
+ title.className = 'error-title';
1019
+ title.textContent = titleText !== null && titleText !== void 0 ? titleText : 'error';
1020
+ errorMessagePanel.appendChild(title);
1021
+ errorMessagePanel.appendChild(errorText);
1022
+ if (showRetryBtn) {
1023
+ const retryText = document.createElement('div');
1024
+ retryText.className = 'retry-text';
1025
+ retryText.textContent = buttonText !== null && buttonText !== void 0 ? buttonText : '重試';
658
1026
  errorMessagePanel.appendChild(retryText);
659
1027
  if (callback) {
660
1028
  retryText.addEventListener('click', e => {
@@ -673,27 +1041,29 @@ function hideErrorMessage() {
673
1041
  body === null || body === void 0 ? void 0 : body.removeChild(errorMessagePanel);
674
1042
  }
675
1043
  }
676
- function asyncShowErrorMessage(text, showRetryBtn) {
1044
+ function asyncShowErrorMessage(text, showRetryBtn, options) {
1045
+ var _a;
677
1046
  return __awaiter(this, void 0, void 0, function* () {
1047
+ const _showErrorMessage = (_a = options === null || options === void 0 ? void 0 : options.showErrorMessageHandler) !== null && _a !== void 0 ? _a : showErrorMessage;
678
1048
  return new Promise((res, rej) => {
1049
+ var _a;
679
1050
  const callback = () => {
680
1051
  res(true);
681
1052
  hideErrorMessage();
682
1053
  };
683
- showErrorMessage(text, showRetryBtn, callback);
1054
+ _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
1055
  });
685
1056
  });
686
1057
  }
687
1058
  function asyncOnLineShowErrorMessage(text, showRetryBtn) {
688
1059
  return __awaiter(this, void 0, void 0, function* () {
689
1060
  return new Promise((res, rej) => {
690
- const callback = () => {
1061
+ showErrorMessage(text, showRetryBtn, (_, tools) => {
691
1062
  if (window.navigator.onLine) {
692
1063
  res(true);
693
- hideErrorMessage();
1064
+ tools === null || tools === void 0 ? void 0 : tools.hideErrorMessage();
694
1065
  }
695
- };
696
- showErrorMessage(text, showRetryBtn, callback);
1066
+ });
697
1067
  });
698
1068
  });
699
1069
  }
@@ -761,7 +1131,10 @@ var BROWSER_CAMERA_ERRORS;
761
1131
  BROWSER_CAMERA_ERRORS["NO_CAMERA"] = "NO_CAMERA";
762
1132
  BROWSER_CAMERA_ERRORS["NOT_ALLOWED_ERROR"] = "NotAllowedError";
763
1133
  BROWSER_CAMERA_ERRORS["NOT_FOUND_ERROR"] = "NotFoundError";
1134
+ BROWSER_CAMERA_ERRORS["NOT_READABLE_ERROR"] = "NotReadableError";
1135
+ BROWSER_CAMERA_ERRORS["ABORT_ERROR"] = "AbortError";
764
1136
  })(BROWSER_CAMERA_ERRORS || (BROWSER_CAMERA_ERRORS = {}));
1137
+ let stream;
765
1138
  const videoConstraintsFactory = (isPC, facingMode) => {
766
1139
  return isPC ? {
767
1140
  video: {
@@ -842,6 +1215,43 @@ function arrayFromAsync(asyncIterable) {
842
1215
  return result;
843
1216
  });
844
1217
  }
1218
+ function switchCamera(deviceId, video) {
1219
+ return __awaiter(this, void 0, void 0, function* () {
1220
+ try {
1221
+ if (stream) {
1222
+ stream.getTracks().forEach(track => track.stop());
1223
+ }
1224
+ const constraints = {
1225
+ video: {
1226
+ // 推測依然需要使用 width & height 的限制條件,
1227
+ // 否則即使是高解析度相機,也有可能拿到低解析度的圖片。(待驗證)
1228
+ width: {
1229
+ min: 1280,
1230
+ ideal: 1920,
1231
+ max: 1920
1232
+ },
1233
+ height: {
1234
+ min: 720,
1235
+ ideal: 1080,
1236
+ max: 1080
1237
+ },
1238
+ focusMode: 'auto',
1239
+ deviceId: deviceId
1240
+ }
1241
+ };
1242
+ stream = yield navigator.mediaDevices.getUserMedia(constraints);
1243
+ video.srcObject = stream;
1244
+ yield video.play();
1245
+ // Note: Fix Safari 15 video not showing bug
1246
+ video.srcObject = null;
1247
+ setTimeout(() => {
1248
+ video.srcObject = stream;
1249
+ }, 10);
1250
+ } catch (e) {
1251
+ throw new AuthmeError(ErrorCode.CAMERA_NOT_SUPPORT, e);
1252
+ }
1253
+ });
1254
+ }
845
1255
  function _requestCamera(video, facingMode) {
846
1256
  var _a;
847
1257
  return __awaiter(this, void 0, void 0, function* () {
@@ -916,39 +1326,14 @@ function _requestCamera(video, facingMode) {
916
1326
  if (!deviceId) {
917
1327
  throw BROWSER_CAMERA_ERRORS.NO_CAMERA;
918
1328
  }
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
- }
1329
+ if (stream) {
1330
+ stream.getTracks().forEach(track => track.stop());
1331
+ }
1332
+ yield switchCamera(deviceId, video);
1333
+ return {
1334
+ facingMode: firstDevice.meta.facingMode,
1335
+ deviceMetas: deviceMetas
938
1336
  };
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
1337
  });
953
1338
  }
954
1339
  function isOverconstrainedError(error) {
@@ -982,6 +1367,15 @@ function requestCamera({
982
1367
  showMessage(translate('camera.error.notFound'));
983
1368
  throw new AuthmeError(ErrorCode.CAMERA_NOT_SUPPORT, error);
984
1369
  }
1370
+ if ((error === null || error === void 0 ? void 0 : error.name) === BROWSER_CAMERA_ERRORS.NOT_READABLE_ERROR || (error === null || error === void 0 ? void 0 : error.name) === BROWSER_CAMERA_ERRORS.ABORT_ERROR) {
1371
+ showMessage(translate('camera.error.notFound'));
1372
+ /* NOT_READABLE_ERROR,ABORT_ERROR 這兩個錯誤是用戶授權了,但在呼叫裝置時出現錯誤,
1373
+ * 常發生在APP webview ,例如: 手機開啟 web 使用 sdk,儘管在 webview 層級上授權了,但手機在設定層級沒有授權 app 使用相機,會導致此問題。
1374
+ * 但每個 android 手機的在這方面的實作不一致,不是每個手機在這種情況下都會拋出錯誤。
1375
+ * 參考 https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia#notreadableerror
1376
+ */
1377
+ throw new AuthmeError(ErrorCode.CAMERA_NOT_SUPPORT, error);
1378
+ }
985
1379
  if (isOverconstrainedError(error)) {
986
1380
  showMessage(translate('camera.error.lowResolution'));
987
1381
  throw new AuthmeError(ErrorCode.CAMERA_NOT_SUPPORT, error);
@@ -1977,15 +2371,46 @@ function RGBToLottieColor(color) {
1977
2371
  return color.map(c => c / 255);
1978
2372
  }
1979
2373
 
2374
+ const QUEUE_LENGTH = 10;
2375
+ const requstQueue = [];
2376
+ function pushRequest(request) {
2377
+ if (requstQueue.length > QUEUE_LENGTH - 1) {
2378
+ requstQueue.shift();
2379
+ }
2380
+ requstQueue.push(request);
2381
+ }
2382
+ function clearRequest() {
2383
+ requstQueue.splice(0, requstQueue.length);
2384
+ }
2385
+ function backgroundRequest(request) {
2386
+ const requestPromise = request();
2387
+ requestPromise.catch(err => {
2388
+ if (err._code === ErrorCode.NETWORK_ERROR) {
2389
+ pushRequest(request);
2390
+ }
2391
+ });
2392
+ }
2393
+ window.ononline = () => {
2394
+ const tasks = [...requstQueue];
2395
+ clearRequest();
2396
+ tasks.forEach(request => {
2397
+ backgroundRequest(request);
2398
+ });
2399
+ };
2400
+
1980
2401
  var name = "@authme/util";
1981
- var version$1 = "2.4.2";
2402
+ var version$1 = "2.4.6";
1982
2403
  var peerDependencies = {
1983
2404
  "core-js": "^3.6.0"
1984
2405
  };
2406
+ var devDependencies = {
2407
+ "@types/file-saver": "^2.0.5"
2408
+ };
1985
2409
  var packageInfo = {
1986
2410
  name: name,
1987
2411
  version: version$1,
1988
- peerDependencies: peerDependencies
2412
+ peerDependencies: peerDependencies,
2413
+ devDependencies: devDependencies
1989
2414
  };
1990
2415
 
1991
2416
  var _a;
@@ -1994,4 +2419,4 @@ const version = packageInfo.version;
1994
2419
  (_a = (_b = window)[_c = Symbol.for('authme-sdk')]) !== null && _a !== void 0 ? _a : _b[_c] = {};
1995
2420
  window[Symbol.for('authme-sdk')][packageInfo.name] = version;
1996
2421
 
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 };
2422
+ export { AuthmeError, ErrorCode, Icon, RGBToLottieColor, RUN_FUNCTION_NAME, STORAGE_KEY, Storage, TIME_UNIT, UintArrayToBlob, asyncOnLineShowErrorMessage, asyncShowErrorMessage, asyncShowPopup, backgroundRequest, 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,12 +1,17 @@
1
1
  {
2
2
  "name": "@authme/util",
3
- "version": "2.4.2",
3
+ "version": "2.4.6",
4
4
  "peerDependencies": {
5
5
  "core-js": "^3.6.0",
6
6
  "jwt-decode": "3.1.2",
7
7
  "rxjs": "7.5.7",
8
+ "file-saver": "2.0.5",
9
+ "jszip": "3.10.1",
8
10
  "lottie-web": "5.9.6"
9
11
  },
12
+ "devDependencies": {
13
+ "@types/file-saver": "^2.0.5"
14
+ },
10
15
  "module": "./index.js",
11
16
  "main": "./index.cjs",
12
17
  "type": "module",
package/src/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './lib/shared-util';
2
2
  export * from './ui';
3
+ export * from './lib/background-request-process';
3
4
  export { version } from './lib/version';
@@ -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
  }