Files
sales-trainer/frontend/dist/assets/Settings-k8fzlPYr.js
Macky e1d61e1e1e feat(ip): protect persona 'formula' — secret fields only super_admin sees/edits
IP protection so casual copying yields inferior results:
- SECRET_PERSONA_FIELDS (pains/objections/negotiation_levers/opener/tolerance +
  pain rootCause/resolutionConditions): only super_admin can view/edit them.
- list_personas/get_persona/update_persona/get_group strip these for role=admin (and
  hide sales_kit + pain-fit report from admins too).
- update_persona rejects admin attempts to set secret fields (403).
- PersonaForm hides the 'การขาย' recipe section for non-super-admin (shows locked note);
  auth.isSuperAdmin getter added.
Rebuilt dist. Added test_ip_protection.
2026-08-09 07:22:50 +07:00

12 lines
4.3 KiB
JavaScript

import{c as M,_ as T,r as c,h as u,a as h,b as e,l as k,u as a,S as $,m as v,t as o,i as s,w as b,v as x,g as V,B as S,x as B,o as g}from"./index-BCax2GDh.js";import{L as D}from"./lock-uERjsrGr.js";/**
* @license lucide-vue-next v1.0.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const E=M("globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);/**
* @license lucide-vue-next v1.0.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const I=M("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]),j={class:"card"},G={style:{"margin-top":"0"}},H={class:"muted"},O=["value"],q={class:"row",style:{gap:"10px","margin-top":"16px"}},A=["disabled"],F={key:0,class:"spinner"},J={class:"card",style:{"margin-top":"16px"}},K={style:{"margin-top":"0"}},Q={class:"row",style:{gap:"10px","margin-top":"16px"}},R=["disabled"],W={key:0,class:"spinner"},X={class:"card",style:{"margin-top":"16px"}},Y={style:{"margin-top":"0"}},Z={class:"row"},ee={key:0,class:"error",role:"alert"},ae={key:1,class:"ok",role:"status"},se={__name:"Settings",setup(te){var z,C;const y=c(((z=u.user)==null?void 0:z.name)||""),p=c(((C=u.user)==null?void 0:C.email)||""),i=c(""),_=c(""),r=c(""),m=c(""),f=c(!1),w=c(!1);async function U(){var d,t;r.value="",m.value="",f.value=!0;try{const n={};if(y.value&&y.value!==((d=u.user)==null?void 0:d.name)&&(n.name=y.value),p.value&&p.value!==((t=u.user)==null?void 0:t.email)&&(n.email=p.value),Object.keys(n).length){const l=await B.updateProfile(n);u.user=l.user,m.value=s.t("saved")}}catch(n){r.value=n.message}finally{f.value=!1}}async function L(){var d,t,n;if(r.value="",m.value="",i.value.length<4){r.value=s.t("passwordTooShort");return}if(i.value!==_.value){r.value=s.t("passwordMismatch");return}w.value=!0;try{const l=((d=u.user)==null?void 0:d.username)||((t=u.user)==null?void 0:t.id)||"",N=await B.setup({username:l,email:p.value||((n=u.user)==null?void 0:n.email),password:i.value});u.user=N.user,i.value="",_.value="",m.value=s.t("saved")}catch(l){r.value=l.message}finally{w.value=!1}}function P(d){s.set(d)}return(d,t)=>{var n;return g(),h("div",null,[e("h2",null,[k(a($),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),v(" "+o(a(s).t("settings")),1)]),e("div",j,[e("h3",G,[k(a(I),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("profile")),1)]),e("label",null,[v(o(a(s).t("username"))+" ",1),e("span",H,"("+o(a(s).t("readonly"))+")",1)]),e("input",{value:((n=a(u).user)==null?void 0:n.username)||"",disabled:""},null,8,O),e("label",null,o(a(s).t("name")),1),b(e("input",{"onUpdate:modelValue":t[0]||(t[0]=l=>y.value=l),type:"text"},null,512),[[x,y.value]]),e("label",null,o(a(s).t("email")),1),b(e("input",{"onUpdate:modelValue":t[1]||(t[1]=l=>p.value=l),type:"email"},null,512),[[x,p.value]]),e("div",q,[e("button",{class:"primary",disabled:f.value,onClick:U},[f.value?(g(),h("span",F)):V("",!0),v(o(a(s).t("saveProfile")),1)],8,A)])]),e("div",J,[e("h3",K,[k(a(D),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("changePassword")),1)]),e("label",null,o(a(s).t("newPassword")),1),b(e("input",{"onUpdate:modelValue":t[2]||(t[2]=l=>i.value=l),type:"password",autocomplete:"new-password"},null,512),[[x,i.value]]),e("label",null,o(a(s).t("confirmPassword")),1),b(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>_.value=l),type:"password",autocomplete:"new-password"},null,512),[[x,_.value]]),e("div",Q,[e("button",{class:"primary",disabled:w.value||!i.value||i.value!==_.value,onClick:L},[w.value?(g(),h("span",W)):V("",!0),v(o(a(s).t("save")),1)],8,R)])]),e("div",X,[e("h3",Y,[k(a(E),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("language")),1)]),e("div",Z,[e("button",{class:S({active:a(s).locale==="th"}),onClick:t[4]||(t[4]=l=>P("th"))},"ไทย",2),e("button",{class:S({active:a(s).locale==="en"}),onClick:t[5]||(t[5]=l=>P("en"))},"English",2)])]),r.value?(g(),h("div",ee,o(r.value),1)):V("",!0),m.value?(g(),h("div",ae,"✅ "+o(m.value),1)):V("",!0)])}}},ne=T(se,[["__scopeId","data-v-4a5a3af4"]]);export{ne as default};