sensitive-data-display
Version:
A Vue 3 component for displaying sensitive data with masking and toggle functionality
2 lines (1 loc) • 5.56 kB
JavaScript
(function(i,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue"),require("ant-design-vue"),require("@ant-design/icons-vue")):typeof define=="function"&&define.amd?define(["exports","vue","ant-design-vue","@ant-design/icons-vue"],n):(i=typeof globalThis<"u"?globalThis:i||self,n(i.SensitiveDataDisplay={},i.Vue,i.antd,i.antdIcons))})(this,function(i,n,S,p){"use strict";const A="",E={class:"sensitive-data-display"},b="SENSITIVE_CACHE_",k=n.defineComponent({__name:"SensitiveDataDisplay",props:{value:{},mode:{default:"server"},type:{default:"custom"},showStart:{default:3},showEnd:{default:4},maskChar:{default:"*"},defaultVisible:{type:Boolean,default:!1},fetchFullData:{},dataId:{},cacheExpiry:{default:10},cacheStorage:{default:"memory"}},emits:["toggleRequest"],setup(e,{expose:u,emit:r}){const t=e,l=r,s=n.ref(t.defaultVisible),o=n.ref(!1),d=n.ref(""),m=n.ref(0),C=n.ref(!1),f=()=>`${b}${t.dataId||"default"}`,y={setCache(a,c){try{const h=JSON.stringify(c);switch(t.cacheStorage){case"session":sessionStorage.setItem(a,h);break;case"local":localStorage.setItem(a,h);break;case"memory":default:d.value=c.data,m.value=c.timestamp;break}}catch(h){console.warn("Failed to set cache:",h)}},getCache(a){try{let c=null;switch(t.cacheStorage){case"session":c=sessionStorage.getItem(a);break;case"local":c=localStorage.getItem(a);break;case"memory":default:return d.value&&m.value?{data:d.value,timestamp:m.value,expiry:t.cacheExpiry*60*1e3}:null}if(c)return JSON.parse(c)}catch(c){console.warn("Failed to get cache:",c)}return null},clearCache(a){try{switch(t.cacheStorage){case"session":sessionStorage.removeItem(a);break;case"local":localStorage.removeItem(a);break;case"memory":default:d.value="",m.value=0;break}}catch(c){console.warn("Failed to clear cache:",c)}}},V=()=>{const a=f(),c=y.getCache(a);return c&&Date.now()-c.timestamp<c.expiry?c.data:(y.clearCache(a),null)},_=async()=>{if(!o.value){if(t.mode==="custom"){l("toggleRequest",!s,t.dataId);return}s.value?s.value=!1:await $()}},$=async()=>{if(!o.value)try{o.value=!0,C.value=!1;let a="";if(t.mode==="server")if(t.fetchFullData)a=await t.fetchFullData();else throw new Error("fetchFullData function is required for server mode");else a=t.value;const c=f(),h={data:a,timestamp:Date.now(),expiry:t.cacheExpiry*60*1e3};y.setCache(c,h),s.value=!0}catch(a){console.error("Failed to fetch full data:",a),C.value=!0}finally{o.value=!1}},N=(a,c)=>{if(!a)return"";switch(c){case"phone":return a.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2");case"idCard":return a.replace(/(\d{6})\d{8}(\d{4})/,"$1********$2");case"bankCard":return a.replace(/(\d{4})\d{8}(\d{4})/,"$1********$2");case"email":const[h,q]=a.split("@");return h.length<=2?a:`${h.substring(0,2)}***@${q}`;case"custom":default:if(a.length<=t.showStart+t.showEnd)return a;const B=a.substring(0,t.showStart),R=a.substring(a.length-t.showEnd),T=t.maskChar.repeat(a.length-t.showStart-t.showEnd);return`${B}${T}${R}`}},w=n.computed(()=>s.value?t.mode==="server"&&V()||t.value:N(t.value,t.type));return u({setFullDataAndShow:a=>{d.value=a,m.value=Date.now(),s.value=!0},hideData:()=>{s.value=!1},toggle:()=>{_()},getVisibleState:()=>s.value,clearCache:()=>{const a=f();y.clearCache(a)}}),(a,c)=>(n.openBlock(),n.createElementBlock("div",E,[n.createVNode(n.unref(S.Tooltip),{title:w.value,placement:"top"},{default:n.withCtx(()=>[n.createElementVNode("span",{class:n.normalizeClass(["data-text",{"is-masked":!s.value&&t.mode==="client"}])},n.toDisplayString(w.value),3)]),_:1},8,["title"]),n.createVNode(n.unref(S.Button),{type:"text",size:"small",class:"toggle-btn",onClick:_,loading:o.value},{icon:n.withCtx(()=>[!s.value&&!o.value?(n.openBlock(),n.createBlock(n.unref(p.EyeOutlined),{key:0})):s.value&&!o.value?(n.openBlock(),n.createBlock(n.unref(p.EyeInvisibleOutlined),{key:1})):n.createCommentVNode("",!0)]),_:1},8,["loading"])]))}}),O="",g=((e,u)=>{const r=e.__vccOpts||e;for(const[t,l]of u)r[t]=l;return r})(k,[["__scopeId","data-v-8cb6442a"]]),v="SENSITIVE_CACHE_",D=(e,u)=>{const r=[];for(let t=0;t<e.length;t++){const l=e.key(t);l&&l.startsWith(u)&&r.push(l)}r.forEach(t=>e.removeItem(t))},I=e=>{const u=()=>n.defineComponent({name:"SensitiveDataDisplayWrapper",props:{value:{type:String,required:!0},mode:{type:String,default:(e==null?void 0:e.mode)||"server"},type:{type:String,default:(e==null?void 0:e.type)||"custom"},showStart:{type:Number,default:(e==null?void 0:e.showStart)||3},showEnd:{type:Number,default:(e==null?void 0:e.showEnd)||4},maskChar:{type:String,default:(e==null?void 0:e.maskChar)||"*"},defaultVisible:{type:Boolean,default:(e==null?void 0:e.defaultVisible)||!1},fetchFullData:{type:Function,default:e==null?void 0:e.fetchFullData},dataId:{type:[String,Number],default:e==null?void 0:e.dataId},cacheExpiry:{type:Number,default:(e==null?void 0:e.cacheExpiry)||10},cacheStorage:{type:String,default:(e==null?void 0:e.cacheStorage)||"memory"}},emits:["toggleRequest"],setup(r,{emit:t,attrs:l}){const s=n.ref();return()=>n.h(g,{ref:s,...r,...l,onToggleRequest:(o,d)=>{t("toggleRequest",o,d)}})}});return{SensitiveDataDisplayComponent:u(),createComponent:u}},x=()=>{try{typeof sessionStorage<"u"&&D(sessionStorage,v),typeof localStorage<"u"&&D(localStorage,v),console.log("All sensitive data cache cleared")}catch(e){console.warn("Failed to clear sensitive cache:",e)}},F={install:e=>{e.component("SensitiveDataDisplay",g)}};i.SensitiveDataDisplay=g,i.clearAllSensitiveCache=x,i.default=F,i.useSensitiveDataDisplay=I,Object.defineProperties(i,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});