max-remotes-helper 1.0.2 → 1.0.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/dist/components/DevButton.d.ts +1 -0
- package/dist/components/DevCard.d.ts +1 -0
- package/dist/components/DevWrapper.d.ts +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/DevButton.tsx +47 -14
- package/src/components/DevCard.tsx +16 -4
- package/src/components/DevWrapper.tsx +65 -18
- package/src/components/FloatingTokenButton.tsx +42 -5
- package/src/components/TokenGenerator.tsx +128 -25
- package/src/components/TokenInput.tsx +39 -9
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
-
(()=>{var e={20:(e,t,r)=>{"use strict";var o=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,i=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var o,a={},c=null,d=null;for(o in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,o)&&!l.hasOwnProperty(o)&&(a[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===a[o]&&(a[o]=t[o]);return{$$typeof:n,type:e,key:c,ref:d,props:a,_owner:i.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},60:(e,t,r)=>{var o={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(o,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r(o[e])})}n.keys=()=>Object.keys(o),n.id=60,e.exports=n},87:(e,t,r)=>{(()=>{var t={20:(e,t,r)=>{"use strict";var o=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,i=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.Fragment=a,t.jsx=function(e,t,r){var o,a={},c=null,d=null;for(o in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,o)&&!l.hasOwnProperty(o)&&(a[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===a[o]&&(a[o]=t[o]);return{$$typeof:n,type:e,key:c,ref:d,props:a,_owner:i.current}}},60:(e,t,r)=>{var o={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(o,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r(o[e])})}n.keys=()=>Object.keys(o),n.id=60,e.exports=n},226:(e,t,r)=>{"use strict";r.r(t),r.d(t,{createRemoteComponentLoader:()=>i,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>s,loadRemoteModule:()=>a});var o=r(953),n=r.n(o);const a=async(e,t)=>{try{return await r(60)(`${e}/${t}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${t}:`,r),r}},s=async e=>{try{const t=window[e];return"function"==typeof t?.get}catch(e){return!1}},i=(e,t,r)=>n().lazy(async()=>{try{return await a(e,t)}catch(o){return console.error(`Remote component loading failed: ${e}/${t}`,o),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${t}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,t,r)=>{"use strict";r.r(t),r.d(t,{decodeToken:()=>o,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>s});const o=e=>{try{if(!e)return null;const t=e.split(".");if(3!==t.length)return null;const r=t[1],o=r+"=".repeat((4-r.length%4)%4),n=atob(o);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const t=o(e);if(!t||!t.exp)return!0;const r=Math.floor(Date.now()/1e3);return t.exp<r},a=e=>{if(!e)return[];const t=["permissions","roles","authorities","scope"];for(const r of t){const t=e[r];if(Array.isArray(t))return t;if("string"==typeof t)return t.split(" ").filter(Boolean)}return[]},s={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(s.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(s.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(s.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,t,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=r(953)}},o={};function n(e){var r=o[e];if(void 0!==r)return r.exports;var a=o[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.e=()=>Promise.resolve(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};(()=>{"use strict";n.r(a),n.d(a,{RemoteAuthProvider:()=>l,RemoteWrapper:()=>u,Secured:()=>d,createRemoteComponentLoader:()=>g.createRemoteComponentLoader,decodeToken:()=>r.decodeToken,extractPermissions:()=>r.extractPermissions,getRemoteEnvironment:()=>g.getRemoteEnvironment,isRemoteAvailable:()=>g.isRemoteAvailable,isTokenExpired:()=>r.isTokenExpired,loadRemoteModule:()=>g.loadRemoteModule,tokenStorage:()=>r.tokenStorage,useRemoteAuth:()=>c,useRemoteConfig:()=>m});var e=n(848),t=n(953),r=n(433);const o={token:null,isAuthenticated:!1,permissions:[],user:void 0},s=(e,t)=>{switch(t.type){case"SET_TOKEN":const n=(0,r.decodeToken)(t.payload),a=n?(0,r.extractPermissions)(n):[];return{...e,token:t.payload,isAuthenticated:!(0,r.isTokenExpired)(t.payload),permissions:a,user:n?{id:n.sub||"",email:n.email||"",name:n.name||n.email||""}:void 0};case"CLEAR_AUTH":return{...o};case"SET_USER_INFO":return{...e,user:{id:t.payload.sub||"",email:t.payload.email||"",name:t.payload.name||t.payload.email||""}};default:return e}},i=(0,t.createContext)(void 0),l=({children:n,initialToken:a})=>{const[l,c]=(0,t.useReducer)(s,o);(0,t.useEffect)(()=>{if(console.log("🔍 RemoteAuthContext: useEffect triggered",{initialToken:a?a.substring(0,30)+"...":"No initialToken"}),a)console.log("✅ RemoteAuthContext: Using initialToken from prop"),(0,r.isTokenExpired)(a)?(console.log("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),r.tokenStorage.remove(),c({type:"CLEAR_AUTH"})):(console.log("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),c({type:"SET_TOKEN",payload:a}),r.tokenStorage.save(a));else{console.log("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=r.tokenStorage.get();e&&!(0,r.isTokenExpired)(e)?(console.log("💾 RemoteAuthContext: Using stored token"),c({type:"SET_TOKEN",payload:e})):e&&(console.log("🗑️ RemoteAuthContext: Stored token expired, clearing"),r.tokenStorage.remove(),c({type:"CLEAR_AUTH"}))}},[a]);const d={state:l,setToken:e=>{e&&(r.tokenStorage.save(e),c({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{r.tokenStorage.remove(),c({type:"CLEAR_AUTH"})},hasPermission:e=>!!l.isAuthenticated&&l.permissions.includes(e)};return(0,e.jsx)(i.Provider,{value:d,children:n})},c=()=>{const e=(0,t.useContext)(i);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},d=({children:t,permission:r,fallback:o=null})=>{const{hasPermission:n,state:a}=c();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:t}):(0,e.jsx)(e.Fragment,{children:o})},u=({children:t,token:r,apiBaseUrl:o,module:n})=>(0,e.jsx)(l,{initialToken:r,children:(0,e.jsx)("div",{"data-remote-module":n,"data-api-base":o,children:t})}),m=()=>{const e=(0,t.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(t,r)=>({name:t,filename:"remoteEntry.js",exposes:r,shared:e})}};var g=n(226)})(),e.exports=a})()},226:(e,t,r)=>{"use strict";r.r(t),r.d(t,{createRemoteComponentLoader:()=>i,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>s,loadRemoteModule:()=>a});var o=r(953),n=r.n(o);const a=async(e,t)=>{try{return await r(60)(`${e}/${t}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${t}:`,r),r}},s=async e=>{try{const t=window[e];return"function"==typeof t?.get}catch(e){return!1}},i=(e,t,r)=>n().lazy(async()=>{try{return await a(e,t)}catch(o){return console.error(`Remote component loading failed: ${e}/${t}`,o),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${t}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,t,r)=>{"use strict";r.r(t),r.d(t,{decodeToken:()=>o,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>s});const o=e=>{try{if(!e)return null;const t=e.split(".");if(3!==t.length)return null;const r=t[1],o=r+"=".repeat((4-r.length%4)%4),n=atob(o);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const t=o(e);if(!t||!t.exp)return!0;const r=Math.floor(Date.now()/1e3);return t.exp<r},a=e=>{if(!e)return[];const t=["permissions","roles","authorities","scope"];for(const r of t){const t=e[r];if(Array.isArray(t))return t;if("string"==typeof t)return t.split(" ").filter(Boolean)}return[]},s={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(s.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(s.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(s.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,t,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=require("react")}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var a=t[o]={exports:{}};return e[o](a,a.exports,r),a.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.e=()=>Promise.resolve(),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var o={};(()=>{"use strict";r.r(o),r.d(o,{DevWrapper:()=>y,RemoteAuthProvider:()=>l,RemoteWrapper:()=>u,Secured:()=>d,createRemoteComponentLoader:()=>b.createRemoteComponentLoader,decodeToken:()=>n.decodeToken,extractPermissions:()=>n.extractPermissions,getRemoteEnvironment:()=>b.getRemoteEnvironment,isRemoteAvailable:()=>b.isRemoteAvailable,isTokenExpired:()=>n.isTokenExpired,loadRemoteModule:()=>b.loadRemoteModule,tokenStorage:()=>n.tokenStorage,useRemoteAuth:()=>c,useRemoteConfig:()=>v});var e=r(848),t=r(953),n=r(433);const a={token:null,isAuthenticated:!1,permissions:[],user:void 0},s=(e,t)=>{switch(t.type){case"SET_TOKEN":const r=(0,n.decodeToken)(t.payload),o=r?(0,n.extractPermissions)(r):[];return{...e,token:t.payload,isAuthenticated:!(0,n.isTokenExpired)(t.payload),permissions:o,user:r?{id:r.sub||"",email:r.email||"",name:r.name||r.email||""}:void 0};case"CLEAR_AUTH":return{...a};case"SET_USER_INFO":return{...e,user:{id:t.payload.sub||"",email:t.payload.email||"",name:t.payload.name||t.payload.email||""}};default:return e}},i=(0,t.createContext)(void 0),l=({children:r,initialToken:o})=>{const[l,c]=(0,t.useReducer)(s,a),d="dev"===process.env.REACT_APP_ENVIRONMENT?console.log:()=>{};(0,t.useEffect)(()=>{if(d("🔍 RemoteAuthContext: useEffect triggered",{initialToken:o?o.substring(0,30)+"...":"No initialToken"}),o)d("✅ RemoteAuthContext: Using initialToken from prop"),(0,n.isTokenExpired)(o)?(d("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),n.tokenStorage.remove(),c({type:"CLEAR_AUTH"})):(d("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),c({type:"SET_TOKEN",payload:o}),n.tokenStorage.save(o));else{d("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=n.tokenStorage.get();e&&!(0,n.isTokenExpired)(e)?(d("💾 RemoteAuthContext: Using stored token"),c({type:"SET_TOKEN",payload:e})):e&&(d("🗑️ RemoteAuthContext: Stored token expired, clearing"),n.tokenStorage.remove(),c({type:"CLEAR_AUTH"}))}},[o]);const u={state:l,setToken:e=>{e&&(n.tokenStorage.save(e),c({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{n.tokenStorage.remove(),c({type:"CLEAR_AUTH"})},hasPermission:e=>!!l.isAuthenticated&&l.permissions.includes(e)};return(0,e.jsx)(i.Provider,{value:u,children:r})},c=()=>{const e=(0,t.useContext)(i);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},d=({children:t,permission:r,fallback:o=null})=>{const{hasPermission:n,state:a}=c();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:t}):(0,e.jsx)(e.Fragment,{children:o})},u=({children:t,token:r})=>(0,e.jsx)(l,{initialToken:r,children:(0,e.jsx)("div",{children:t})});var m=r(87);const g=({children:t,className:r=""})=>(0,e.jsx)("div",{className:`bg-white rounded-lg shadow-md border border-gray-20 ${r}`,children:t}),p=({label:t,onClick:r,disabled:o=!1,variant:n="primary",size:a="medium",className:s="",type:i="button"})=>(0,e.jsx)("button",{type:i,onClick:r,disabled:o,className:`rounded-lg font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed ${{primary:"bg-gradient-to-br from-blue-40 to-blue-70 hover:from-blue-50 hover:to-blue-90 text-white focus:ring-blue-50 shadow-sm hover:shadow-md",secondary:"bg-gray-20 hover:bg-gray-30 text-gray-80 focus:ring-gray-40 border border-gray-30",text:"bg-transparent hover:bg-gray-10 text-blue-60 hover:text-blue-80 focus:ring-blue-30"}[n]} ${{small:"px-4 py-2 text-sm",medium:"px-5 py-2.5 text-base",large:"px-6 py-3 text-lg"}[a]} ${s}`,children:t}),x=({onSubmit:r,onCancel:o,onClearStorage:n,defaultDevRoles:a=[],currentToken:s=""})=>{const[i,l]=(0,t.useState)(!1),[c,d]=(0,t.useState)(""),[u,m]=(0,t.useState)({user:"usuario@bdsol.com.ar",roles:a,channel:"mf-testing",sessionId:crypto.randomUUID()}),[x,h]=(0,t.useState)(a.join("\n")),f=(e,t)=>{m(r=>({...r,[e]:t}))};return(0,e.jsx)("div",{className:"p-6 w-full overflow-y-auto",children:(0,e.jsx)(g,{className:"p-6",children:(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)("h2",{className:"text-2xl font-bold text-gray-80 mb-4",children:"🔧 Generador de Tokens (Desarrollo)"}),(0,e.jsx)("p",{className:"text-gray-60 mb-6",children:"Genera un token JWT para desarrollo usando el BFF. Solo disponible cuando ENVIRONMENT=dev."}),c&&(0,e.jsx)("div",{className:"mb-4 p-3 bg-red-10 border border-red-40 text-red-70 rounded",children:c}),(0,e.jsxs)("div",{className:"space-y-4 mb-6",children:[(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Email del usuario"}),(0,e.jsx)("input",{type:"email",value:u.user,onChange:e=>f("user",e.target.value),className:"w-full p-2 border border-gray-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:"usuario@bdsol.com.ar"})]}),(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Roles (uno por línea)"}),(0,e.jsx)("textarea",{value:x,onChange:e=>h(e.target.value),className:"w-full h-32 p-2 border border-gray-30 rounded-lg font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:a.join(" ")}),(0,e.jsx)("p",{className:"text-xs text-gray-50 mt-1",children:"Roles definidos en src/config/roles.ts"})]}),(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Channel"}),(0,e.jsx)("input",{type:"text",value:u.channel,onChange:e=>f("channel",e.target.value),className:"w-full p-2 border border-gray-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:"mf-testing"})]}),(0,e.jsxs)("div",{children:[(0,e.jsx)("label",{className:"block text-sm font-medium text-gray-70 mb-1",children:"Session ID"}),(0,e.jsxs)("div",{className:"flex gap-2",children:[(0,e.jsx)("input",{type:"text",value:u.sessionId,onChange:e=>f("sessionId",e.target.value),className:"flex-1 p-2 border border-gray-30 rounded-lg font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-50",placeholder:"uuid-session-id"}),(0,e.jsx)(p,{label:"🎲",variant:"primary",size:"small",onClick:()=>{m(e=>({...e,sessionId:crypto.randomUUID()}))},className:"px-3"})]})]})]}),(0,e.jsxs)("div",{className:"flex gap-3 flex-wrap mb-4",children:[(0,e.jsx)(p,{label:i?"Generando...":"🚀 Generar Token",variant:"primary",size:"small",onClick:async()=>{l(!0),d(""),n();try{const e=x.split("\n").map(e=>e.trim()).filter(e=>e.length>0),t={...u,roles:e},o=process.env.REACT_APP_API_URL||"http://localhost:3020",n=await fetch(`${o}/template/api/dev/generate-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const e=await n.json();throw new Error(e.error||"Error al generar token")}const a=await n.json();r(a.token)}catch(e){d(e instanceof Error?e.message:"Error desconocido")}finally{l(!1)}},disabled:i||!u.user.trim()}),(0,e.jsx)(p,{label:"Limpiar almacenamiento",variant:"primary",size:"small",onClick:()=>{n(),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(p,{label:"Cancelar",size:"small",variant:"secondary",onClick:o})]}),s&&(0,e.jsxs)("div",{className:"mt-4 p-4 bg-green-50 rounded-lg",children:[(0,e.jsx)("h3",{className:"font-semibold text-green-70 mb-2",children:"✅ Token cargado"}),(0,e.jsx)("p",{className:"text-sm text-green-60",children:"Tienes un token activo en el almacenamiento local."})]})," "]})})})},h=({onSubmit:r,onCancel:o,onClearStorage:n,currentToken:a=""})=>{const[s,i]=(0,t.useState)(a),[l,c]=(0,t.useState)(!0);return(0,e.jsxs)("div",{className:"bg-white rounded-lg shadow-lg p-6 w-full max-w-2xl",children:[(0,e.jsx)("h2",{className:"text-2xl font-bold text-gray-80 mb-4",children:"Modo Desarrollo - Cargar Token JWT"}),(0,e.jsx)("p",{className:"text-gray-60 mb-6",children:"Ingresa el token JWT decodificado (JSON) que normalmente recibiría desde el host:"}),(0,e.jsxs)("div",{className:"mb-4",children:[(0,e.jsx)("textarea",{value:s,onChange:e=>{const t=e.target.value;i(t),l||c(!0)},placeholder:"Pegue aquí el token JWT en formato JSON",className:`w-full h-40 p-3 border rounded-lg font-mono text-sm ${l?"border-gray-30":"border-red-50"} focus:outline-none focus:ring-2 focus:ring-blue-50`}),!l&&(0,e.jsx)("p",{className:"text-red-50 text-sm mt-2",children:"El JSON no es válido. Por favor verifica la sintaxis."})]}),(0,e.jsxs)("div",{className:"flex gap-3 flex-wrap",children:[(0,e.jsx)(p,{label:"Cargar Token",variant:"primary",size:"small",onClick:()=>{try{JSON.parse(s),c(!0),r(s)}catch(e){c(!1)}},disabled:!s.trim()}),(0,e.jsx)(p,{label:"Limpiar",size:"small",variant:"text",onClick:()=>i("")}),(0,e.jsx)(p,{label:"Limpiar Storage",variant:"primary",size:"small",onClick:()=>{n(),i(""),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(p,{label:"Cancelar",variant:"secondary",size:"small",onClick:o})]})]})},f=({onClick:t})=>(0,e.jsxs)("button",{onClick:t,className:"fixed bottom-6 right-6 bg-gradient-to-br from-blue-40 to-blue-70 hover:from-blue-50 hover:to-blue-90 text-white p-4 rounded-full shadow-dropdown hover:shadow-2xl transition-all duration-300 z-50 group transform hover:scale-110",title:"Recargar Token",children:[(0,e.jsx)("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,e.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"})}),(0,e.jsx)("span",{className:"absolute bottom-full right-0 mb-3 px-3 py-1 text-xs text-white bg-gray-90/90 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap backdrop-blur-sm",children:"Recargar Token"})]}),y=({children:r})=>{const[o,n]=(0,t.useState)(""),[a,s]=(0,t.useState)(!1),[i,l]=(0,t.useState)(!1),[c,d]=(0,t.useState)(!0),u="dev"===process.env.REACT_APP_ENVIRONMENT&&!o;(0,t.useEffect)(()=>{const e=m.tokenStorage.get();e?(n(e),l(!1)):u&&l(!0)},[u]);const g=e=>{console.log("🔄 DevWrapper: Nuevo token generado",{token:e.substring(0,50)+"..."}),n(e),m.tokenStorage.save(e),console.log("💾 DevWrapper: Token guardado en storage"),s(!1),l(!1)},p=()=>{m.tokenStorage.clear(),n(""),l(u)};return i?(0,e.jsx)("div",{className:"min-h-screen bg-gray-50 flex items-center justify-center p-4",children:(0,e.jsx)(x,{onSubmit:g,onCancel:()=>l(!1),onClearStorage:p,currentToken:o})}):(0,e.jsxs)("div",{className:"min-h-screen bg-gray-50",children:[a&&(0,e.jsx)("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:(0,e.jsxs)("div",{className:"bg-white rounded-lg shadow-lg max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto",children:[(0,e.jsxs)("div",{className:"flex border-b",children:[(0,e.jsx)("button",{onClick:()=>d(!0),className:"flex-1 py-3 px-4 text-sm font-medium "+(c?"bg-blue-50 ":"bg-gray-10 text-gray-70 hover:bg-gray-20"),children:"Generar Token"}),(0,e.jsx)("button",{onClick:()=>d(!1),className:"flex-1 py-3 px-4 text-sm font-medium "+(c?"bg-gray-10 text-gray-70 hover:bg-gray-20":"bg-blue-50 text-gray-50"),children:"Input Manual"})]}),(0,e.jsx)("div",{className:"p-0",children:c?(0,e.jsx)(x,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:p,currentToken:o}):(0,e.jsx)("div",{className:"p-6",children:(0,e.jsx)(h,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:p,currentToken:o})})})]})}),(0,e.jsx)(f,{onClick:()=>{s(!a)}}),(0,e.jsx)(m.RemoteWrapper,{token:o,children:r})]})},v=()=>{const e=(0,t.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(t,r)=>({name:t,filename:"remoteEntry.js",exposes:r,shared:e})}};var b=r(226)})(),module.exports=o})();
|
|
2
|
+
(()=>{var e={20:(e,o,r)=>{"use strict";var t=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function d(e,o,r){var t,a={},d=null,c=null;for(t in void 0!==r&&(d=""+r),void 0!==o.key&&(d=""+o.key),void 0!==o.ref&&(c=o.ref),o)i.call(o,t)&&!l.hasOwnProperty(t)&&(a[t]=o[t]);if(e&&e.defaultProps)for(t in o=e.defaultProps)void 0===a[t]&&(a[t]=o[t]);return{$$typeof:n,type:e,key:d,ref:c,props:a,_owner:s.current}}o.Fragment=a,o.jsx=d,o.jsxs=d},60:(e,o,r)=>{var t={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(t,e)){var o=new Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}return r(t[e])})}n.keys=()=>Object.keys(t),n.id=60,e.exports=n},87:(e,o,r)=>{(()=>{var o={20:(e,o,r)=>{"use strict";var t=r(953),n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};o.Fragment=a,o.jsx=function(e,o,r){var t,a={},d=null,c=null;for(t in void 0!==r&&(d=""+r),void 0!==o.key&&(d=""+o.key),void 0!==o.ref&&(c=o.ref),o)i.call(o,t)&&!l.hasOwnProperty(t)&&(a[t]=o[t]);if(e&&e.defaultProps)for(t in o=e.defaultProps)void 0===a[t]&&(a[t]=o[t]);return{$$typeof:n,type:e,key:d,ref:c,props:a,_owner:s.current}}},60:(e,o,r)=>{var t={"./moduleUtils":226,"./moduleUtils.ts":226,"./tokenUtils":433,"./tokenUtils.ts":433};function n(e){return Promise.resolve().then(()=>{if(!r.o(t,e)){var o=new Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}return r(t[e])})}n.keys=()=>Object.keys(t),n.id=60,e.exports=n},226:(e,o,r)=>{"use strict";r.r(o),r.d(o,{createRemoteComponentLoader:()=>s,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>i,loadRemoteModule:()=>a});var t=r(953),n=r.n(t);const a=async(e,o)=>{try{return await r(60)(`${e}/${o}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${o}:`,r),r}},i=async e=>{try{const o=window[e];return"function"==typeof o?.get}catch(e){return!1}},s=(e,o,r)=>n().lazy(async()=>{try{return await a(e,o)}catch(t){return console.error(`Remote component loading failed: ${e}/${o}`,t),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${o}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,o,r)=>{"use strict";r.r(o),r.d(o,{decodeToken:()=>t,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>i});const t=e=>{try{if(!e)return null;const o=e.split(".");if(3!==o.length)return null;const r=o[1],t=r+"=".repeat((4-r.length%4)%4),n=atob(t);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const o=t(e);if(!o||!o.exp)return!0;const r=Math.floor(Date.now()/1e3);return o.exp<r},a=e=>{if(!e)return[];const o=["permissions","roles","authorities","scope"];for(const r of o){const o=e[r];if(Array.isArray(o))return o;if("string"==typeof o)return o.split(" ").filter(Boolean)}return[]},i={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(i.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(i.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(i.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,o,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=r(953)}},t={};function n(e){var r=t[e];if(void 0!==r)return r.exports;var a=t[e]={exports:{}};return o[e](a,a.exports,n),a.exports}n.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return n.d(o,{a:o}),o},n.d=(e,o)=>{for(var r in o)n.o(o,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},n.e=()=>Promise.resolve(),n.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};(()=>{"use strict";n.r(a),n.d(a,{RemoteAuthProvider:()=>l,RemoteWrapper:()=>m,Secured:()=>c,createRemoteComponentLoader:()=>p.createRemoteComponentLoader,decodeToken:()=>r.decodeToken,extractPermissions:()=>r.extractPermissions,getRemoteEnvironment:()=>p.getRemoteEnvironment,isRemoteAvailable:()=>p.isRemoteAvailable,isTokenExpired:()=>r.isTokenExpired,loadRemoteModule:()=>p.loadRemoteModule,tokenStorage:()=>r.tokenStorage,useRemoteAuth:()=>d,useRemoteConfig:()=>u});var e=n(848),o=n(953),r=n(433);const t={token:null,isAuthenticated:!1,permissions:[],user:void 0},i=(e,o)=>{switch(o.type){case"SET_TOKEN":const n=(0,r.decodeToken)(o.payload),a=n?(0,r.extractPermissions)(n):[];return{...e,token:o.payload,isAuthenticated:!(0,r.isTokenExpired)(o.payload),permissions:a,user:n?{id:n.sub||"",email:n.email||"",name:n.name||n.email||""}:void 0};case"CLEAR_AUTH":return{...t};case"SET_USER_INFO":return{...e,user:{id:o.payload.sub||"",email:o.payload.email||"",name:o.payload.name||o.payload.email||""}};default:return e}},s=(0,o.createContext)(void 0),l=({children:n,initialToken:a})=>{const[l,d]=(0,o.useReducer)(i,t);(0,o.useEffect)(()=>{if(console.log("🔍 RemoteAuthContext: useEffect triggered",{initialToken:a?a.substring(0,30)+"...":"No initialToken"}),a)console.log("✅ RemoteAuthContext: Using initialToken from prop"),(0,r.isTokenExpired)(a)?(console.log("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),r.tokenStorage.remove(),d({type:"CLEAR_AUTH"})):(console.log("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),d({type:"SET_TOKEN",payload:a}),r.tokenStorage.save(a));else{console.log("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=r.tokenStorage.get();e&&!(0,r.isTokenExpired)(e)?(console.log("💾 RemoteAuthContext: Using stored token"),d({type:"SET_TOKEN",payload:e})):e&&(console.log("🗑️ RemoteAuthContext: Stored token expired, clearing"),r.tokenStorage.remove(),d({type:"CLEAR_AUTH"}))}},[a]);const c={state:l,setToken:e=>{e&&(r.tokenStorage.save(e),d({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{r.tokenStorage.remove(),d({type:"CLEAR_AUTH"})},hasPermission:e=>!!l.isAuthenticated&&l.permissions.includes(e)};return(0,e.jsx)(s.Provider,{value:c,children:n})},d=()=>{const e=(0,o.useContext)(s);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},c=({children:o,permission:r,fallback:t=null})=>{const{hasPermission:n,state:a}=d();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:o}):(0,e.jsx)(e.Fragment,{children:t})},m=({children:o,token:r,apiBaseUrl:t,module:n})=>(0,e.jsx)(l,{initialToken:r,children:(0,e.jsx)("div",{"data-remote-module":n,"data-api-base":t,children:o})}),u=()=>{const e=(0,o.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(o,r)=>({name:o,filename:"remoteEntry.js",exposes:r,shared:e})}};var p=n(226)})(),e.exports=a})()},226:(e,o,r)=>{"use strict";r.r(o),r.d(o,{createRemoteComponentLoader:()=>s,getRemoteEnvironment:()=>l,isRemoteAvailable:()=>i,loadRemoteModule:()=>a});var t=r(953),n=r.n(t);const a=async(e,o)=>{try{return await r(60)(`${e}/${o}`)}catch(r){throw console.error(`Failed to load remote module ${e}/${o}:`,r),r}},i=async e=>{try{const o=window[e];return"function"==typeof o?.get}catch(e){return!1}},s=(e,o,r)=>n().lazy(async()=>{try{return await a(e,o)}catch(t){return console.error(`Remote component loading failed: ${e}/${o}`,t),r?{default:r}:{default:()=>n().createElement("div",{style:{padding:"20px",color:"red"}},`Failed to load remote component: ${e}/${o}`)}}}),l=()=>({isDevelopment:!1,apiBaseUrl:process.env.REACT_APP_API_URL||"",frontUrl:process.env.REACT_APP_FRONT_URL||""})},433:(e,o,r)=>{"use strict";r.r(o),r.d(o,{decodeToken:()=>t,extractPermissions:()=>a,isTokenExpired:()=>n,tokenStorage:()=>i});const t=e=>{try{if(!e)return null;const o=e.split(".");if(3!==o.length)return null;const r=o[1],t=r+"=".repeat((4-r.length%4)%4),n=atob(t);return JSON.parse(n)}catch(e){return console.error("Error decoding token:",e),null}},n=e=>{const o=t(e);if(!o||!o.exp)return!0;const r=Math.floor(Date.now()/1e3);return o.exp<r},a=e=>{if(!e)return[];const o=["permissions","roles","authorities","scope"];for(const r of o){const o=e[r];if(Array.isArray(o))return o;if("string"==typeof o)return o.split(" ").filter(Boolean)}return[]},i={key:"bo-remote-token",save:e=>{try{sessionStorage.setItem(i.key,e)}catch(e){console.error("Error saving token:",e)}},get:()=>{try{return sessionStorage.getItem(i.key)}catch(e){return console.error("Error getting token:",e),null}},remove:()=>{try{sessionStorage.removeItem(i.key)}catch(e){console.error("Error removing token:",e)}},clear:()=>{try{sessionStorage.clear()}catch(e){console.error("Error clearing storage:",e)}}}},848:(e,o,r)=>{"use strict";e.exports=r(20)},953:e=>{"use strict";e.exports=require("react")}},o={};function r(t){var n=o[t];if(void 0!==n)return n.exports;var a=o[t]={exports:{}};return e[t](a,a.exports,r),a.exports}r.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return r.d(o,{a:o}),o},r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},r.e=()=>Promise.resolve(),r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var t={};(()=>{"use strict";r.r(t),r.d(t,{DevWrapper:()=>v,RemoteAuthProvider:()=>d,RemoteWrapper:()=>u,Secured:()=>m,createRemoteComponentLoader:()=>b.createRemoteComponentLoader,decodeToken:()=>a.decodeToken,extractPermissions:()=>a.extractPermissions,getRemoteEnvironment:()=>b.getRemoteEnvironment,isRemoteAvailable:()=>b.isRemoteAvailable,isTokenExpired:()=>a.isTokenExpired,loadRemoteModule:()=>b.loadRemoteModule,tokenStorage:()=>a.tokenStorage,useRemoteAuth:()=>c,useRemoteConfig:()=>k});var e=r(848),o=r(953),n=r.n(o),a=r(433);const i={token:null,isAuthenticated:!1,permissions:[],user:void 0},s=(e,o)=>{switch(o.type){case"SET_TOKEN":const r=(0,a.decodeToken)(o.payload),t=r?(0,a.extractPermissions)(r):[];return{...e,token:o.payload,isAuthenticated:!(0,a.isTokenExpired)(o.payload),permissions:t,user:r?{id:r.sub||"",email:r.email||"",name:r.name||r.email||""}:void 0};case"CLEAR_AUTH":return{...i};case"SET_USER_INFO":return{...e,user:{id:o.payload.sub||"",email:o.payload.email||"",name:o.payload.name||o.payload.email||""}};default:return e}},l=(0,o.createContext)(void 0),d=({children:r,initialToken:t})=>{const[n,d]=(0,o.useReducer)(s,i),c="dev"===process.env.REACT_APP_ENVIRONMENT?console.log:()=>{};(0,o.useEffect)(()=>{if(c("🔍 RemoteAuthContext: useEffect triggered",{initialToken:t?t.substring(0,30)+"...":"No initialToken"}),t)c("✅ RemoteAuthContext: Using initialToken from prop"),(0,a.isTokenExpired)(t)?(c("🔴 RemoteAuthContext: Provided token is expired, clearing auth"),a.tokenStorage.remove(),d({type:"CLEAR_AUTH"})):(c("🟢 RemoteAuthContext: Token is valid, dispatching SET_TOKEN"),d({type:"SET_TOKEN",payload:t}),a.tokenStorage.save(t));else{c("⚪ RemoteAuthContext: No initialToken, checking stored token");const e=a.tokenStorage.get();e&&!(0,a.isTokenExpired)(e)?(c("💾 RemoteAuthContext: Using stored token"),d({type:"SET_TOKEN",payload:e})):e&&(c("🗑️ RemoteAuthContext: Stored token expired, clearing"),a.tokenStorage.remove(),d({type:"CLEAR_AUTH"}))}},[t]);const m={state:n,setToken:e=>{e&&(a.tokenStorage.save(e),d({type:"SET_TOKEN",payload:e}))},clearAuth:()=>{a.tokenStorage.remove(),d({type:"CLEAR_AUTH"})},hasPermission:e=>!!n.isAuthenticated&&n.permissions.includes(e)};return(0,e.jsx)(l.Provider,{value:m,children:r})},c=()=>{const e=(0,o.useContext)(l);if(void 0===e)throw new Error("useRemoteAuth must be used within a RemoteAuthProvider");return e},m=({children:o,permission:r,fallback:t=null})=>{const{hasPermission:n,state:a}=c();return a.isAuthenticated&&n(r)?(0,e.jsx)(e.Fragment,{children:o}):(0,e.jsx)(e.Fragment,{children:t})},u=({children:o,token:r})=>(0,e.jsx)(d,{initialToken:r,children:(0,e.jsx)("div",{children:o})});var p=r(87);const g=({children:o,className:r="",style:t})=>{const n={backgroundColor:"white",borderRadius:"0.5rem",boxShadow:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",border:"1px solid #E5E7EB",...t};return(0,e.jsx)("div",{style:n,className:r,children:o})},h=({label:o,onClick:r,disabled:t=!1,variant:n="primary",size:a="medium",className:i="",type:s="button",style:l})=>{const d={borderRadius:"0.5rem",fontWeight:500,transition:"all 0.2s",outline:"none",cursor:t?"not-allowed":"pointer",opacity:t?.5:1,border:"none"};return(0,e.jsx)("button",{type:s,onClick:r,disabled:t,style:{...d,...{primary:{background:"linear-gradient(to bottom right, #3B82F6, #1E40AF)",color:"white",boxShadow:"0 1px 2px 0 rgb(0 0 0 / 0.05)"},secondary:{backgroundColor:"#F3F4F6",color:"#1F2937",border:"1px solid #D1D5DB"},text:{backgroundColor:"transparent",color:"#2563EB"}}[n],...{small:{padding:"0.5rem 1rem",fontSize:"0.875rem"},medium:{padding:"0.625rem 1.25rem",fontSize:"1rem"},large:{padding:"0.75rem 1.5rem",fontSize:"1.125rem"}}[a],...l},className:i,children:o})},x=({onSubmit:r,onCancel:t,onClearStorage:n,defaultDevRoles:a=[],currentToken:i=""})=>{const[s,l]=(0,o.useState)(!1),[d,c]=(0,o.useState)(""),[m,u]=(0,o.useState)({user:"usuario@bdsol.com.ar",roles:a,channel:"mf-testing",sessionId:crypto.randomUUID()}),[p,x]=(0,o.useState)(a.join("\n")),y=(e,o)=>{u(r=>({...r,[e]:o}))};return(0,e.jsx)("div",{style:{padding:"1.5rem",width:"100%",overflowY:"auto"},children:(0,e.jsx)(g,{style:{padding:"1.5rem"},children:(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)("h2",{style:{fontSize:"1.5rem",fontWeight:"bold",color:"#1F2937",marginBottom:"1rem"},children:"🔧 Generador de Tokens (Desarrollo)"}),(0,e.jsx)("p",{style:{color:"#6B7280",marginBottom:"1.5rem"},children:"Genera un token JWT para desarrollo usando el BFF. Solo disponible cuando ENVIRONMENT=dev."}),d&&(0,e.jsx)("div",{style:{marginBottom:"1rem",padding:"0.75rem",backgroundColor:"#FEE2E2",border:"1px solid #F87171",color:"#B91C1C",borderRadius:"0.25rem"},children:d}),(0,e.jsxs)("div",{style:{marginBottom:"1.5rem"},children:[(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Email del usuario"}),(0,e.jsx)("input",{type:"email",value:m.user,onChange:e=>y("user",e.target.value),style:{width:"100%",padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",outline:"none"},placeholder:"usuario@bdsol.com.ar"})]}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Roles (uno por línea)"}),(0,e.jsx)("textarea",{value:p,onChange:e=>x(e.target.value),style:{width:"100%",height:"8rem",padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",fontFamily:"monospace",fontSize:"0.875rem",outline:"none"},placeholder:a.join(" ")}),(0,e.jsx)("p",{style:{fontSize:"0.75rem",color:"#9CA3AF",marginTop:"0.25rem"},children:"Roles definidos en src/config/roles.ts"})]}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Channel"}),(0,e.jsx)("input",{type:"text",value:m.channel,onChange:e=>y("channel",e.target.value),style:{width:"100%",padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",outline:"none"},placeholder:"mf-testing"})]}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("label",{style:{display:"block",fontSize:"0.875rem",fontWeight:500,color:"#374151",marginBottom:"0.25rem"},children:"Session ID"}),(0,e.jsxs)("div",{style:{display:"flex",gap:"0.5rem"},children:[(0,e.jsx)("input",{type:"text",value:m.sessionId,onChange:e=>y("sessionId",e.target.value),style:{flex:1,padding:"0.5rem",border:"1px solid #D1D5DB",borderRadius:"0.5rem",fontFamily:"monospace",fontSize:"0.875rem",outline:"none"},placeholder:"uuid-session-id"}),(0,e.jsx)(h,{label:"🎲",variant:"primary",size:"small",onClick:()=>{u(e=>({...e,sessionId:crypto.randomUUID()}))},style:{padding:"0.5rem 0.75rem"}})]})]})]}),(0,e.jsxs)("div",{style:{display:"flex",gap:"0.75rem",flexWrap:"wrap",marginBottom:"1rem"},children:[(0,e.jsx)(h,{label:s?"Generando...":"🚀 Generar Token",variant:"primary",size:"small",onClick:async()=>{l(!0),c(""),n();try{const e=p.split("\n").map(e=>e.trim()).filter(e=>e.length>0),o={...m,roles:e},t=process.env.REACT_APP_API_URL||"http://localhost:3020",n=await fetch(`${t}/template/api/dev/generate-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){const e=await n.json();throw new Error(e.error||"Error al generar token")}const a=await n.json();r(a.token)}catch(e){c(e instanceof Error?e.message:"Error desconocido")}finally{l(!1)}},disabled:s||!m.user.trim()}),(0,e.jsx)(h,{label:"Limpiar almacenamiento",variant:"primary",size:"small",onClick:()=>{n(),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(h,{label:"Cancelar",size:"small",variant:"secondary",onClick:t})]}),i&&(0,e.jsxs)("div",{style:{marginTop:"1rem",padding:"1rem",backgroundColor:"#D1FAE5",borderRadius:"0.5rem"},children:[(0,e.jsx)("h3",{style:{fontWeight:600,color:"#047857",marginBottom:"0.5rem"},children:"✅ Token cargado"}),(0,e.jsx)("p",{style:{fontSize:"0.875rem",color:"#059669"},children:"Tienes un token activo en el almacenamiento local."})]})," "]})})})},y=({onSubmit:r,onCancel:t,onClearStorage:n,currentToken:a=""})=>{const[i,s]=(0,o.useState)(a),[l,d]=(0,o.useState)(!0);return(0,e.jsxs)("div",{style:{backgroundColor:"white",borderRadius:"0.5rem",boxShadow:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",padding:"1.5rem",width:"100%",maxWidth:"42rem"},children:[(0,e.jsx)("h2",{style:{fontSize:"1.5rem",fontWeight:"bold",color:"#1F2937",marginBottom:"1rem"},children:"Modo Desarrollo - Cargar Token JWT"}),(0,e.jsx)("p",{style:{color:"#6B7280",marginBottom:"1.5rem"},children:"Ingresa el token JWT decodificado (JSON) que normalmente recibiría desde el host:"}),(0,e.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,e.jsx)("textarea",{value:i,onChange:e=>{const o=e.target.value;s(o),l||d(!0)},placeholder:"Pegue aquí el token JWT en formato JSON",style:{width:"100%",height:"10rem",padding:"0.75rem",border:"1px solid "+(l?"#D1D5DB":"#F87171"),borderRadius:"0.5rem",fontFamily:"monospace",fontSize:"0.875rem",outline:"none"}}),!l&&(0,e.jsx)("p",{style:{color:"#EF4444",fontSize:"0.875rem",marginTop:"0.5rem"},children:"El JSON no es válido. Por favor verifica la sintaxis."})]}),(0,e.jsxs)("div",{style:{display:"flex",gap:"0.75rem",flexWrap:"wrap"},children:[(0,e.jsx)(h,{label:"Cargar Token",variant:"primary",size:"small",onClick:()=>{try{JSON.parse(i),d(!0),r(i)}catch(e){d(!1)}},disabled:!i.trim()}),(0,e.jsx)(h,{label:"Limpiar",size:"small",variant:"text",onClick:()=>s("")}),(0,e.jsx)(h,{label:"Limpiar Storage",variant:"primary",size:"small",onClick:()=>{n(),s(""),alert("SessionStorage limpiado correctamente")}}),(0,e.jsx)(h,{label:"Cancelar",variant:"secondary",size:"small",onClick:t})]})]})},f=({onClick:o})=>{const[r,t]=n().useState(!1),a={position:"fixed",bottom:"1.5rem",right:"1.5rem",background:"linear-gradient(to bottom right, #3B82F6, #1E40AF)",color:"white",padding:"1rem",borderRadius:"9999px",boxShadow:r?"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)":"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",transition:"all 0.3s",zIndex:50,transform:r?"scale(1.1)":"scale(1)",border:"none",cursor:"pointer"},i={position:"absolute",bottom:"100%",right:0,marginBottom:"0.75rem",padding:"0.25rem 0.75rem",fontSize:"0.75rem",color:"white",backgroundColor:"rgba(17, 24, 39, 0.9)",borderRadius:"0.5rem",opacity:r?1:0,transition:"opacity 0.2s",whiteSpace:"nowrap",backdropFilter:"blur(4px)",pointerEvents:"none"};return(0,e.jsxs)("button",{onClick:o,style:a,title:"Recargar Token",onMouseEnter:()=>t(!0),onMouseLeave:()=>t(!1),children:[(0,e.jsx)("svg",{style:{width:"1.25rem",height:"1.25rem"},fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,e.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"})}),(0,e.jsx)("span",{style:i,children:"Recargar Token"})]})},v=({children:r,defaultDevRoles:t=[]})=>{const[n,a]=(0,o.useState)(""),[i,s]=(0,o.useState)(!1),[l,d]=(0,o.useState)(!1),[c,m]=(0,o.useState)(!0),u="dev"===process.env.REACT_APP_ENVIRONMENT&&!n;(0,o.useEffect)(()=>{const e=p.tokenStorage.get();e?(a(e),d(!1)):u&&d(!0)},[u]);const g=e=>{console.log("🔄 DevWrapper: Nuevo token generado",{token:e.substring(0,50)+"..."}),a(e),p.tokenStorage.save(e),console.log("💾 DevWrapper: Token guardado en storage"),s(!1),d(!1)},h=()=>{p.tokenStorage.clear(),a(""),d(u)};return l?(0,e.jsx)("div",{style:{minHeight:"100vh",backgroundColor:"#F9FAFB",display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem"},children:(0,e.jsx)(x,{onSubmit:g,onCancel:()=>d(!1),onClearStorage:h,currentToken:n,defaultDevRoles:t})}):(0,e.jsxs)("div",{style:{minHeight:"100vh",backgroundColor:"#F9FAFB"},children:[i&&(0,e.jsx)("div",{style:{position:"fixed",inset:0,backgroundColor:"rgba(0, 0, 0, 0.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:50},children:(0,e.jsxs)("div",{style:{backgroundColor:"white",borderRadius:"0.5rem",boxShadow:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",maxWidth:"42rem",width:"100%",margin:"0 1rem",maxHeight:"90vh",overflowY:"auto"},children:[(0,e.jsxs)("div",{style:{display:"flex",borderBottom:"1px solid #E5E7EB"},children:[(0,e.jsx)("button",{onClick:()=>m(!0),style:{flex:1,padding:"0.75rem 1rem",fontSize:"0.875rem",fontWeight:500,backgroundColor:c?"#EFF6FF":"#F3F4F6",color:c?"#1E3A8A":"#4B5563",border:"none",cursor:"pointer"},children:"Generar Token"}),(0,e.jsx)("button",{onClick:()=>m(!1),style:{flex:1,padding:"0.75rem 1rem",fontSize:"0.875rem",fontWeight:500,backgroundColor:c?"#F3F4F6":"#EFF6FF",color:c?"#4B5563":"#1E3A8A",border:"none",cursor:"pointer"},children:"Input Manual"})]}),(0,e.jsx)("div",{style:{padding:0},children:c?(0,e.jsx)(x,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:h,currentToken:n,defaultDevRoles:t}):(0,e.jsx)("div",{style:{padding:"1.5rem"},children:(0,e.jsx)(y,{onSubmit:g,onCancel:()=>s(!1),onClearStorage:h,currentToken:n})})})]})}),(0,e.jsx)(f,{onClick:()=>{s(!i)}}),(0,e.jsx)(p.RemoteWrapper,{token:n,children:r})]})},k=()=>{const e=(0,o.useMemo)(()=>({react:{singleton:!0,eager:!1},"react-dom":{singleton:!0,eager:!1},"aurora-web":{singleton:!0,eager:!1},"react-i18next":{singleton:!0,eager:!1},i18next:{singleton:!0,eager:!1}}),[]);return{sharedDependencies:e,getWebpackConfig:(o,r)=>({name:o,filename:"remoteEntry.js",exposes:r,shared:e})}};var b=r(226)})(),module.exports=t})();
|
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@ interface DevButtonProps {
|
|
|
18
18
|
size?: ButtonSize;
|
|
19
19
|
className?: string;
|
|
20
20
|
type?: "button" | "submit" | "reset";
|
|
21
|
+
style?: React.CSSProperties;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
const DevButton: React.FC<DevButtonProps> = ({
|
|
@@ -28,22 +29,48 @@ const DevButton: React.FC<DevButtonProps> = ({
|
|
|
28
29
|
size = "medium",
|
|
29
30
|
className = "",
|
|
30
31
|
type = "button",
|
|
32
|
+
style,
|
|
31
33
|
}) => {
|
|
32
|
-
const baseStyles =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
text: "bg-transparent hover:bg-gray-10 text-blue-60 hover:text-blue-80 focus:ring-blue-30",
|
|
34
|
+
const baseStyles: React.CSSProperties = {
|
|
35
|
+
borderRadius: "0.5rem",
|
|
36
|
+
fontWeight: 500,
|
|
37
|
+
transition: "all 0.2s",
|
|
38
|
+
outline: "none",
|
|
39
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
40
|
+
opacity: disabled ? 0.5 : 1,
|
|
41
|
+
border: "none",
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const variantStyles: Record<ButtonVariant, React.CSSProperties> = {
|
|
45
|
+
primary: {
|
|
46
|
+
background: "linear-gradient(to bottom right, #3B82F6, #1E40AF)",
|
|
47
|
+
color: "white",
|
|
48
|
+
boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
|
49
|
+
},
|
|
50
|
+
secondary: {
|
|
51
|
+
backgroundColor: "#F3F4F6",
|
|
52
|
+
color: "#1F2937",
|
|
53
|
+
border: "1px solid #D1D5DB",
|
|
54
|
+
},
|
|
55
|
+
text: {
|
|
56
|
+
backgroundColor: "transparent",
|
|
57
|
+
color: "#2563EB",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const sizeStyles: Record<ButtonSize, React.CSSProperties> = {
|
|
62
|
+
small: {
|
|
63
|
+
padding: "0.5rem 1rem",
|
|
64
|
+
fontSize: "0.875rem",
|
|
65
|
+
},
|
|
66
|
+
medium: {
|
|
67
|
+
padding: "0.625rem 1.25rem",
|
|
68
|
+
fontSize: "1rem",
|
|
69
|
+
},
|
|
70
|
+
large: {
|
|
71
|
+
padding: "0.75rem 1.5rem",
|
|
72
|
+
fontSize: "1.125rem",
|
|
73
|
+
},
|
|
47
74
|
};
|
|
48
75
|
|
|
49
76
|
return (
|
|
@@ -51,7 +78,13 @@ const DevButton: React.FC<DevButtonProps> = ({
|
|
|
51
78
|
type={type}
|
|
52
79
|
onClick={onClick}
|
|
53
80
|
disabled={disabled}
|
|
54
|
-
|
|
81
|
+
style={{
|
|
82
|
+
...baseStyles,
|
|
83
|
+
...variantStyles[variant],
|
|
84
|
+
...sizeStyles[size],
|
|
85
|
+
...style,
|
|
86
|
+
}}
|
|
87
|
+
className={className}
|
|
55
88
|
>
|
|
56
89
|
{label}
|
|
57
90
|
</button>
|
|
@@ -10,13 +10,25 @@ import React from "react";
|
|
|
10
10
|
interface DevCardProps {
|
|
11
11
|
children: React.ReactNode;
|
|
12
12
|
className?: string;
|
|
13
|
+
style?: React.CSSProperties;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
const DevCard: React.FC<DevCardProps> = ({
|
|
16
|
+
const DevCard: React.FC<DevCardProps> = ({
|
|
17
|
+
children,
|
|
18
|
+
className = "",
|
|
19
|
+
style,
|
|
20
|
+
}) => {
|
|
21
|
+
const cardStyles: React.CSSProperties = {
|
|
22
|
+
backgroundColor: "white",
|
|
23
|
+
borderRadius: "0.5rem",
|
|
24
|
+
boxShadow:
|
|
25
|
+
"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
|
26
|
+
border: "1px solid #E5E7EB",
|
|
27
|
+
...style,
|
|
28
|
+
};
|
|
29
|
+
|
|
16
30
|
return (
|
|
17
|
-
<div
|
|
18
|
-
className={`bg-white rounded-lg shadow-md border border-gray-20 ${className}`}
|
|
19
|
-
>
|
|
31
|
+
<div style={cardStyles} className={className}>
|
|
20
32
|
{children}
|
|
21
33
|
</div>
|
|
22
34
|
);
|
|
@@ -6,9 +6,13 @@ import FloatingTokenButton from "./FloatingTokenButton";
|
|
|
6
6
|
|
|
7
7
|
interface DevWrapperProps {
|
|
8
8
|
children: React.ReactNode;
|
|
9
|
+
defaultDevRoles?: string[];
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
const DevWrapper: React.FC<DevWrapperProps> = ({
|
|
12
|
+
const DevWrapper: React.FC<DevWrapperProps> = ({
|
|
13
|
+
children,
|
|
14
|
+
defaultDevRoles = [],
|
|
15
|
+
}) => {
|
|
12
16
|
const [currentToken, setCurrentToken] = useState<string>("");
|
|
13
17
|
const [showTokenInput, setShowTokenInput] = useState<boolean>(false);
|
|
14
18
|
const [needsToken, setNeedsToken] = useState<boolean>(false);
|
|
@@ -52,57 +56,100 @@ const DevWrapper: React.FC<DevWrapperProps> = ({ children }) => {
|
|
|
52
56
|
// Si estamos en desarrollo, sin host y sin token, mostrar pantalla de generación
|
|
53
57
|
if (needsToken) {
|
|
54
58
|
return (
|
|
55
|
-
<div
|
|
59
|
+
<div
|
|
60
|
+
style={{
|
|
61
|
+
minHeight: "100vh",
|
|
62
|
+
backgroundColor: "#F9FAFB",
|
|
63
|
+
display: "flex",
|
|
64
|
+
alignItems: "center",
|
|
65
|
+
justifyContent: "center",
|
|
66
|
+
padding: "1rem",
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
56
69
|
<TokenGenerator
|
|
57
70
|
onSubmit={handleTokenSubmit}
|
|
58
71
|
onCancel={() => setNeedsToken(false)}
|
|
59
72
|
onClearStorage={handleClearStorage}
|
|
60
73
|
currentToken={currentToken}
|
|
74
|
+
defaultDevRoles={defaultDevRoles}
|
|
61
75
|
/>
|
|
62
76
|
</div>
|
|
63
77
|
);
|
|
64
78
|
}
|
|
65
79
|
|
|
66
80
|
return (
|
|
67
|
-
<div
|
|
81
|
+
<div style={{ minHeight: "100vh", backgroundColor: "#F9FAFB" }}>
|
|
68
82
|
{/* Token Input/Generator Modal */}
|
|
69
83
|
{showTokenInput && (
|
|
70
|
-
<div
|
|
71
|
-
|
|
84
|
+
<div
|
|
85
|
+
style={{
|
|
86
|
+
position: "fixed",
|
|
87
|
+
inset: 0,
|
|
88
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
89
|
+
display: "flex",
|
|
90
|
+
alignItems: "center",
|
|
91
|
+
justifyContent: "center",
|
|
92
|
+
zIndex: 50,
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
<div
|
|
96
|
+
style={{
|
|
97
|
+
backgroundColor: "white",
|
|
98
|
+
borderRadius: "0.5rem",
|
|
99
|
+
boxShadow:
|
|
100
|
+
"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
|
|
101
|
+
maxWidth: "42rem",
|
|
102
|
+
width: "100%",
|
|
103
|
+
margin: "0 1rem",
|
|
104
|
+
maxHeight: "90vh",
|
|
105
|
+
overflowY: "auto",
|
|
106
|
+
}}
|
|
107
|
+
>
|
|
72
108
|
{/* Tabs para cambiar entre generador y input manual */}
|
|
73
|
-
<div
|
|
109
|
+
<div style={{ display: "flex", borderBottom: "1px solid #E5E7EB" }}>
|
|
74
110
|
<button
|
|
75
111
|
onClick={() => setShowGenerator(true)}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
112
|
+
style={{
|
|
113
|
+
flex: 1,
|
|
114
|
+
padding: "0.75rem 1rem",
|
|
115
|
+
fontSize: "0.875rem",
|
|
116
|
+
fontWeight: 500,
|
|
117
|
+
backgroundColor: showGenerator ? "#EFF6FF" : "#F3F4F6",
|
|
118
|
+
color: showGenerator ? "#1E3A8A" : "#4B5563",
|
|
119
|
+
border: "none",
|
|
120
|
+
cursor: "pointer",
|
|
121
|
+
}}
|
|
81
122
|
>
|
|
82
123
|
Generar Token
|
|
83
124
|
</button>
|
|
84
125
|
<button
|
|
85
126
|
onClick={() => setShowGenerator(false)}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
127
|
+
style={{
|
|
128
|
+
flex: 1,
|
|
129
|
+
padding: "0.75rem 1rem",
|
|
130
|
+
fontSize: "0.875rem",
|
|
131
|
+
fontWeight: 500,
|
|
132
|
+
backgroundColor: !showGenerator ? "#EFF6FF" : "#F3F4F6",
|
|
133
|
+
color: !showGenerator ? "#1E3A8A" : "#4B5563",
|
|
134
|
+
border: "none",
|
|
135
|
+
cursor: "pointer",
|
|
136
|
+
}}
|
|
91
137
|
>
|
|
92
138
|
Input Manual
|
|
93
139
|
</button>
|
|
94
140
|
</div>
|
|
95
141
|
|
|
96
|
-
<div
|
|
142
|
+
<div style={{ padding: 0 }}>
|
|
97
143
|
{showGenerator ? (
|
|
98
144
|
<TokenGenerator
|
|
99
145
|
onSubmit={handleTokenSubmit}
|
|
100
146
|
onCancel={() => setShowTokenInput(false)}
|
|
101
147
|
onClearStorage={handleClearStorage}
|
|
102
148
|
currentToken={currentToken}
|
|
149
|
+
defaultDevRoles={defaultDevRoles}
|
|
103
150
|
/>
|
|
104
151
|
) : (
|
|
105
|
-
<div
|
|
152
|
+
<div style={{ padding: "1.5rem" }}>
|
|
106
153
|
<TokenInput
|
|
107
154
|
onSubmit={handleTokenSubmit}
|
|
108
155
|
onCancel={() => setShowTokenInput(false)}
|
|
@@ -7,14 +7,53 @@ interface FloatingTokenButtonProps {
|
|
|
7
7
|
const FloatingTokenButton: React.FC<FloatingTokenButtonProps> = ({
|
|
8
8
|
onClick,
|
|
9
9
|
}) => {
|
|
10
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
11
|
+
|
|
12
|
+
const buttonStyles: React.CSSProperties = {
|
|
13
|
+
position: "fixed",
|
|
14
|
+
bottom: "1.5rem",
|
|
15
|
+
right: "1.5rem",
|
|
16
|
+
background: "linear-gradient(to bottom right, #3B82F6, #1E40AF)",
|
|
17
|
+
color: "white",
|
|
18
|
+
padding: "1rem",
|
|
19
|
+
borderRadius: "9999px",
|
|
20
|
+
boxShadow: isHovered
|
|
21
|
+
? "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
|
|
22
|
+
: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
|
|
23
|
+
transition: "all 0.3s",
|
|
24
|
+
zIndex: 50,
|
|
25
|
+
transform: isHovered ? "scale(1.1)" : "scale(1)",
|
|
26
|
+
border: "none",
|
|
27
|
+
cursor: "pointer",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const tooltipStyles: React.CSSProperties = {
|
|
31
|
+
position: "absolute",
|
|
32
|
+
bottom: "100%",
|
|
33
|
+
right: 0,
|
|
34
|
+
marginBottom: "0.75rem",
|
|
35
|
+
padding: "0.25rem 0.75rem",
|
|
36
|
+
fontSize: "0.75rem",
|
|
37
|
+
color: "white",
|
|
38
|
+
backgroundColor: "rgba(17, 24, 39, 0.9)",
|
|
39
|
+
borderRadius: "0.5rem",
|
|
40
|
+
opacity: isHovered ? 1 : 0,
|
|
41
|
+
transition: "opacity 0.2s",
|
|
42
|
+
whiteSpace: "nowrap",
|
|
43
|
+
backdropFilter: "blur(4px)",
|
|
44
|
+
pointerEvents: "none",
|
|
45
|
+
};
|
|
46
|
+
|
|
10
47
|
return (
|
|
11
48
|
<button
|
|
12
49
|
onClick={onClick}
|
|
13
|
-
|
|
50
|
+
style={buttonStyles}
|
|
14
51
|
title="Recargar Token"
|
|
52
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
53
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
15
54
|
>
|
|
16
55
|
<svg
|
|
17
|
-
|
|
56
|
+
style={{ width: "1.25rem", height: "1.25rem" }}
|
|
18
57
|
fill="none"
|
|
19
58
|
stroke="currentColor"
|
|
20
59
|
viewBox="0 0 24 24"
|
|
@@ -26,9 +65,7 @@ const FloatingTokenButton: React.FC<FloatingTokenButtonProps> = ({
|
|
|
26
65
|
d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"
|
|
27
66
|
/>
|
|
28
67
|
</svg>
|
|
29
|
-
<span
|
|
30
|
-
{"Recargar Token"}
|
|
31
|
-
</span>
|
|
68
|
+
<span style={tooltipStyles}>{"Recargar Token"}</span>
|
|
32
69
|
</button>
|
|
33
70
|
);
|
|
34
71
|
};
|
|
@@ -101,79 +101,162 @@ const TokenGenerator: React.FC<TokenGeneratorProps> = ({
|
|
|
101
101
|
};
|
|
102
102
|
|
|
103
103
|
return (
|
|
104
|
-
<div
|
|
105
|
-
<DevCard
|
|
104
|
+
<div style={{ padding: "1.5rem", width: "100%", overflowY: "auto" }}>
|
|
105
|
+
<DevCard style={{ padding: "1.5rem" }}>
|
|
106
106
|
<>
|
|
107
|
-
<h2
|
|
107
|
+
<h2
|
|
108
|
+
style={{
|
|
109
|
+
fontSize: "1.5rem",
|
|
110
|
+
fontWeight: "bold",
|
|
111
|
+
color: "#1F2937",
|
|
112
|
+
marginBottom: "1rem",
|
|
113
|
+
}}
|
|
114
|
+
>
|
|
108
115
|
🔧 Generador de Tokens (Desarrollo)
|
|
109
116
|
</h2>
|
|
110
|
-
<p
|
|
117
|
+
<p style={{ color: "#6B7280", marginBottom: "1.5rem" }}>
|
|
111
118
|
Genera un token JWT para desarrollo usando el BFF. Solo disponible
|
|
112
119
|
cuando ENVIRONMENT=dev.
|
|
113
120
|
</p>
|
|
114
121
|
{error && (
|
|
115
|
-
<div
|
|
122
|
+
<div
|
|
123
|
+
style={{
|
|
124
|
+
marginBottom: "1rem",
|
|
125
|
+
padding: "0.75rem",
|
|
126
|
+
backgroundColor: "#FEE2E2",
|
|
127
|
+
border: "1px solid #F87171",
|
|
128
|
+
color: "#B91C1C",
|
|
129
|
+
borderRadius: "0.25rem",
|
|
130
|
+
}}
|
|
131
|
+
>
|
|
116
132
|
{error}
|
|
117
133
|
</div>
|
|
118
134
|
)}
|
|
119
|
-
<div
|
|
135
|
+
<div style={{ marginBottom: "1.5rem" }}>
|
|
120
136
|
{/* Email */}
|
|
121
|
-
<div>
|
|
122
|
-
<label
|
|
137
|
+
<div style={{ marginBottom: "1rem" }}>
|
|
138
|
+
<label
|
|
139
|
+
style={{
|
|
140
|
+
display: "block",
|
|
141
|
+
fontSize: "0.875rem",
|
|
142
|
+
fontWeight: 500,
|
|
143
|
+
color: "#374151",
|
|
144
|
+
marginBottom: "0.25rem",
|
|
145
|
+
}}
|
|
146
|
+
>
|
|
123
147
|
Email del usuario
|
|
124
148
|
</label>
|
|
125
149
|
<input
|
|
126
150
|
type="email"
|
|
127
151
|
value={formData.user}
|
|
128
152
|
onChange={(e) => handleInputChange("user", e.target.value)}
|
|
129
|
-
|
|
153
|
+
style={{
|
|
154
|
+
width: "100%",
|
|
155
|
+
padding: "0.5rem",
|
|
156
|
+
border: "1px solid #D1D5DB",
|
|
157
|
+
borderRadius: "0.5rem",
|
|
158
|
+
outline: "none",
|
|
159
|
+
}}
|
|
130
160
|
placeholder="usuario@bdsol.com.ar"
|
|
131
161
|
/>
|
|
132
162
|
</div>
|
|
133
163
|
|
|
134
164
|
{/* Roles */}
|
|
135
|
-
<div>
|
|
136
|
-
<label
|
|
165
|
+
<div style={{ marginBottom: "1rem" }}>
|
|
166
|
+
<label
|
|
167
|
+
style={{
|
|
168
|
+
display: "block",
|
|
169
|
+
fontSize: "0.875rem",
|
|
170
|
+
fontWeight: 500,
|
|
171
|
+
color: "#374151",
|
|
172
|
+
marginBottom: "0.25rem",
|
|
173
|
+
}}
|
|
174
|
+
>
|
|
137
175
|
Roles (uno por línea)
|
|
138
176
|
</label>
|
|
139
177
|
<textarea
|
|
140
178
|
value={rolesText}
|
|
141
179
|
onChange={(e) => setRolesText(e.target.value)}
|
|
142
|
-
|
|
180
|
+
style={{
|
|
181
|
+
width: "100%",
|
|
182
|
+
height: "8rem",
|
|
183
|
+
padding: "0.5rem",
|
|
184
|
+
border: "1px solid #D1D5DB",
|
|
185
|
+
borderRadius: "0.5rem",
|
|
186
|
+
fontFamily: "monospace",
|
|
187
|
+
fontSize: "0.875rem",
|
|
188
|
+
outline: "none",
|
|
189
|
+
}}
|
|
143
190
|
placeholder={defaultDevRoles.join(" ")}
|
|
144
191
|
/>
|
|
145
|
-
<p
|
|
192
|
+
<p
|
|
193
|
+
style={{
|
|
194
|
+
fontSize: "0.75rem",
|
|
195
|
+
color: "#9CA3AF",
|
|
196
|
+
marginTop: "0.25rem",
|
|
197
|
+
}}
|
|
198
|
+
>
|
|
146
199
|
Roles definidos en src/config/roles.ts
|
|
147
200
|
</p>
|
|
148
201
|
</div>
|
|
149
202
|
|
|
150
203
|
{/* Channel */}
|
|
151
|
-
<div>
|
|
152
|
-
<label
|
|
204
|
+
<div style={{ marginBottom: "1rem" }}>
|
|
205
|
+
<label
|
|
206
|
+
style={{
|
|
207
|
+
display: "block",
|
|
208
|
+
fontSize: "0.875rem",
|
|
209
|
+
fontWeight: 500,
|
|
210
|
+
color: "#374151",
|
|
211
|
+
marginBottom: "0.25rem",
|
|
212
|
+
}}
|
|
213
|
+
>
|
|
153
214
|
Channel
|
|
154
215
|
</label>
|
|
155
216
|
<input
|
|
156
217
|
type="text"
|
|
157
218
|
value={formData.channel}
|
|
158
219
|
onChange={(e) => handleInputChange("channel", e.target.value)}
|
|
159
|
-
|
|
220
|
+
style={{
|
|
221
|
+
width: "100%",
|
|
222
|
+
padding: "0.5rem",
|
|
223
|
+
border: "1px solid #D1D5DB",
|
|
224
|
+
borderRadius: "0.5rem",
|
|
225
|
+
outline: "none",
|
|
226
|
+
}}
|
|
160
227
|
placeholder="mf-testing"
|
|
161
228
|
/>
|
|
162
229
|
</div>
|
|
163
230
|
|
|
164
231
|
{/* Session ID */}
|
|
165
|
-
<div>
|
|
166
|
-
<label
|
|
232
|
+
<div style={{ marginBottom: "1rem" }}>
|
|
233
|
+
<label
|
|
234
|
+
style={{
|
|
235
|
+
display: "block",
|
|
236
|
+
fontSize: "0.875rem",
|
|
237
|
+
fontWeight: 500,
|
|
238
|
+
color: "#374151",
|
|
239
|
+
marginBottom: "0.25rem",
|
|
240
|
+
}}
|
|
241
|
+
>
|
|
167
242
|
Session ID
|
|
168
243
|
</label>
|
|
169
|
-
<div
|
|
244
|
+
<div style={{ display: "flex", gap: "0.5rem" }}>
|
|
170
245
|
<input
|
|
171
246
|
type="text"
|
|
172
247
|
value={formData.sessionId}
|
|
173
248
|
onChange={(e) =>
|
|
174
249
|
handleInputChange("sessionId", e.target.value)
|
|
175
250
|
}
|
|
176
|
-
|
|
251
|
+
style={{
|
|
252
|
+
flex: 1,
|
|
253
|
+
padding: "0.5rem",
|
|
254
|
+
border: "1px solid #D1D5DB",
|
|
255
|
+
borderRadius: "0.5rem",
|
|
256
|
+
fontFamily: "monospace",
|
|
257
|
+
fontSize: "0.875rem",
|
|
258
|
+
outline: "none",
|
|
259
|
+
}}
|
|
177
260
|
placeholder="uuid-session-id"
|
|
178
261
|
/>
|
|
179
262
|
<DevButton
|
|
@@ -181,12 +264,19 @@ const TokenGenerator: React.FC<TokenGeneratorProps> = ({
|
|
|
181
264
|
variant="primary"
|
|
182
265
|
size="small"
|
|
183
266
|
onClick={generateNewSessionId}
|
|
184
|
-
|
|
267
|
+
style={{ padding: "0.5rem 0.75rem" }}
|
|
185
268
|
/>
|
|
186
269
|
</div>
|
|
187
270
|
</div>
|
|
188
271
|
</div>
|
|
189
|
-
<div
|
|
272
|
+
<div
|
|
273
|
+
style={{
|
|
274
|
+
display: "flex",
|
|
275
|
+
gap: "0.75rem",
|
|
276
|
+
flexWrap: "wrap",
|
|
277
|
+
marginBottom: "1rem",
|
|
278
|
+
}}
|
|
279
|
+
>
|
|
190
280
|
<DevButton
|
|
191
281
|
label={loading ? "Generando..." : "🚀 Generar Token"}
|
|
192
282
|
variant="primary"
|
|
@@ -209,11 +299,24 @@ const TokenGenerator: React.FC<TokenGeneratorProps> = ({
|
|
|
209
299
|
</div>
|
|
210
300
|
{/* Información del token actual */}
|
|
211
301
|
{currentToken && (
|
|
212
|
-
<div
|
|
213
|
-
|
|
302
|
+
<div
|
|
303
|
+
style={{
|
|
304
|
+
marginTop: "1rem",
|
|
305
|
+
padding: "1rem",
|
|
306
|
+
backgroundColor: "#D1FAE5",
|
|
307
|
+
borderRadius: "0.5rem",
|
|
308
|
+
}}
|
|
309
|
+
>
|
|
310
|
+
<h3
|
|
311
|
+
style={{
|
|
312
|
+
fontWeight: 600,
|
|
313
|
+
color: "#047857",
|
|
314
|
+
marginBottom: "0.5rem",
|
|
315
|
+
}}
|
|
316
|
+
>
|
|
214
317
|
✅ Token cargado
|
|
215
318
|
</h3>
|
|
216
|
-
<p
|
|
319
|
+
<p style={{ fontSize: "0.875rem", color: "#059669" }}>
|
|
217
320
|
Tienes un token activo en el almacenamiento local.
|
|
218
321
|
</p>
|
|
219
322
|
</div>
|
|
@@ -44,32 +44,62 @@ const TokenInput: React.FC<TokenInputProps> = ({
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
return (
|
|
47
|
-
<div
|
|
48
|
-
|
|
47
|
+
<div
|
|
48
|
+
style={{
|
|
49
|
+
backgroundColor: "white",
|
|
50
|
+
borderRadius: "0.5rem",
|
|
51
|
+
boxShadow:
|
|
52
|
+
"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
|
|
53
|
+
padding: "1.5rem",
|
|
54
|
+
width: "100%",
|
|
55
|
+
maxWidth: "42rem",
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
<h2
|
|
59
|
+
style={{
|
|
60
|
+
fontSize: "1.5rem",
|
|
61
|
+
fontWeight: "bold",
|
|
62
|
+
color: "#1F2937",
|
|
63
|
+
marginBottom: "1rem",
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
49
66
|
Modo Desarrollo - Cargar Token JWT
|
|
50
67
|
</h2>
|
|
51
|
-
<p
|
|
68
|
+
<p style={{ color: "#6B7280", marginBottom: "1.5rem" }}>
|
|
52
69
|
Ingresa el token JWT decodificado (JSON) que normalmente recibiría desde
|
|
53
70
|
el host:
|
|
54
71
|
</p>
|
|
55
72
|
|
|
56
|
-
<div
|
|
73
|
+
<div style={{ marginBottom: "1rem" }}>
|
|
57
74
|
<textarea
|
|
58
75
|
value={token}
|
|
59
76
|
onChange={handleTextareaChange}
|
|
60
77
|
placeholder="Pegue aquí el token JWT en formato JSON"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
style={{
|
|
79
|
+
width: "100%",
|
|
80
|
+
height: "10rem",
|
|
81
|
+
padding: "0.75rem",
|
|
82
|
+
border: `1px solid ${!isValidJson ? "#F87171" : "#D1D5DB"}`,
|
|
83
|
+
borderRadius: "0.5rem",
|
|
84
|
+
fontFamily: "monospace",
|
|
85
|
+
fontSize: "0.875rem",
|
|
86
|
+
outline: "none",
|
|
87
|
+
}}
|
|
64
88
|
/>
|
|
65
89
|
{!isValidJson && (
|
|
66
|
-
<p
|
|
90
|
+
<p
|
|
91
|
+
style={{
|
|
92
|
+
color: "#EF4444",
|
|
93
|
+
fontSize: "0.875rem",
|
|
94
|
+
marginTop: "0.5rem",
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
67
97
|
El JSON no es válido. Por favor verifica la sintaxis.
|
|
68
98
|
</p>
|
|
69
99
|
)}
|
|
70
100
|
</div>
|
|
71
101
|
|
|
72
|
-
<div
|
|
102
|
+
<div style={{ display: "flex", gap: "0.75rem", flexWrap: "wrap" }}>
|
|
73
103
|
<DevButton
|
|
74
104
|
label="Cargar Token"
|
|
75
105
|
variant="primary"
|