@authme/util 2.8.1 → 2.8.3

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
@@ -25,9 +25,9 @@ require('core-js/modules/es.array.includes.js');
25
25
  require('core-js/modules/es.string.includes.js');
26
26
  var fileSaver = require('file-saver');
27
27
  var JSZip = require('jszip');
28
+ require('core-js/modules/es.parse-int.js');
28
29
  var Lottie = require('lottie-web');
29
30
  require('core-js/modules/es.array.sort.js');
30
- require('core-js/modules/es.parse-int.js');
31
31
  require('core-js/modules/es.string.trim.js');
32
32
  require('core-js/modules/es.string.starts-with.js');
33
33
  require('core-js/modules/es.symbol.description.js');
@@ -995,9 +995,81 @@ function cropByRatio(width, height, ratio) {
995
995
  };
996
996
  }
997
997
 
998
- function startSpinner(text, backgroundOpaque) {
998
+ const fontWeight = {
999
+ regular: '400',
1000
+ medium: '500',
1001
+ bold: '700'
1002
+ };
1003
+ const hexToRgba = (hex, alpha = 1) => {
1004
+ // 移除 # 符號(如果有的話)
1005
+ hex = hex.replace(/^#/, '');
1006
+ // 解析短格式 (e.g., #RGB -> #RRGGBB)
1007
+ if (hex.length === 3) {
1008
+ hex = hex.split('').map(x => x + x).join('');
1009
+ }
1010
+ // 確保是有效的 HEX 格式
1011
+ if (hex.length !== 6) {
1012
+ throw new Error('Invalid HEX color.');
1013
+ }
1014
+ // 轉換 HEX 到 RGB
1015
+ const r = parseInt(hex.substring(0, 2), 16);
1016
+ const g = parseInt(hex.substring(2, 4), 16);
1017
+ const b = parseInt(hex.substring(4, 6), 16);
1018
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
1019
+ };
1020
+ const uiThemeText = (dom, textStyle) => {
1021
+ dom.style.color = textStyle.textColor;
1022
+ dom.style.fontWeight = fontWeight[textStyle.textWeight];
1023
+ dom.style.fontSize = `${textStyle.fontSize}px`;
1024
+ };
1025
+ const uiThemeHint = (dom, hintStyle) => {
1026
+ dom.style.borderRadius = `${hintStyle.cornerRadius}px`;
1027
+ dom.style.backgroundColor = hintStyle.backgroundColor;
1028
+ dom.style.opacity = hintStyle.opacity;
1029
+ dom.style.color = hintStyle.textColor;
1030
+ dom.style.fontWeight = fontWeight[hintStyle.textWeight];
1031
+ dom.style.fontSize = `${hintStyle.fontSize}px`;
1032
+ };
1033
+ const uiThemeButton = (dom, buttonStyle) => {
1034
+ dom.style.borderRadius = `${buttonStyle.cornerRadius}px`;
1035
+ dom.style.backgroundColor = buttonStyle.backgroundColor;
1036
+ dom.style.opacity = buttonStyle.backgroundOpacity;
1037
+ dom.style.color = buttonStyle.textColor;
1038
+ dom.style.borderColor = hexToRgba(buttonStyle.borderColor, buttonStyle.borderOpacity);
1039
+ dom.style.borderWidth = `${buttonStyle.borderWidth}px`;
1040
+ dom.style.fontWeight = fontWeight[buttonStyle.textWeight];
1041
+ dom.style.fontSize = `${buttonStyle.fontSize}px`;
1042
+ dom.style.borderStyle = 'solid';
1043
+ // dom.style.height = `${buttonStyle.cornerRadius * 2}px`;
1044
+ dom.style.height = `48px`;
1045
+ dom.style.width = `calc(100% - ${buttonStyle.cornerRadius * 2}px)`;
1046
+ dom.style.maxWidth = `327px`;
1047
+ };
1048
+ const uiThemeSmallButton = (dom, buttonStyle) => {
1049
+ dom.style.borderRadius = `${buttonStyle.cornerRadius}px`;
1050
+ dom.style.backgroundColor = buttonStyle.backgroundColor;
1051
+ dom.style.opacity = buttonStyle.backgroundOpacity;
1052
+ dom.style.color = buttonStyle.textColor;
1053
+ dom.style.borderColor = hexToRgba(buttonStyle.borderColor, buttonStyle.borderOpacity);
1054
+ dom.style.borderWidth = `${buttonStyle.borderWidth}px`;
1055
+ dom.style.fontWeight = fontWeight[buttonStyle.textWeight];
1056
+ dom.style.fontSize = `${buttonStyle.fontSize}px`;
1057
+ dom.style.borderStyle = 'solid';
1058
+ // dom.style.height = `${buttonStyle.cornerRadius * 2}px`;
1059
+ dom.style.height = `30px`;
1060
+ dom.style.width = `calc(100% - ${buttonStyle.cornerRadius * 2}px)`;
1061
+ dom.style.maxWidth = `106px`;
1062
+ };
1063
+
1064
+ function startSpinner(args) {
999
1065
  const loadingLottie = Storage.getItem(exports.STORAGE_KEY.LOADING_LOTTIE);
1066
+ const themeConfig = Storage.getItem('themeConfig');
1000
1067
  const body = document.querySelector('.authme-container');
1068
+ //Statement
1069
+ const statementContainer = document.createElement('div');
1070
+ statementContainer.classList.add('statement');
1071
+ uiThemeText(statementContainer, themeConfig.bodyThreeDarkMode);
1072
+ statementContainer.textContent = args.statement || '';
1001
1073
  if (loadingLottie) {
1002
1074
  const loadingSDKOuter = document.createElement('div');
1003
1075
  const loadingSDKContent = document.createElement('div');
@@ -1014,12 +1086,18 @@ function startSpinner(text, backgroundOpaque) {
1014
1086
  animationData: loadingLottie
1015
1087
  });
1016
1088
  body === null || body === void 0 ? void 0 : body.appendChild(loadingSDKOuter);
1017
- if (text) {
1089
+ if (args.text) {
1018
1090
  loadingSDKText.classList.add('authme-loading-sdk-text');
1019
- loadingSDKText.textContent = text;
1091
+ loadingSDKText.textContent = args.text;
1092
+ loadingSDKText.style.color = themeConfig.titleTwo.textColor;
1093
+ loadingSDKText.style.fontWeight = themeConfig.titleTwo.textWeight;
1094
+ loadingSDKText.style.fontSize = `${themeConfig.titleTwo.fontSize}px`;
1020
1095
  loadingSDKContent.appendChild(loadingSDKText);
1021
1096
  }
1022
- if (backgroundOpaque) {
1097
+ if (args.backgroundOpaque) {
1098
+ loadingSDKOuter.classList.add('loading-outer--opaque');
1099
+ }
1100
+ if (args.backgroundOpaque) {
1023
1101
  loadingSDKOuter.classList.add('authme-loading-sdk-outer--opaque');
1024
1102
  }
1025
1103
  return;
@@ -1030,14 +1108,21 @@ function startSpinner(text, backgroundOpaque) {
1030
1108
  spinnerOuter.appendChild(spinner);
1031
1109
  spinnerOuter.className = 'loading-outer';
1032
1110
  spinner.className = 'loading';
1033
- if (text) {
1111
+ spinner.style.borderRightColor = themeConfig.loadingViewContentColor;
1112
+ spinner.style.borderBottomColor = themeConfig.loadingViewContentColor;
1113
+ spinner.style.borderLeftColor = themeConfig.loadingViewContentColor;
1114
+ if (args.text) {
1034
1115
  spinnerText.className = 'loading-text';
1035
- spinnerText.textContent = text;
1116
+ spinnerText.textContent = args.text;
1117
+ uiThemeText(spinnerText, themeConfig.titleTwo);
1036
1118
  spinnerOuter.appendChild(spinnerText);
1037
1119
  }
1038
- if (backgroundOpaque) {
1120
+ if (args.backgroundOpaque) {
1039
1121
  spinnerOuter.classList.add('loading-outer--opaque');
1040
1122
  }
1123
+ if (themeConfig.isStatementEnabled) {
1124
+ spinnerOuter.appendChild(statementContainer);
1125
+ }
1041
1126
  body === null || body === void 0 ? void 0 : body.appendChild(spinnerOuter);
1042
1127
  }
1043
1128
  function stopSpinner() {
@@ -2490,6 +2575,106 @@ function RGBToLottieColor(color) {
2490
2575
  return color.map(c => c / 255);
2491
2576
  }
2492
2577
 
2578
+ const uploadModal = arg => {
2579
+ const authmeContainer = document.querySelector('.authme-container');
2580
+ if (!authmeContainer) {
2581
+ console.error('uploadModal: authmeContainer not found');
2582
+ return;
2583
+ }
2584
+ const uiThemeConfig = Storage.getItem('themeConfig');
2585
+ function removeModal() {
2586
+ var _a;
2587
+ (_a = document.querySelector('.video-container__upload')) === null || _a === void 0 ? void 0 : _a.remove();
2588
+ }
2589
+ const domModal = document.createElement('div');
2590
+ const domIcon = document.createElement('div');
2591
+ const domTitle = document.createElement('div');
2592
+ const domMessage = document.createElement('div');
2593
+ const domStatement = document.createElement('div');
2594
+ const domFooterContainer = document.createElement('div');
2595
+ const domClose = document.createElement('div');
2596
+ const domRetry = document.createElement('div');
2597
+ domModal.classList.add('video-container__upload');
2598
+ domIcon.classList.add('video-container__upload-icon');
2599
+ domTitle.classList.add('video-container__upload-title');
2600
+ domMessage.classList.add('video-container__upload-message');
2601
+ domStatement.classList.add('video-container__upload-statement');
2602
+ domFooterContainer.classList.add('video-container__upload-footer-container');
2603
+ domClose.classList.add('video-container__upload-close');
2604
+ domRetry.classList.add('video-container__upload-retry');
2605
+ uiThemeText(domTitle, uiThemeConfig.titleTwo);
2606
+ uiThemeText(domMessage, uiThemeConfig.bodyOne);
2607
+ if (arg.type === 'success') {
2608
+ domIcon.innerHTML = `<svg width="49" height="48" viewBox="0 0 49 48" fill="none" xmlns="http://www.w3.org/2000/svg">
2609
+ <rect x="0.5" width="48" height="48" rx="24" fill="${uiThemeConfig.uploadCompleteView.backgroundColor}" fill-opacity="${uiThemeConfig.uploadCompleteView.backgroundOpacity}" />
2610
+ <g clip-path="url(#clip0_21855_2149)">
2611
+ <path d="M16.25 25.5L21.5 30.75L33.5 18.75" stroke="${uiThemeConfig.uploadCompleteView.contentColor}" stroke-opacity="${uiThemeConfig.uploadCompleteView.contentOpacity}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
2612
+ </g>
2613
+ <defs>
2614
+ <clipPath id="clip0_21855_2149">
2615
+ <rect width="24" height="24" fill="white" transform="translate(12.5 12)"/>
2616
+ </clipPath>
2617
+ </defs>
2618
+ </svg>`;
2619
+ }
2620
+ if (arg.type === 'error') {
2621
+ domIcon.innerHTML = `<svg width="49" height="48" viewBox="0 0 49 48" fill="none" xmlns="http://www.w3.org/2000/svg">
2622
+ <rect x="0.5" width="48" height="48" rx="24" fill="${uiThemeConfig.uploadIncompleteView.backgroundColor}" fill-opacity="${uiThemeConfig.uploadIncompleteView.backgroundOpacity}"/>
2623
+ <g clip-path="url(#clip0_21855_2690)">
2624
+ <path d="M31.25 17.25L17.75 30.75" stroke="${uiThemeConfig.uploadIncompleteView.contentColor}" stroke-opacity="${uiThemeConfig.uploadIncompleteView.contentOpacity}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
2625
+ <path d="M31.25 30.75L17.75 17.25" stroke="${uiThemeConfig.uploadIncompleteView.contentColor}" stroke-opacity="${uiThemeConfig.uploadIncompleteView.contentOpacity}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
2626
+ </g>
2627
+ <defs>
2628
+ <clipPath id="clip0_21855_2690">
2629
+ <rect width="24" height="24" fill="white" transform="translate(12.5 12)"/>
2630
+ </clipPath>
2631
+ </defs>
2632
+ </svg>
2633
+ `;
2634
+ }
2635
+ if (arg.type === 'success') {
2636
+ domTitle.innerText = arg.titleSuccess || '';
2637
+ domMessage.innerText = arg.messageSuccess || '';
2638
+ }
2639
+ if (arg.type === 'error') {
2640
+ domTitle.innerText = arg.titleError || '';
2641
+ domMessage.innerText = arg.messageError || '';
2642
+ }
2643
+ domModal.appendChild(domIcon);
2644
+ domModal.appendChild(domTitle);
2645
+ domModal.appendChild(domMessage);
2646
+ if (uiThemeConfig.isStatementEnabled && arg.statement && arg.type === 'success') {
2647
+ uiThemeText(domStatement, uiThemeConfig.bodyThree);
2648
+ domStatement.innerText = arg.statement;
2649
+ domModal.appendChild(domStatement);
2650
+ }
2651
+ if (arg.type === 'error' && arg.retryText && arg.closeText) {
2652
+ uiThemeButton(domRetry, uiThemeConfig.majorButton);
2653
+ domRetry.innerText = arg.retryText;
2654
+ domRetry.addEventListener('click', () => __awaiter(void 0, void 0, void 0, function* () {
2655
+ if (arg.onRetry) {
2656
+ yield arg.onRetry();
2657
+ }
2658
+ removeModal();
2659
+ }));
2660
+ uiThemeButton(domClose, uiThemeConfig.minorButton);
2661
+ domClose.innerText = arg.closeText;
2662
+ domClose.addEventListener('click', () => __awaiter(void 0, void 0, void 0, function* () {
2663
+ if (arg.onClose) {
2664
+ yield arg.onClose();
2665
+ }
2666
+ removeModal();
2667
+ }));
2668
+ domFooterContainer.appendChild(domRetry);
2669
+ domFooterContainer.appendChild(domClose);
2670
+ domModal.appendChild(domFooterContainer);
2671
+ }
2672
+ authmeContainer.appendChild(domModal);
2673
+ return {
2674
+ removeModal
2675
+ };
2676
+ };
2677
+
2493
2678
  const QUEUE_LENGTH = 10;
2494
2679
  const requstQueue = [];
2495
2680
  function pushRequest(request) {
@@ -2517,9 +2702,288 @@ window.ononline = () => {
2517
2702
  });
2518
2703
  };
2519
2704
 
2705
+ const themeConfigDefault = {
2706
+ isFraudAnimationLoadingPageEnabled: true,
2707
+ isStatementEnabled: true,
2708
+ isLivenessIntroPageEnabled: true,
2709
+ resultPageCountdown: {
2710
+ // 結果頁倒數的參數們
2711
+ // 結果頁是否顯示倒數
2712
+ isEnabled: true,
2713
+ // 倒數敘述文字
2714
+ textColor: '#212121',
2715
+ textWeight: 'regular',
2716
+ fontSize: 14,
2717
+ // 倒數時間
2718
+ timeTextColor: '#FF3B30',
2719
+ timeTextWeight: 'regular',
2720
+ timeFontSize: 14
2721
+ },
2722
+ headerTitle: {
2723
+ // G.H.2
2724
+ // Header(畫面上方標題,如前導頁)的參數們
2725
+ textColor: '#212121',
2726
+ textWeight: 'medium',
2727
+ fontSize: 18
2728
+ },
2729
+ nonEkycCloseButton: {
2730
+ // G.A.3
2731
+ // 非ekyc流程中的X
2732
+ contentColor: '#424242',
2733
+ contentOpacity: 1
2734
+ },
2735
+ backButton: {
2736
+ // iOS only
2737
+ // ekyc流程中的返回
2738
+ contentColor: '#424242',
2739
+ contentOpacity: 1
2740
+ },
2741
+ ekycCloseButton: {
2742
+ // G.A.1、G.A.2
2743
+ // ekyc流程中的X
2744
+ contentColor: '#ffffff',
2745
+ contentOpacity: 1,
2746
+ backgroundColor: '#000000',
2747
+ backgroundOpacity: 0.2
2748
+ },
2749
+ majorButton: {
2750
+ // G.B.1、G.B.2、G.B.3、G.B.4
2751
+ // 主要button
2752
+ cornerRadius: 24,
2753
+ backgroundColor: '#00c1b6',
2754
+ backgroundOpacity: 1,
2755
+ borderColor: '#000000',
2756
+ borderOpacity: 1,
2757
+ borderWidth: 0,
2758
+ textColor: '#ffffff',
2759
+ textWeight: 'medium',
2760
+ fontSize: 16,
2761
+ disabledBackgroundColor: '#E0E0E0',
2762
+ disabledBorderColor: '#E0E0E0',
2763
+ disabledTextColor: '#FFFFFF'
2764
+ },
2765
+ minorButton: {
2766
+ // G.B.5、G.B.6、G.B.7、G.B.8
2767
+ // 次要button
2768
+ cornerRadius: 24,
2769
+ backgroundColor: '#ffffff',
2770
+ backgroundOpacity: 1,
2771
+ borderColor: '#00c1b6',
2772
+ borderOpacity: 1,
2773
+ borderWidth: 1,
2774
+ textColor: '#00c1b6',
2775
+ textWeight: 'medium',
2776
+ fontSize: 16,
2777
+ disabledBackgroundColor: '#FFFFFF',
2778
+ disabledBorderColor: '#BDBDBD',
2779
+ disabledTextColor: '#BDBDBD'
2780
+ },
2781
+ smallermMajorButton: {
2782
+ // 主要button(小)
2783
+ // 用於dialog/alert的按鈕
2784
+ cornerRadius: 15,
2785
+ backgroundColor: '#00c1b6',
2786
+ backgroundOpacity: 1,
2787
+ borderColor: '#000000',
2788
+ borderOpacity: 1,
2789
+ borderWidth: 0,
2790
+ textColor: '#ffffff',
2791
+ textWeight: 'medium',
2792
+ fontSize: 14,
2793
+ disabledBackgroundColor: '#E0E0E0',
2794
+ disabledBorderColor: '#E0E0E0',
2795
+ disabledTextColor: '#FFFFFF' //預設值: #FFFFFF
2796
+ },
2797
+
2798
+ // 次要button(小)
2799
+ smallerMinorButton: {
2800
+ cornerRadius: 15,
2801
+ backgroundColor: '#ffffff',
2802
+ backgroundOpacity: 1,
2803
+ borderColor: '#00c1b6',
2804
+ borderOpacity: 1,
2805
+ borderWidth: 1,
2806
+ textColor: '#00c1b6',
2807
+ textWeight: 'medium',
2808
+ fontSize: 14,
2809
+ disabledBackgroundColor: '#FFFFFF',
2810
+ disabledBorderColor: '#BDBDBD',
2811
+ disabledTextColor: '#BDBDBD' //預設值: #BDBDBD
2812
+ },
2813
+
2814
+ hint: {
2815
+ // G.HT.2
2816
+ // Hint 提示框(OCR、防偽、活體下面的提示的訊息)
2817
+ cornerRadius: 8,
2818
+ backgroundColor: '#000000',
2819
+ opacity: 0.4,
2820
+ textColor: '#ffffff',
2821
+ textWeight: 'regular',
2822
+ fontSize: 14
2823
+ },
2824
+ fraudIntroStepTitle: {
2825
+ // G.L.1、G.L.2
2826
+ // Fraud引導頁Step title(step1, step2 那塊)
2827
+ cornerRadius: 15,
2828
+ backgroundColor: '#25608A',
2829
+ backgroundOpacity: 1,
2830
+ textColor: '#ffffff',
2831
+ textWeight: 'medium',
2832
+ fontSize: 14
2833
+ },
2834
+ uploadCompleteView: {
2835
+ // G.S.1、G.S.2
2836
+ // 上傳完成的勾勾圖
2837
+ contentColor: '#ffffff',
2838
+ contentOpacity: 1,
2839
+ backgroundColor: '#00c1b6',
2840
+ backgroundOpacity: 1
2841
+ },
2842
+ uploadIncompleteView: {
2843
+ // G.S.3、G.S.4
2844
+ // 上傳失敗的X圖
2845
+ contentColor: '#ffffff',
2846
+ contentOpacity: 1,
2847
+ backgroundColor: '#FF3B30',
2848
+ backgroundOpacity: 1
2849
+ },
2850
+ loadingViewContentColor: '#00c1b6',
2851
+ scanFrame: {
2852
+ // G.SC.1、G.SC.2
2853
+ // 框線圖相關(外框)
2854
+ isEnabled: true,
2855
+ style: 'cornered',
2856
+ width: 2,
2857
+ opacity: 1,
2858
+ undetectedColor: '#ffffff',
2859
+ detectedColor: '#7CFFF9'
2860
+ },
2861
+ scanLine: {
2862
+ // 框線圖相關(掃描線)
2863
+ isEnabled: true,
2864
+ color: '#00c1b6'
2865
+ },
2866
+ scanHint: {
2867
+ // G.SC.4
2868
+ // 框線圖相關(掃描線)
2869
+ isEnabled: true,
2870
+ style: 'image',
2871
+ color: '#ffffff',
2872
+ opacity: 0.7,
2873
+ textWeight: 'medium',
2874
+ fontSize: 60
2875
+ },
2876
+ fraudScanHint: {
2877
+ // D.F.SC.1
2878
+ // 防偽框線圖相關參數(圖)
2879
+ isEnabled: true,
2880
+ style: 'animation',
2881
+ color: '#000000',
2882
+ opacity: 0.7
2883
+ },
2884
+ popupView: {
2885
+ // popup
2886
+ width: 0.75,
2887
+ cornerRadius: 12,
2888
+ backgroundColor: '#ffffff'
2889
+ },
2890
+ livenessErrorScanFrame: {
2891
+ // G.LIVE.2
2892
+ // 活體偵測錯誤
2893
+ color: '#FF3B30',
2894
+ opacity: 1,
2895
+ borderWidth: 6
2896
+ },
2897
+ livenessSuccessScanFrame: {
2898
+ // G.LIVE.1
2899
+ // 活體偵測成功
2900
+ color: '#00C1B6',
2901
+ opacity: 1,
2902
+ borderWidth: 6
2903
+ },
2904
+ isFraudScanIntroPageEnabled: true,
2905
+ pageDotColor: '#00C1B6',
2906
+ titleOne: {
2907
+ // G.T.1
2908
+ // figma 上的 title 1
2909
+ // OCR 確認頁的"確認xx正面、反面"、nfc 護照的"掃描護照晶片(Android 要調整 nfc sdk,比較麻煩)"[後面做]
2910
+ // 、"厚度檢測"、人臉辨識導引頁的"即將進行人臉拍攝"
2911
+ textColor: '#212121',
2912
+ textWeight: 'medium',
2913
+ fontSize: 20
2914
+ },
2915
+ titleTwo: {
2916
+ // G.T.2
2917
+ // Figma標示title 2
2918
+ // loading 圖的"上傳中"、"上傳失敗"、"上傳完成,等待審核中"、
2919
+ // timeout或其他錯誤 alert 的內容"請聯繫客服以協助處理此問題"
2920
+ textColor: '#212121',
2921
+ textWeight: 'medium',
2922
+ fontSize: 18
2923
+ },
2924
+ titleThree: {
2925
+ // G.T.3
2926
+ // Figma標示title 3
2927
+ // 活體的標題"將人臉放入邊框中"、nfc 護照的"尋找生物特徵的圖示(Android 要調整 nfc sdk,比較麻煩)"
2928
+ // 結果頁的"請在xx:xx內完成確認"
2929
+ textColor: '#212121',
2930
+ textWeight: 'medium',
2931
+ fontSize: 16
2932
+ },
2933
+ bodyOne: {
2934
+ // G.T.4
2935
+ // figma 上的 body 1
2936
+ // "完成流程"、"請檢查網路連線狀況並重新嘗試"、"請根據下方教學步驟依序完成NFC操作"、"請將卡面傾斜45度角放入畫面框線進行拍攝"
2937
+ // "將臉部置於方框中,依照畫面指示進行操作"
2938
+ textColor: '#212121',
2939
+ textWeight: 'regular',
2940
+ fontSize: 16
2941
+ },
2942
+ bodyTwo: {
2943
+ // G.T.5
2944
+ // Figma標示body 2或body2
2945
+ textColor: '#212121',
2946
+ textWeight: 'regular',
2947
+ fontSize: 14
2948
+ },
2949
+ bodyThree: {
2950
+ // G.T.6
2951
+ // Figma標示body 3或body3
2952
+ textColor: '#212121',
2953
+ textWeight: 'regular',
2954
+ fontSize: 12
2955
+ },
2956
+ titleOneDarkMode: {
2957
+ // G.T.D.1
2958
+ // Figma標示dark_title 1
2959
+ textColor: '#ffffff',
2960
+ textWeight: 'medium',
2961
+ fontSize: 20
2962
+ },
2963
+ titleTwoDarkMode: {
2964
+ // G.T.D.2
2965
+ // Figma標示dark_title 2
2966
+ textColor: '#ffffff',
2967
+ textWeight: 'medium',
2968
+ fontSize: 18
2969
+ },
2970
+ bodyTwoDarkMode: {
2971
+ textColor: '#ffffff',
2972
+ textWeight: 'regular',
2973
+ fontSize: 14
2974
+ },
2975
+ bodyThreeDarkMode: {
2976
+ // G.T.D.4
2977
+ // Figma標示dark_body 3
2978
+ textColor: '#E0E0E0',
2979
+ textWeight: 'regular',
2980
+ fontSize: 12
2981
+ }
2982
+ };
2983
+
2520
2984
  var name = "authme/sdk";
2521
- var version$1 = "2.8.1";
2522
- var date = "2025-02-04T09:12:52+0000";
2985
+ var version$1 = "2.8.3";
2986
+ var date = "2025-03-05T06:16:55+0000";
2523
2987
  var packageInfo = {
2524
2988
  name: name,
2525
2989
  version: version$1,
@@ -2550,6 +3014,7 @@ exports.dataURItoBlob = dataURItoBlob;
2550
3014
  exports.debugLog = debugLog;
2551
3015
  exports.debugTools = debugTools;
2552
3016
  exports.decodeToken = decodeToken;
3017
+ exports.fontWeight = fontWeight;
2553
3018
  exports.getCanvasSize = getCanvasSize;
2554
3019
  exports.getCssVariable = getCssVariable;
2555
3020
  exports.getDeviceInfo = getDeviceInfo;
@@ -2576,6 +3041,12 @@ exports.startSpinner = startSpinner;
2576
3041
  exports.stopLoadingSDK = stopLoadingSDK;
2577
3042
  exports.stopSpinner = stopSpinner;
2578
3043
  exports.switchCamera = switchCamera;
3044
+ exports.themeConfigDefault = themeConfigDefault;
3045
+ exports.uiThemeButton = uiThemeButton;
3046
+ exports.uiThemeHint = uiThemeHint;
3047
+ exports.uiThemeSmallButton = uiThemeSmallButton;
3048
+ exports.uiThemeText = uiThemeText;
3049
+ exports.uploadModal = uploadModal;
2579
3050
  exports.useState = useState;
2580
3051
  exports.verificationErrorMessages = verificationErrorMessages;
2581
3052
  exports.version = version;
package/index.js CHANGED
@@ -21,9 +21,9 @@ import 'core-js/modules/es.array.includes.js';
21
21
  import 'core-js/modules/es.string.includes.js';
22
22
  import { saveAs } from 'file-saver';
23
23
  import JSZip from 'jszip';
24
+ import 'core-js/modules/es.parse-int.js';
24
25
  import Lottie from 'lottie-web';
25
26
  import 'core-js/modules/es.array.sort.js';
26
- import 'core-js/modules/es.parse-int.js';
27
27
  import 'core-js/modules/es.string.trim.js';
28
28
  import 'core-js/modules/es.string.starts-with.js';
29
29
  import 'core-js/modules/es.symbol.description.js';
@@ -985,9 +985,81 @@ function cropByRatio(width, height, ratio) {
985
985
  };
986
986
  }
987
987
 
988
- function startSpinner(text, backgroundOpaque) {
988
+ const fontWeight = {
989
+ regular: '400',
990
+ medium: '500',
991
+ bold: '700'
992
+ };
993
+ const hexToRgba = (hex, alpha = 1) => {
994
+ // 移除 # 符號(如果有的話)
995
+ hex = hex.replace(/^#/, '');
996
+ // 解析短格式 (e.g., #RGB -> #RRGGBB)
997
+ if (hex.length === 3) {
998
+ hex = hex.split('').map(x => x + x).join('');
999
+ }
1000
+ // 確保是有效的 HEX 格式
1001
+ if (hex.length !== 6) {
1002
+ throw new Error('Invalid HEX color.');
1003
+ }
1004
+ // 轉換 HEX 到 RGB
1005
+ const r = parseInt(hex.substring(0, 2), 16);
1006
+ const g = parseInt(hex.substring(2, 4), 16);
1007
+ const b = parseInt(hex.substring(4, 6), 16);
1008
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
1009
+ };
1010
+ const uiThemeText = (dom, textStyle) => {
1011
+ dom.style.color = textStyle.textColor;
1012
+ dom.style.fontWeight = fontWeight[textStyle.textWeight];
1013
+ dom.style.fontSize = `${textStyle.fontSize}px`;
1014
+ };
1015
+ const uiThemeHint = (dom, hintStyle) => {
1016
+ dom.style.borderRadius = `${hintStyle.cornerRadius}px`;
1017
+ dom.style.backgroundColor = hintStyle.backgroundColor;
1018
+ dom.style.opacity = hintStyle.opacity;
1019
+ dom.style.color = hintStyle.textColor;
1020
+ dom.style.fontWeight = fontWeight[hintStyle.textWeight];
1021
+ dom.style.fontSize = `${hintStyle.fontSize}px`;
1022
+ };
1023
+ const uiThemeButton = (dom, buttonStyle) => {
1024
+ dom.style.borderRadius = `${buttonStyle.cornerRadius}px`;
1025
+ dom.style.backgroundColor = buttonStyle.backgroundColor;
1026
+ dom.style.opacity = buttonStyle.backgroundOpacity;
1027
+ dom.style.color = buttonStyle.textColor;
1028
+ dom.style.borderColor = hexToRgba(buttonStyle.borderColor, buttonStyle.borderOpacity);
1029
+ dom.style.borderWidth = `${buttonStyle.borderWidth}px`;
1030
+ dom.style.fontWeight = fontWeight[buttonStyle.textWeight];
1031
+ dom.style.fontSize = `${buttonStyle.fontSize}px`;
1032
+ dom.style.borderStyle = 'solid';
1033
+ // dom.style.height = `${buttonStyle.cornerRadius * 2}px`;
1034
+ dom.style.height = `48px`;
1035
+ dom.style.width = `calc(100% - ${buttonStyle.cornerRadius * 2}px)`;
1036
+ dom.style.maxWidth = `327px`;
1037
+ };
1038
+ const uiThemeSmallButton = (dom, buttonStyle) => {
1039
+ dom.style.borderRadius = `${buttonStyle.cornerRadius}px`;
1040
+ dom.style.backgroundColor = buttonStyle.backgroundColor;
1041
+ dom.style.opacity = buttonStyle.backgroundOpacity;
1042
+ dom.style.color = buttonStyle.textColor;
1043
+ dom.style.borderColor = hexToRgba(buttonStyle.borderColor, buttonStyle.borderOpacity);
1044
+ dom.style.borderWidth = `${buttonStyle.borderWidth}px`;
1045
+ dom.style.fontWeight = fontWeight[buttonStyle.textWeight];
1046
+ dom.style.fontSize = `${buttonStyle.fontSize}px`;
1047
+ dom.style.borderStyle = 'solid';
1048
+ // dom.style.height = `${buttonStyle.cornerRadius * 2}px`;
1049
+ dom.style.height = `30px`;
1050
+ dom.style.width = `calc(100% - ${buttonStyle.cornerRadius * 2}px)`;
1051
+ dom.style.maxWidth = `106px`;
1052
+ };
1053
+
1054
+ function startSpinner(args) {
989
1055
  const loadingLottie = Storage.getItem(STORAGE_KEY.LOADING_LOTTIE);
1056
+ const themeConfig = Storage.getItem('themeConfig');
990
1057
  const body = document.querySelector('.authme-container');
1058
+ //Statement
1059
+ const statementContainer = document.createElement('div');
1060
+ statementContainer.classList.add('statement');
1061
+ uiThemeText(statementContainer, themeConfig.bodyThreeDarkMode);
1062
+ statementContainer.textContent = args.statement || '';
991
1063
  if (loadingLottie) {
992
1064
  const loadingSDKOuter = document.createElement('div');
993
1065
  const loadingSDKContent = document.createElement('div');
@@ -1004,12 +1076,18 @@ function startSpinner(text, backgroundOpaque) {
1004
1076
  animationData: loadingLottie
1005
1077
  });
1006
1078
  body === null || body === void 0 ? void 0 : body.appendChild(loadingSDKOuter);
1007
- if (text) {
1079
+ if (args.text) {
1008
1080
  loadingSDKText.classList.add('authme-loading-sdk-text');
1009
- loadingSDKText.textContent = text;
1081
+ loadingSDKText.textContent = args.text;
1082
+ loadingSDKText.style.color = themeConfig.titleTwo.textColor;
1083
+ loadingSDKText.style.fontWeight = themeConfig.titleTwo.textWeight;
1084
+ loadingSDKText.style.fontSize = `${themeConfig.titleTwo.fontSize}px`;
1010
1085
  loadingSDKContent.appendChild(loadingSDKText);
1011
1086
  }
1012
- if (backgroundOpaque) {
1087
+ if (args.backgroundOpaque) {
1088
+ loadingSDKOuter.classList.add('loading-outer--opaque');
1089
+ }
1090
+ if (args.backgroundOpaque) {
1013
1091
  loadingSDKOuter.classList.add('authme-loading-sdk-outer--opaque');
1014
1092
  }
1015
1093
  return;
@@ -1020,14 +1098,21 @@ function startSpinner(text, backgroundOpaque) {
1020
1098
  spinnerOuter.appendChild(spinner);
1021
1099
  spinnerOuter.className = 'loading-outer';
1022
1100
  spinner.className = 'loading';
1023
- if (text) {
1101
+ spinner.style.borderRightColor = themeConfig.loadingViewContentColor;
1102
+ spinner.style.borderBottomColor = themeConfig.loadingViewContentColor;
1103
+ spinner.style.borderLeftColor = themeConfig.loadingViewContentColor;
1104
+ if (args.text) {
1024
1105
  spinnerText.className = 'loading-text';
1025
- spinnerText.textContent = text;
1106
+ spinnerText.textContent = args.text;
1107
+ uiThemeText(spinnerText, themeConfig.titleTwo);
1026
1108
  spinnerOuter.appendChild(spinnerText);
1027
1109
  }
1028
- if (backgroundOpaque) {
1110
+ if (args.backgroundOpaque) {
1029
1111
  spinnerOuter.classList.add('loading-outer--opaque');
1030
1112
  }
1113
+ if (themeConfig.isStatementEnabled) {
1114
+ spinnerOuter.appendChild(statementContainer);
1115
+ }
1031
1116
  body === null || body === void 0 ? void 0 : body.appendChild(spinnerOuter);
1032
1117
  }
1033
1118
  function stopSpinner() {
@@ -2480,6 +2565,106 @@ function RGBToLottieColor(color) {
2480
2565
  return color.map(c => c / 255);
2481
2566
  }
2482
2567
 
2568
+ const uploadModal = arg => {
2569
+ const authmeContainer = document.querySelector('.authme-container');
2570
+ if (!authmeContainer) {
2571
+ console.error('uploadModal: authmeContainer not found');
2572
+ return;
2573
+ }
2574
+ const uiThemeConfig = Storage.getItem('themeConfig');
2575
+ function removeModal() {
2576
+ var _a;
2577
+ (_a = document.querySelector('.video-container__upload')) === null || _a === void 0 ? void 0 : _a.remove();
2578
+ }
2579
+ const domModal = document.createElement('div');
2580
+ const domIcon = document.createElement('div');
2581
+ const domTitle = document.createElement('div');
2582
+ const domMessage = document.createElement('div');
2583
+ const domStatement = document.createElement('div');
2584
+ const domFooterContainer = document.createElement('div');
2585
+ const domClose = document.createElement('div');
2586
+ const domRetry = document.createElement('div');
2587
+ domModal.classList.add('video-container__upload');
2588
+ domIcon.classList.add('video-container__upload-icon');
2589
+ domTitle.classList.add('video-container__upload-title');
2590
+ domMessage.classList.add('video-container__upload-message');
2591
+ domStatement.classList.add('video-container__upload-statement');
2592
+ domFooterContainer.classList.add('video-container__upload-footer-container');
2593
+ domClose.classList.add('video-container__upload-close');
2594
+ domRetry.classList.add('video-container__upload-retry');
2595
+ uiThemeText(domTitle, uiThemeConfig.titleTwo);
2596
+ uiThemeText(domMessage, uiThemeConfig.bodyOne);
2597
+ if (arg.type === 'success') {
2598
+ domIcon.innerHTML = `<svg width="49" height="48" viewBox="0 0 49 48" fill="none" xmlns="http://www.w3.org/2000/svg">
2599
+ <rect x="0.5" width="48" height="48" rx="24" fill="${uiThemeConfig.uploadCompleteView.backgroundColor}" fill-opacity="${uiThemeConfig.uploadCompleteView.backgroundOpacity}" />
2600
+ <g clip-path="url(#clip0_21855_2149)">
2601
+ <path d="M16.25 25.5L21.5 30.75L33.5 18.75" stroke="${uiThemeConfig.uploadCompleteView.contentColor}" stroke-opacity="${uiThemeConfig.uploadCompleteView.contentOpacity}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
2602
+ </g>
2603
+ <defs>
2604
+ <clipPath id="clip0_21855_2149">
2605
+ <rect width="24" height="24" fill="white" transform="translate(12.5 12)"/>
2606
+ </clipPath>
2607
+ </defs>
2608
+ </svg>`;
2609
+ }
2610
+ if (arg.type === 'error') {
2611
+ domIcon.innerHTML = `<svg width="49" height="48" viewBox="0 0 49 48" fill="none" xmlns="http://www.w3.org/2000/svg">
2612
+ <rect x="0.5" width="48" height="48" rx="24" fill="${uiThemeConfig.uploadIncompleteView.backgroundColor}" fill-opacity="${uiThemeConfig.uploadIncompleteView.backgroundOpacity}"/>
2613
+ <g clip-path="url(#clip0_21855_2690)">
2614
+ <path d="M31.25 17.25L17.75 30.75" stroke="${uiThemeConfig.uploadIncompleteView.contentColor}" stroke-opacity="${uiThemeConfig.uploadIncompleteView.contentOpacity}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
2615
+ <path d="M31.25 30.75L17.75 17.25" stroke="${uiThemeConfig.uploadIncompleteView.contentColor}" stroke-opacity="${uiThemeConfig.uploadIncompleteView.contentOpacity}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
2616
+ </g>
2617
+ <defs>
2618
+ <clipPath id="clip0_21855_2690">
2619
+ <rect width="24" height="24" fill="white" transform="translate(12.5 12)"/>
2620
+ </clipPath>
2621
+ </defs>
2622
+ </svg>
2623
+ `;
2624
+ }
2625
+ if (arg.type === 'success') {
2626
+ domTitle.innerText = arg.titleSuccess || '';
2627
+ domMessage.innerText = arg.messageSuccess || '';
2628
+ }
2629
+ if (arg.type === 'error') {
2630
+ domTitle.innerText = arg.titleError || '';
2631
+ domMessage.innerText = arg.messageError || '';
2632
+ }
2633
+ domModal.appendChild(domIcon);
2634
+ domModal.appendChild(domTitle);
2635
+ domModal.appendChild(domMessage);
2636
+ if (uiThemeConfig.isStatementEnabled && arg.statement && arg.type === 'success') {
2637
+ uiThemeText(domStatement, uiThemeConfig.bodyThree);
2638
+ domStatement.innerText = arg.statement;
2639
+ domModal.appendChild(domStatement);
2640
+ }
2641
+ if (arg.type === 'error' && arg.retryText && arg.closeText) {
2642
+ uiThemeButton(domRetry, uiThemeConfig.majorButton);
2643
+ domRetry.innerText = arg.retryText;
2644
+ domRetry.addEventListener('click', () => __awaiter(void 0, void 0, void 0, function* () {
2645
+ if (arg.onRetry) {
2646
+ yield arg.onRetry();
2647
+ }
2648
+ removeModal();
2649
+ }));
2650
+ uiThemeButton(domClose, uiThemeConfig.minorButton);
2651
+ domClose.innerText = arg.closeText;
2652
+ domClose.addEventListener('click', () => __awaiter(void 0, void 0, void 0, function* () {
2653
+ if (arg.onClose) {
2654
+ yield arg.onClose();
2655
+ }
2656
+ removeModal();
2657
+ }));
2658
+ domFooterContainer.appendChild(domRetry);
2659
+ domFooterContainer.appendChild(domClose);
2660
+ domModal.appendChild(domFooterContainer);
2661
+ }
2662
+ authmeContainer.appendChild(domModal);
2663
+ return {
2664
+ removeModal
2665
+ };
2666
+ };
2667
+
2483
2668
  const QUEUE_LENGTH = 10;
2484
2669
  const requstQueue = [];
2485
2670
  function pushRequest(request) {
@@ -2507,9 +2692,288 @@ window.ononline = () => {
2507
2692
  });
2508
2693
  };
2509
2694
 
2695
+ const themeConfigDefault = {
2696
+ isFraudAnimationLoadingPageEnabled: true,
2697
+ isStatementEnabled: true,
2698
+ isLivenessIntroPageEnabled: true,
2699
+ resultPageCountdown: {
2700
+ // 結果頁倒數的參數們
2701
+ // 結果頁是否顯示倒數
2702
+ isEnabled: true,
2703
+ // 倒數敘述文字
2704
+ textColor: '#212121',
2705
+ textWeight: 'regular',
2706
+ fontSize: 14,
2707
+ // 倒數時間
2708
+ timeTextColor: '#FF3B30',
2709
+ timeTextWeight: 'regular',
2710
+ timeFontSize: 14
2711
+ },
2712
+ headerTitle: {
2713
+ // G.H.2
2714
+ // Header(畫面上方標題,如前導頁)的參數們
2715
+ textColor: '#212121',
2716
+ textWeight: 'medium',
2717
+ fontSize: 18
2718
+ },
2719
+ nonEkycCloseButton: {
2720
+ // G.A.3
2721
+ // 非ekyc流程中的X
2722
+ contentColor: '#424242',
2723
+ contentOpacity: 1
2724
+ },
2725
+ backButton: {
2726
+ // iOS only
2727
+ // ekyc流程中的返回
2728
+ contentColor: '#424242',
2729
+ contentOpacity: 1
2730
+ },
2731
+ ekycCloseButton: {
2732
+ // G.A.1、G.A.2
2733
+ // ekyc流程中的X
2734
+ contentColor: '#ffffff',
2735
+ contentOpacity: 1,
2736
+ backgroundColor: '#000000',
2737
+ backgroundOpacity: 0.2
2738
+ },
2739
+ majorButton: {
2740
+ // G.B.1、G.B.2、G.B.3、G.B.4
2741
+ // 主要button
2742
+ cornerRadius: 24,
2743
+ backgroundColor: '#00c1b6',
2744
+ backgroundOpacity: 1,
2745
+ borderColor: '#000000',
2746
+ borderOpacity: 1,
2747
+ borderWidth: 0,
2748
+ textColor: '#ffffff',
2749
+ textWeight: 'medium',
2750
+ fontSize: 16,
2751
+ disabledBackgroundColor: '#E0E0E0',
2752
+ disabledBorderColor: '#E0E0E0',
2753
+ disabledTextColor: '#FFFFFF'
2754
+ },
2755
+ minorButton: {
2756
+ // G.B.5、G.B.6、G.B.7、G.B.8
2757
+ // 次要button
2758
+ cornerRadius: 24,
2759
+ backgroundColor: '#ffffff',
2760
+ backgroundOpacity: 1,
2761
+ borderColor: '#00c1b6',
2762
+ borderOpacity: 1,
2763
+ borderWidth: 1,
2764
+ textColor: '#00c1b6',
2765
+ textWeight: 'medium',
2766
+ fontSize: 16,
2767
+ disabledBackgroundColor: '#FFFFFF',
2768
+ disabledBorderColor: '#BDBDBD',
2769
+ disabledTextColor: '#BDBDBD'
2770
+ },
2771
+ smallermMajorButton: {
2772
+ // 主要button(小)
2773
+ // 用於dialog/alert的按鈕
2774
+ cornerRadius: 15,
2775
+ backgroundColor: '#00c1b6',
2776
+ backgroundOpacity: 1,
2777
+ borderColor: '#000000',
2778
+ borderOpacity: 1,
2779
+ borderWidth: 0,
2780
+ textColor: '#ffffff',
2781
+ textWeight: 'medium',
2782
+ fontSize: 14,
2783
+ disabledBackgroundColor: '#E0E0E0',
2784
+ disabledBorderColor: '#E0E0E0',
2785
+ disabledTextColor: '#FFFFFF' //預設值: #FFFFFF
2786
+ },
2787
+
2788
+ // 次要button(小)
2789
+ smallerMinorButton: {
2790
+ cornerRadius: 15,
2791
+ backgroundColor: '#ffffff',
2792
+ backgroundOpacity: 1,
2793
+ borderColor: '#00c1b6',
2794
+ borderOpacity: 1,
2795
+ borderWidth: 1,
2796
+ textColor: '#00c1b6',
2797
+ textWeight: 'medium',
2798
+ fontSize: 14,
2799
+ disabledBackgroundColor: '#FFFFFF',
2800
+ disabledBorderColor: '#BDBDBD',
2801
+ disabledTextColor: '#BDBDBD' //預設值: #BDBDBD
2802
+ },
2803
+
2804
+ hint: {
2805
+ // G.HT.2
2806
+ // Hint 提示框(OCR、防偽、活體下面的提示的訊息)
2807
+ cornerRadius: 8,
2808
+ backgroundColor: '#000000',
2809
+ opacity: 0.4,
2810
+ textColor: '#ffffff',
2811
+ textWeight: 'regular',
2812
+ fontSize: 14
2813
+ },
2814
+ fraudIntroStepTitle: {
2815
+ // G.L.1、G.L.2
2816
+ // Fraud引導頁Step title(step1, step2 那塊)
2817
+ cornerRadius: 15,
2818
+ backgroundColor: '#25608A',
2819
+ backgroundOpacity: 1,
2820
+ textColor: '#ffffff',
2821
+ textWeight: 'medium',
2822
+ fontSize: 14
2823
+ },
2824
+ uploadCompleteView: {
2825
+ // G.S.1、G.S.2
2826
+ // 上傳完成的勾勾圖
2827
+ contentColor: '#ffffff',
2828
+ contentOpacity: 1,
2829
+ backgroundColor: '#00c1b6',
2830
+ backgroundOpacity: 1
2831
+ },
2832
+ uploadIncompleteView: {
2833
+ // G.S.3、G.S.4
2834
+ // 上傳失敗的X圖
2835
+ contentColor: '#ffffff',
2836
+ contentOpacity: 1,
2837
+ backgroundColor: '#FF3B30',
2838
+ backgroundOpacity: 1
2839
+ },
2840
+ loadingViewContentColor: '#00c1b6',
2841
+ scanFrame: {
2842
+ // G.SC.1、G.SC.2
2843
+ // 框線圖相關(外框)
2844
+ isEnabled: true,
2845
+ style: 'cornered',
2846
+ width: 2,
2847
+ opacity: 1,
2848
+ undetectedColor: '#ffffff',
2849
+ detectedColor: '#7CFFF9'
2850
+ },
2851
+ scanLine: {
2852
+ // 框線圖相關(掃描線)
2853
+ isEnabled: true,
2854
+ color: '#00c1b6'
2855
+ },
2856
+ scanHint: {
2857
+ // G.SC.4
2858
+ // 框線圖相關(掃描線)
2859
+ isEnabled: true,
2860
+ style: 'image',
2861
+ color: '#ffffff',
2862
+ opacity: 0.7,
2863
+ textWeight: 'medium',
2864
+ fontSize: 60
2865
+ },
2866
+ fraudScanHint: {
2867
+ // D.F.SC.1
2868
+ // 防偽框線圖相關參數(圖)
2869
+ isEnabled: true,
2870
+ style: 'animation',
2871
+ color: '#000000',
2872
+ opacity: 0.7
2873
+ },
2874
+ popupView: {
2875
+ // popup
2876
+ width: 0.75,
2877
+ cornerRadius: 12,
2878
+ backgroundColor: '#ffffff'
2879
+ },
2880
+ livenessErrorScanFrame: {
2881
+ // G.LIVE.2
2882
+ // 活體偵測錯誤
2883
+ color: '#FF3B30',
2884
+ opacity: 1,
2885
+ borderWidth: 6
2886
+ },
2887
+ livenessSuccessScanFrame: {
2888
+ // G.LIVE.1
2889
+ // 活體偵測成功
2890
+ color: '#00C1B6',
2891
+ opacity: 1,
2892
+ borderWidth: 6
2893
+ },
2894
+ isFraudScanIntroPageEnabled: true,
2895
+ pageDotColor: '#00C1B6',
2896
+ titleOne: {
2897
+ // G.T.1
2898
+ // figma 上的 title 1
2899
+ // OCR 確認頁的"確認xx正面、反面"、nfc 護照的"掃描護照晶片(Android 要調整 nfc sdk,比較麻煩)"[後面做]
2900
+ // 、"厚度檢測"、人臉辨識導引頁的"即將進行人臉拍攝"
2901
+ textColor: '#212121',
2902
+ textWeight: 'medium',
2903
+ fontSize: 20
2904
+ },
2905
+ titleTwo: {
2906
+ // G.T.2
2907
+ // Figma標示title 2
2908
+ // loading 圖的"上傳中"、"上傳失敗"、"上傳完成,等待審核中"、
2909
+ // timeout或其他錯誤 alert 的內容"請聯繫客服以協助處理此問題"
2910
+ textColor: '#212121',
2911
+ textWeight: 'medium',
2912
+ fontSize: 18
2913
+ },
2914
+ titleThree: {
2915
+ // G.T.3
2916
+ // Figma標示title 3
2917
+ // 活體的標題"將人臉放入邊框中"、nfc 護照的"尋找生物特徵的圖示(Android 要調整 nfc sdk,比較麻煩)"
2918
+ // 結果頁的"請在xx:xx內完成確認"
2919
+ textColor: '#212121',
2920
+ textWeight: 'medium',
2921
+ fontSize: 16
2922
+ },
2923
+ bodyOne: {
2924
+ // G.T.4
2925
+ // figma 上的 body 1
2926
+ // "完成流程"、"請檢查網路連線狀況並重新嘗試"、"請根據下方教學步驟依序完成NFC操作"、"請將卡面傾斜45度角放入畫面框線進行拍攝"
2927
+ // "將臉部置於方框中,依照畫面指示進行操作"
2928
+ textColor: '#212121',
2929
+ textWeight: 'regular',
2930
+ fontSize: 16
2931
+ },
2932
+ bodyTwo: {
2933
+ // G.T.5
2934
+ // Figma標示body 2或body2
2935
+ textColor: '#212121',
2936
+ textWeight: 'regular',
2937
+ fontSize: 14
2938
+ },
2939
+ bodyThree: {
2940
+ // G.T.6
2941
+ // Figma標示body 3或body3
2942
+ textColor: '#212121',
2943
+ textWeight: 'regular',
2944
+ fontSize: 12
2945
+ },
2946
+ titleOneDarkMode: {
2947
+ // G.T.D.1
2948
+ // Figma標示dark_title 1
2949
+ textColor: '#ffffff',
2950
+ textWeight: 'medium',
2951
+ fontSize: 20
2952
+ },
2953
+ titleTwoDarkMode: {
2954
+ // G.T.D.2
2955
+ // Figma標示dark_title 2
2956
+ textColor: '#ffffff',
2957
+ textWeight: 'medium',
2958
+ fontSize: 18
2959
+ },
2960
+ bodyTwoDarkMode: {
2961
+ textColor: '#ffffff',
2962
+ textWeight: 'regular',
2963
+ fontSize: 14
2964
+ },
2965
+ bodyThreeDarkMode: {
2966
+ // G.T.D.4
2967
+ // Figma標示dark_body 3
2968
+ textColor: '#E0E0E0',
2969
+ textWeight: 'regular',
2970
+ fontSize: 12
2971
+ }
2972
+ };
2973
+
2510
2974
  var name = "authme/sdk";
2511
- var version$1 = "2.8.1";
2512
- var date = "2025-02-04T09:12:52+0000";
2975
+ var version$1 = "2.8.3";
2976
+ var date = "2025-03-05T06:16:55+0000";
2513
2977
  var packageInfo = {
2514
2978
  name: name,
2515
2979
  version: version$1,
@@ -2522,4 +2986,4 @@ const version = packageInfo.version;
2522
2986
  (_a = (_b = window)[_c = Symbol.for('authme-sdk')]) !== null && _a !== void 0 ? _a : _b[_c] = {};
2523
2987
  window[Symbol.for('authme-sdk')][packageInfo.name] = version;
2524
2988
 
2525
- 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, hexToRGB, hideElement, hideErrorMessage, hidePopup, isIphone14proOrProMax, isMobile, isMobileOrTablet, osVersion, requestCamera, resize, retryPromiseWithCondition, showElement, showErrorMessage, showErrorMessageEventName, showPopup, splitResult, startLoadingSDK, startSpinner, stopLoadingSDK, stopSpinner, switchCamera, useState, verificationErrorMessages, version, videoConstraintsFactory, waitTime };
2989
+ 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, fontWeight, getCanvasSize, getCssVariable, getDeviceInfo, getImageData, getSystemInfo, hexToRGB, hideElement, hideErrorMessage, hidePopup, isIphone14proOrProMax, isMobile, isMobileOrTablet, osVersion, requestCamera, resize, retryPromiseWithCondition, showElement, showErrorMessage, showErrorMessageEventName, showPopup, splitResult, startLoadingSDK, startSpinner, stopLoadingSDK, stopSpinner, switchCamera, themeConfigDefault, uiThemeButton, uiThemeHint, uiThemeSmallButton, uiThemeText, uploadModal, useState, verificationErrorMessages, version, videoConstraintsFactory, waitTime };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authme/util",
3
- "version": "2.8.1",
3
+ "version": "2.8.3",
4
4
  "peerDependencies": {
5
5
  "core-js": "^3.6.0",
6
6
  "jwt-decode": "3.1.2",
package/src/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './lib/shared-util';
2
2
  export * from './ui';
3
3
  export * from './lib/background-request-process';
4
+ export * from './lib/const';
4
5
  export { version } from './lib/version';
@@ -0,0 +1 @@
1
+ export declare const themeConfigDefault: any;
package/src/ui/index.d.ts CHANGED
@@ -7,3 +7,5 @@ export * from './camera';
7
7
  export * from './element-style';
8
8
  export * from './sdk-loading';
9
9
  export * from './cssToJs';
10
+ export * from './uiThemeStyle';
11
+ export * from './uploadModal';
@@ -1,2 +1,6 @@
1
- export declare function startSpinner(text?: string, backgroundOpaque?: boolean): void;
1
+ export declare function startSpinner(args: {
2
+ text?: string;
3
+ backgroundOpaque?: boolean;
4
+ statement?: string;
5
+ }): void;
2
6
  export declare function stopSpinner(): void;
@@ -0,0 +1,5 @@
1
+ export declare const fontWeight: any;
2
+ export declare const uiThemeText: (dom: any, textStyle: any) => void;
3
+ export declare const uiThemeHint: (dom: any, hintStyle: any) => void;
4
+ export declare const uiThemeButton: (dom: any, buttonStyle: any) => void;
5
+ export declare const uiThemeSmallButton: (dom: any, buttonStyle: any) => void;
@@ -0,0 +1,14 @@
1
+ export declare const uploadModal: (arg: {
2
+ type: 'success' | 'error';
3
+ titleSuccess?: string;
4
+ messageSuccess?: string;
5
+ titleError?: string;
6
+ messageError?: string;
7
+ statement?: string;
8
+ retryText?: string;
9
+ closeText?: string;
10
+ onClose?: () => void;
11
+ onRetry?: () => void;
12
+ }) => {
13
+ removeModal: () => void;
14
+ };