UNPKG

otp-code-component

Version:

Google Authenticator 验证组件

2 lines 7.72 kB
import{r as t,c as o,h as i}from"./p-BCXA74EW.js";const e=".google-auth-container{display:flex;flex-direction:column;align-items:center;gap:24px;padding:20px;text-align:center;max-width:400px;margin:0 auto}.google-auth-container .auth-header{margin-bottom:24px}.google-auth-container .auth-header .lock-icon{width:48px;height:48px;margin:0 auto;color:#1677ff}.google-auth-container .auth-header .lock-icon svg{width:100%;height:100%}.google-auth-container .auth-header h2{color:#333;font-size:16px;font-weight:normal;margin:0}.google-auth-container .verification-section{display:flex;flex-direction:column;align-items:center;width:100%;gap:16px}.google-auth-container .verification-section p{margin-bottom:24px;color:#333;font-size:14px}.google-auth-container .verification-section .get-qr-button,.google-auth-container .verification-section .get-code-button{padding:8px 16px;background-color:#1677ff;color:white;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:all 0.3s}.google-auth-container .verification-section .get-qr-button:hover,.google-auth-container .verification-section .get-code-button:hover{background-color:#4096ff}.google-auth-container .verification-section .get-qr-button:disabled,.google-auth-container .verification-section .get-code-button:disabled{background-color:#d9d9d9;cursor:not-allowed}.google-auth-container .verification-section .qr-code{margin-top:24px}.google-auth-container .verification-section .qr-code img{max-width:200px;border:1px solid #d9d9d9;border-radius:4px;padding:8px}.google-auth-container .verification-section .code-input-group{display:flex;gap:8px;justify-content:center;margin-bottom:24px}.google-auth-container .verification-section .code-input-group input{width:40px;height:40px;text-align:center;border:1px solid #d9d9d9;border-radius:4px;font-size:18px;outline:none}.google-auth-container .verification-section .code-input-group input:focus{border-color:#1677ff;box-shadow:0 0 0 2px rgba(22, 119, 255, 0.2)}.google-auth-container .verification-section .code-input-group input:disabled{background-color:#f5f5f5;cursor:not-allowed}.google-auth-container .trust-device{display:flex;align-items:center;gap:8px;color:#666;font-size:14px;margin-top:16px}.google-auth-container .trust-device input[type=checkbox]{margin:0}.google-auth-container .mfa-help{color:#4285f4;text-decoration:none;font-size:14px;margin-top:16px}.google-auth-container .mfa-help:hover{text-decoration:underline}.google-auth-container .error-message{color:#ff4d4f;margin-top:16px;font-size:14px}.google-auth-container .success-message{color:#52c41a;margin-top:16px;font-size:14px}.qr-section{text-align:center}.qr-section h3{color:#333;font-size:16px;font-weight:normal;margin-bottom:20px}.qr-section img{max-width:200px;height:auto;margin-top:10px;border:1px solid #ddd;padding:10px;border-radius:4px}";const n=class{constructor(i){t(this,i);this.authSuccess=o(this,"authSuccess");this.authError=o(this,"authError");this.authBound=o(this,"authBound")}getQrcodeUrl;verifyCodeUrl;accessToken;type="google";phone;qrCodeUrl;status="initial";errorMessage="";codeInputs=["","","","","",""];showQRCode=false;countdown=0;countdownTimer;authSuccess;authError;authBound;inputRefs=[];componentWillLoad(){if(this.type==="phone"&&this.phone){this.fetchQRCode()}}disconnectedCallback(){if(this.countdownTimer){window.clearInterval(this.countdownTimer)}}startCountdown(){this.countdown=60;this.countdownTimer=window.setInterval((()=>{if(this.countdown>0){this.countdown--}else{window.clearInterval(this.countdownTimer)}}),1e3)}async fetchQRCode(){try{const t=await fetch(`${this.getQrcodeUrl}`,{method:"POST",headers:{Authorization:`Bearer ${this.accessToken}`,"Content-Type":"application/json"}});if(!t.ok)throw new Error(this.type==="google"?"获取二维码失败":"获取验证码失败");const o=await t.json();if(o.code!==200){throw new Error(o.message||(this.type==="google"?"获取二维码失败":"获取验证码失败"))}if(this.type==="google"){this.qrCodeUrl=o.data.qr_img;this.showQRCode=true;this.authBound.emit()}else{this.startCountdown()}}catch(t){this.errorMessage=t.message;this.authError.emit({code:400,message:t.message})}}async verifyCode(){const t=this.codeInputs.join("");if(!t||t.length!==6){this.errorMessage="请输入6位验证码";return}this.status="verifying";try{const o=await fetch(`${this.verifyCodeUrl}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify({code:t,...this.type==="phone"?{phone:this.phone}:{}})});if(!o.ok)throw new Error("验证失败");const i=await o.json();if(i.code!==200){throw new Error(i.message||"验证失败")}if(i.data.is_pass){this.status="success";this.authSuccess.emit({code:i.code,message:i.message,data:{is_pass:i.data.is_pass}})}else{this.status="error";this.errorMessage="验证失败";this.authError.emit({code:400,message:"验证失败"})}}catch(t){this.status="error";this.errorMessage=t.message;this.authError.emit({code:400,message:t.message})}}handleInput(t,o){const i=o.target;const e=i.value;if(!/^\d*$/.test(e)){i.value="";return}const n=e.slice(-1);i.value=n;this.codeInputs=[...this.codeInputs.slice(0,t),n,...this.codeInputs.slice(t+1)];if(n&&t<5){this.inputRefs[t+1]?.focus()}if(this.codeInputs.every((t=>t))&&this.codeInputs.join("").length===6){this.verifyCode()}}handleKeyDown(t,o){const i=["Backspace","Delete","ArrowLeft","ArrowRight","Tab","0","1","2","3","4","5","6","7","8","9"];if(!i.includes(o.key)){o.preventDefault();return}if(o.key==="Backspace"){if(!this.codeInputs[t]&&t>0){this.inputRefs[t-1]?.focus();this.codeInputs=[...this.codeInputs.slice(0,t-1),"",...this.codeInputs.slice(t)]}else{this.codeInputs=[...this.codeInputs.slice(0,t),"",...this.codeInputs.slice(t+1)]}}}handlePaste=t=>{t.preventDefault();const o=t.clipboardData.getData("text");const i=o.replace(/\D/g,"").slice(0,6).split("");this.codeInputs=[...i,...Array(6-i.length).fill("")];const e=i.length;if(e<6){this.inputRefs[e]?.focus()}if(i.length===6){this.verifyCode()}};render(){const t=t=>t?.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2");return i("div",{class:"google-auth-container"},i("div",{class:"auth-header"},i("div",{class:"lock-icon"},i("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},i("path",{d:"M12 1C8.676 1 6 3.676 6 7v2H4v14h16V9h-2V7c0-3.324-2.676-6-6-6zm0 2c2.276 0 4 1.724 4 4v2H8V7c0-2.276 1.724-4 4-4z"})))),i("div",{class:"verification-section"},this.type==="google"?i("p",null,"当前身份已开启登录保护,请输入Google Authenticator上的安全码"):i("p",null,"当前身份已开启登录保护,请输入发送至 ",t(this.phone)," 的验证码"),i("div",{class:"code-input-group"},Array(6).fill(null).map(((t,o)=>i("input",{key:o,type:"text",inputMode:"numeric",pattern:"[0-9]*",maxLength:1,value:this.codeInputs[o],onInput:t=>this.handleInput(o,t),onKeyDown:t=>this.handleKeyDown(o,t),onPaste:this.handlePaste,disabled:this.status==="verifying"||this.status==="success",ref:t=>this.inputRefs[o]=t})))),this.type==="google"&&!this.showQRCode&&i("button",{class:"get-qr-button",onClick:()=>this.fetchQRCode()},"获取二维码"),this.type==="phone"&&i("button",{class:"get-code-button",onClick:()=>this.fetchQRCode(),disabled:this.countdown>0},this.countdown>0?`重新获取(${this.countdown}s)`:"获取验证码"),this.type==="google"&&this.showQRCode&&this.qrCodeUrl&&i("div",{class:"qr-code"},i("img",{src:this.qrCodeUrl,alt:"Google Authenticator QR Code"}))),this.errorMessage&&i("div",{class:"error-message"},this.errorMessage),this.status==="success"&&i("div",{class:"success-message"},"验证成功!"))}};n.style=e;export{n as GoogleAuth}; //# sourceMappingURL=index.esm.js.map