xtra-cli 1.0.7 → 1.0.9
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/bin/xtra.js +2 -2
- package/dist/commands/access.js +1 -1
- package/dist/commands/admin.js +3 -3
- package/dist/commands/agent.js +4 -0
- package/dist/commands/audit.js +1 -1
- package/dist/commands/branch.js +1 -1
- package/dist/commands/checkout.js +1 -1
- package/dist/commands/ci.js +10 -10
- package/dist/commands/diff.js +6 -6
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/env.js +2 -2
- package/dist/commands/export.js +3 -2
- package/dist/commands/generate.js +3 -3
- package/dist/commands/history.js +4 -4
- package/dist/commands/import.js +1 -1
- package/dist/commands/init.js +4 -4
- package/dist/commands/integration.js +9 -9
- package/dist/commands/jit-run.js +5 -5
- package/dist/commands/local.js +5 -5
- package/dist/commands/login.js +6 -6
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logs.js +3 -3
- package/dist/commands/oidc-link.js +6 -0
- package/dist/commands/project.js +1 -1
- package/dist/commands/rollback.js +1 -1
- package/dist/commands/rotate.js +2 -2
- package/dist/commands/run.js +8 -6
- package/dist/commands/scan.js +13 -18
- package/dist/commands/secrets.js +6 -5
- package/dist/commands/service-account.js +5 -5
- package/dist/commands/simulate.js +5 -5
- package/dist/commands/status.js +2 -2
- package/dist/commands/template.js +9 -9
- package/dist/commands/ui.js +2 -2
- package/dist/commands/watch.js +13 -13
- package/dist/lib/api.js +1 -1
- package/dist/lib/audit.js +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/crypto.js +1 -1
- package/package.json +3 -3
- package/dist/commands/login.test.js +0 -16
- package/dist/lib/api.test.js +0 -1
- package/dist/lib/config.test.js +0 -1
package/dist/commands/secrets.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
var pe=Object.create;var E=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var I=(e,t)=>()=>(e&&(t=e(e=0)),t);var F=(e,t)=>{for(var r in t)E(e,r,{get:t[r],enumerable:!0})},V=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of de(t))!le.call(e,n)&&n!==r&&E(e,n,{get:()=>t[n],enumerable:!(s=ge(t,n))||s.enumerable});return e};var l=(e,t,r)=>(r=e!=null?pe(ue(e)):{},V(t||!e||!e.__esModule?E(r,"default",{value:e,enumerable:!0}):r,e)),R=e=>V(E({},"__esModule",{value:!0}),e);var M,T,H,_,y,J,S,C,G,z,U=I(()=>{M=l(require("conf")),T=l(require("fs")),H=l(require("path")),_="https://www.xtrasecurity.in/api",y=new M.default({projectName:"xtra-cli",defaults:{apiUrl:_}}),J=y.get("apiUrl");J&&!process.env.XTRA_API_URL&&J.includes("xtra-security.vercel.app")&&y.set("apiUrl",_);S=()=>({...y.store,apiUrl:process.env.XTRA_API_URL||y.get("apiUrl")||_}),C=e=>y.get(e),G=()=>y.get("token"),z=()=>{let e={};try{let t=H.default.join(process.cwd(),".xtrarc");T.default.existsSync(t)&&(e=JSON.parse(T.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||y.get("project")||"",env:e.env||y.get("env")||"development",branch:e.branch||y.get("branch")||"main"}}});var Y,X,W,fe,o,h,P=I(()=>{Y=l(require("axios"));U();X=l(require("fs")),W=l(require("path")),fe=JSON.parse(X.readFileSync(W.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=S(),t=G();return Y.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":fe.version,...t?{Authorization:`Bearer ${t}`}:{}}})},h={login:async(e,t,r)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,getSecrets:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data,getSecretVersions:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:r,expectedVersions:s,branch:n})).data,getSecretDetails:async(e,t,r,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,i)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:i})).data,rotateSecret:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=S(),r=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=S(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await o().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,r,s)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:r,expiresAt:s})).data,deleteServiceAccountKey:async(e,t,r)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${r}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});function re(){let e=Q.get("masterKey");e||(e=j.default.randomBytes(32).toString("hex"),Q.set("masterKey",e));let t=(0,ee.machineIdSync)();return j.default.createHash("sha256").update(e+t).digest()}var j,Z,ee,te,Q,se,ne,oe=I(()=>{j=l(require("crypto")),Z=l(require("conf")),ee=require("node-machine-id"),te="aes-256-gcm",Q=new Z.default({projectName:"xtra-cli-crypto"});se=e=>{let t=j.default.randomBytes(16),r=re(),s=j.default.createCipheriv(te,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let i=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:i.toString("hex")}},ne=e=>{let t=re(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=j.default.createDecipheriv(te,t,r);n.setAuthTag(s);let i=n.update(e.content,"hex","utf8");return i+=n.final("utf8"),i}});var b={};F(b,{loadAuditLogs:()=>O,logAudit:()=>me,saveAuditLogs:()=>D,syncAuditLogs:()=>he});function ye(e){if(!e||typeof e!="object")return e;let t={...e},r=["password","token","secret","value","apiKey","secretValue"];for(let s of Object.keys(t))r.some(n=>s.toLowerCase().includes(n))&&(t[s]="[REDACTED]");return t}async function ie(e){try{if(!S().token)return!1;let r={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:ye(e.details),timestamp:e.timestamp,projectId:e.projectId};return await h.post("/audit/cli-logs",{logs:[r]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function me(e,t,r,s){let n={id:(0,ce.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:r,details:s,synced:!1},i=O();i.push(n),D(i),ie(n).then(m=>{if(m){n.synced=!0;let g=O(),d=g.findIndex(c=>c.id===n.id);d!==-1&&(g[d].synced=!0,D(g))}}).catch(()=>{})}function O(){if(!x.default.existsSync(K))return[];try{let e=x.default.readFileSync(K,"utf-8"),t=JSON.parse(e),r=ne(t);return JSON.parse(r)}catch{return[]}}function D(e){x.default.existsSync(B)||x.default.mkdirSync(B,{recursive:!0});let t=JSON.stringify(e),r=se(t);x.default.writeFileSync(K,JSON.stringify(r),"utf-8")}async function he(){let e=O(),t=e.filter(s=>!s.synced);if(t.length===0)return 0;let r=0;for(let s of t)await ie(s)&&(s.synced=!0,r++);return r>0&&D(e),r}var x,N,ce,B,K,$=I(()=>{x=l(require("fs")),N=l(require("path")),ce=require("uuid");oe();U();P();B=N.default.join(process.cwd(),".xtra"),K=N.default.join(B,"audit.enc")});var ve={};F(ve,{secretsCommand:()=>v});module.exports=R(ve);var ae=require("commander");P();var a=l(require("chalk")),k=l(require("ora")),q=require("table");U();var v=new ae.Command("secrets").description("Manage secrets (List, Set, Delete)").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Environment (development, staging, production)","development").option("-b, --branch <branchName>","Branch Name");v.command("list").description("List all secrets for a project/environment").option("--show","Reveal secret values",!1).addHelpText("after",`
|
|
1
|
+
var ve=Object.create;var L=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var xe=Object.getOwnPropertyNames;var we=Object.getPrototypeOf,be=Object.prototype.hasOwnProperty;var V=(e,t)=>()=>(e&&(t=e(e=0)),t);var D=(e,t)=>{for(var r in t)L(e,r,{get:t[r],enumerable:!0})},re=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of xe(t))!be.call(e,n)&&n!==r&&L(e,n,{get:()=>t[n],enumerable:!(s=Se(t,n))||s.enumerable});return e};var h=(e,t,r)=>(r=e!=null?ve(we(e)):{},re(t||!e||!e.__esModule?L(r,"default",{value:e,enumerable:!0}):r,e)),j=e=>re(L({},"__esModule",{value:!0}),e);var X={};D(X,{createWorkloadKeyEnvelope:()=>Te,decrypt:()=>H,decryptSecretValue:()=>Ae,decryptWorkloadKeyEnvelope:()=>Re,deriveProjectKey:()=>ke,encrypt:()=>F,encryptSecretValue:()=>$e,hash:()=>je,resolveVaultPassphrase:()=>ce,saveVaultPassphrase:()=>Ee,secureRead:()=>P,secureSave:()=>R});function ie(){if(N)return N;let e=q.get("masterKey");e||(e=d.default.randomBytes(32).toString("hex"),q.set("masterKey",e));let t="";try{t=(0,ne.machineIdSync)()||""}catch{t=d.default.createHash("sha256").update(w.default.hostname()+(w.default.userInfo?.()?.username||"root")).digest("hex")}let r=w.default.platform(),s=w.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return N=d.default.createHash("sha256").update(n).digest(),N}function ke(e,t){t||(t=ce(void 0,e));let r=Buffer.from(`project_salt_${e}`),s=Buffer.from("xtra-e2ee-project-key-v2"),n=d.default.hkdfSync("sha256",Buffer.from(t),r,s,32);return Buffer.from(n).toString("hex")}function $e(e,t){let r=d.default.randomBytes(12),s=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=d.default.createCipheriv("aes-256-gcm",s,r),i=n.update(e,"utf8","hex");i+=n.final("hex");let f=n.getAuthTag().toString("hex");return{ciphertext:i,iv:r.toString("hex"),authTag:f}}function Ae(e,t){let r=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.authTag,"hex"),i=d.default.createDecipheriv("aes-256-gcm",r,s);i.setAuthTag(n);let f=i.update(e.ciphertext,"hex","utf8");return f+=i.final("utf8"),f}function ce(e,t){if(e&&e.trim())return e.trim();if(process.env.XTRA_VAULT_PASSPHRASE&&process.env.XTRA_VAULT_PASSPHRASE.trim())return process.env.XTRA_VAULT_PASSPHRASE.trim();if(process.env.XTRA_MASTER_SECRET&&process.env.XTRA_MASTER_SECRET.trim())return process.env.XTRA_MASTER_SECRET.trim();try{if(t){let s=P(`vault_${t}`);if(s)return s}let r=P("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(_(),j(ae)),s=r();if(s&&s.passphrase)return s.passphrase}catch{}throw new Error("Vault Passphrase or Master Secret is required for Zero-Knowledge E2EE encryption/decryption.")}function Ee(e,t){t&&R(`vault_${t}`,e),R("vault_passphrase",e)}function Te(e,t){let{publicKey:r,privateKey:s}=d.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),i=d.default.createPublicKey(t),f=d.default.diffieHellman({privateKey:s,publicKey:i}),p=Buffer.from(d.default.hkdfSync("sha256",f,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),a=d.default.randomBytes(12),c=d.default.createCipheriv("aes-256-gcm",p,a),g=c.update(e,"utf8","hex");g+=c.final("hex");let l=c.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:g,iv:a.toString("hex"),authTag:l}}function Re(e,t){let r=d.default.createPrivateKey(t),s=d.default.createPublicKey(e.ephemeralPublicKey),n=d.default.diffieHellman({privateKey:r,publicKey:s}),i=Buffer.from(d.default.hkdfSync("sha256",n,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),f=Buffer.from(e.iv,"hex"),p=Buffer.from(e.authTag,"hex"),a=d.default.createDecipheriv("aes-256-gcm",i,f);a.setAuthTag(p);let c=a.update(e.encryptedProjectKey,"hex","utf8");return c+=a.final("utf8"),c}var d,w,se,ne,T,oe,q,N,F,H,je,R,P,K=V(()=>{d=h(require("crypto")),w=h(require("os")),se=h(require("conf")),ne=require("node-machine-id"),T=require("child_process"),oe="aes-256-gcm",q=new se.default({projectName:"xtra-cli-crypto"}),N=null;F=e=>{let t=d.default.randomBytes(12),r=ie(),s=d.default.createCipheriv(oe,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let i=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:i.toString("hex")}},H=e=>{let t=ie(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=d.default.createDecipheriv(oe,t,r);n.setAuthTag(s);let i=n.update(e.content,"hex","utf8");return i+=n.final("utf8"),i},je=e=>d.default.createHash("sha256").update(e).digest("hex"),R=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if(w.default.platform()==="darwin"){(0,T.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if(w.default.platform()!=="win32"){if(w.default.platform()==="linux")try{(0,T.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=F(t);q.set(`secure_${e}`,JSON.stringify(r))},P=e=>{try{let t="XtraSecurityCLI",r=e;if(w.default.platform()==="darwin")return(0,T.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(w.default.platform()!=="win32"){if(w.default.platform()==="linux")try{return(0,T.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=q.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return H(r)}catch{return null}}});var ae={};D(ae,{clearConfig:()=>Ke,deleteConfig:()=>_e,getAuthToken:()=>C,getBreakGlassSession:()=>Ie,getConfig:()=>$,getConfigValue:()=>I,getProjectConfig:()=>Oe,getRcConfig:()=>Y,setBreakGlassSession:()=>Ce,setConfig:()=>Pe});var ge,k,W,G,y,pe,$,I,Pe,Ke,_e,C,Ie,Ce,Oe,Y,_=V(()=>{ge=h(require("conf")),k=h(require("fs")),W=h(require("path"));K();G="https://www.xtrasecurity.in/api",y=new ge.default({projectName:"xtra-cli",defaults:{apiUrl:G}}),pe=y.get("apiUrl");pe&&!process.env.XTRA_API_URL&&pe.includes("xtra-security.vercel.app")&&y.set("apiUrl",G);$=()=>({...y.store,token:C(),apiUrl:process.env.XTRA_API_URL||y.get("apiUrl")||G}),I=e=>e==="token"?C():y.get(e),Pe=(e,t)=>{if(e==="token"&&t&&R("token",t),y.set(e,t),e==="token"&&process.platform!=="win32"&&k.default.existsSync(y.path))try{k.default.chmodSync(y.path,384)}catch{}},Ke=()=>y.clear(),_e=e=>y.delete(e),C=()=>P("token")||y.get("token"),Ie=()=>y.get("breakGlassSessionId"),Ce=e=>{e?y.set("breakGlassSessionId",e):y.delete("breakGlassSessionId")},Oe=async()=>{try{let e=W.default.join(process.cwd(),"xtra.json");if(k.default.existsSync(e)){let t=k.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},Y=()=>{let e={};try{let t=W.default.join(process.cwd(),".xtrarc");k.default.existsSync(t)&&(e=JSON.parse(k.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||y.get("project")||"",env:e.env||y.get("env")||"development",branch:e.branch||y.get("branch")||"main"}}});var ue,de,le,Ue,o,b,z=V(()=>{ue=h(require("axios"));_();de=h(require("fs")),le=h(require("path")),Ue=JSON.parse(de.readFileSync(le.join(__dirname,"../../package.json"),"utf-8")),o=e=>{let{apiUrl:t}=$(),r=e||C();return ue.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Ue.version,...r?{Authorization:`Bearer ${r}`}:{}}})},b={login:async(e,t,r)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,exchangeOidcToken:async(e,t)=>{let r=await o().post("/v2/auth/oidc/token",{provider:e,token:t});return{accessToken:r.data.access_token,envelope:r.data.envelope}},spawnAgentContext:async e=>(await o().post("/agents/ephemeral-context",e)).data,getSecrets:async(e,t,r="main",s,n,i)=>{let p=(await o(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(p&&typeof p=="object"){let a=null,{deriveProjectKey:c,decryptSecretValue:g,resolveVaultPassphrase:l,decryptWorkloadKeyEnvelope:m}=(K(),j(X));for(let[x,v]of Object.entries(p))if(typeof v=="string"&&v.startsWith("{"))try{let S=JSON.parse(v);if(S.ciphertext&&S.iv){if(!a)if(i&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)a=m(i,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let he=l(s,e);a=c(e,he)}p[x]=g(S,a)}}catch(S){if(S.message&&S.message.includes("Zero-Knowledge"))throw S}}return p},getSecretVersions:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>{let{deriveProjectKey:i,encryptSecretValue:f,resolveVaultPassphrase:p}=(K(),j(X)),a=p(void 0,e),c=i(e,a),g={};for(let[m,x]of Object.entries(r))if(typeof x=="string"&&x.startsWith("{")&&x.includes("ciphertext"))g[m]=x;else{let v=f(x,c);g[m]=JSON.stringify(v)}return(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:g,expectedVersions:s,branch:n})).data},getSecretDetails:async(e,t,r,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,getSecretsV2:async(e,t)=>{let r=t?`&branchId=${t}`:"";return(await o().get(`/v2/secret?projectId=${e}${r}`)).data},createSecretV2:async e=>(await o().post("/v2/secret",e)).data,updateSecretV2:async e=>(await o().put(`/v2/secret?id=${e.id}`,e)).data,deleteSecretV2:async e=>(await o().delete(`/v2/secret?id=${e}`)).data,bulkImportV2:async e=>(await o().post("/v2/secret/bulk",e)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,i)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:i})).data,rotateSecret:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=$(),r=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=$(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await o().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,r,s)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:r,expiresAt:s})).data,deleteServiceAccountKey:async(e,t,r)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${r}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});var O={};D(O,{loadAuditLogs:()=>J,logAudit:()=>Le,saveAuditLogs:()=>M,syncAuditLogs:()=>Ve});function Be(e){if(!e||typeof e!="object")return e;let t={...e},r=["password","token","secret","value","apiKey","secretValue"];for(let s of Object.keys(t))r.some(n=>s.toLowerCase().includes(n))&&(t[s]="[REDACTED]");return t}async function ye(e){try{if(!$().token)return!1;let r={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:Be(e.details),timestamp:e.timestamp,projectId:e.projectId};return await b.post("/audit/cli-logs",{logs:[r]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function Le(e,t,r,s){let n={id:(0,fe.randomUUID)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:r,details:s,synced:!1},i=J();i.push(n),M(i),ye(n).then(f=>{if(f){n.synced=!0;let p=J(),a=p.findIndex(c=>c.id===n.id);a!==-1&&(p[a].synced=!0,M(p))}}).catch(()=>{})}function J(){if(!E.default.existsSync(Q))return[];try{let e=E.default.readFileSync(Q,"utf-8"),t=JSON.parse(e),r=H(t);return JSON.parse(r)}catch{return[]}}function M(e){E.default.existsSync(Z)||E.default.mkdirSync(Z,{recursive:!0});let t=JSON.stringify(e),r=F(t);E.default.writeFileSync(Q,JSON.stringify(r),"utf-8")}async function Ve(){let e=J(),t=e.filter(s=>!s.synced);if(t.length===0)return 0;let r=0;for(let s of t)await ye(s)&&(s.synced=!0,r++);return r>0&&M(e),r}var E,ee,fe,Z,Q,U=V(()=>{E=h(require("fs")),ee=h(require("path")),fe=require("crypto");K();_();z();Z=ee.default.join(process.cwd(),".xtra"),Q=ee.default.join(Z,"audit.enc")});var De={};D(De,{secretsCommand:()=>A});module.exports=j(De);var me=require("commander");z();var u=h(require("chalk")),B=h(require("ora")),te=require("table");_();var A=new me.Command("secrets").description("Manage secrets (List, Set, Delete)").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Environment (development, staging, production)","development").option("-b, --branch <branchName>","Branch Name").option("--passphrase <passphrase>","Vault passphrase for Level 3 Zero-Knowledge decryption");A.command("list").description("List all secrets for a project/environment").option("--show","Reveal secret values",!1).option("--passphrase <passphrase>","Vault passphrase for Level 3 Zero-Knowledge decryption").addHelpText("after",`
|
|
2
2
|
Examples:
|
|
3
3
|
$ xtra secrets list
|
|
4
4
|
$ xtra secrets list -e production --show
|
|
5
|
-
`).action(async e=>{let t=
|
|
5
|
+
`).action(async e=>{let t=A.opts(),{project:r,env:s,branch:n}=t,i=Y();r||(r=i.project),n||(n=i.branch),(!s||s==="development")&&(s=i.env),s={dev:"development",stg:"staging",prod:"production"}[s]||s;let{show:p}=e;r||(console.error(u.default.red("Error: Project ID is required. Use -p <id> or run `xtra init` first.")),process.exit(1));let a=(0,B.default)(`Fetching secrets for ${s} (branch: ${n})...`).start();try{let c=await b.getSecrets(r,s,n,e.passphrase||t.passphrase);if(a.stop(),!c||Object.keys(c).length===0){console.log(u.default.yellow("No secrets found."));return}p&&console.log(u.default.red("\u26A0 Warning: Secret values will be visible in your terminal and shell history!"));let g=[[u.default.bold("Key"),u.default.bold("Value"),u.default.bold("Env")]];Object.entries(c).forEach(([l,m])=>{g.push([l,p?m:"********",s])}),console.log((0,te.table)(g));try{let{logAudit:l}=await Promise.resolve().then(()=>(U(),O));l("SECRET_LIST",r,s,{branch:n,count:Object.keys(c).length})}catch{}}catch(c){a.fail("Failed to fetch secrets"),c.message&&c.message.includes("Zero-Knowledge")?(console.error(u.default.red(`
|
|
6
|
+
[Decryption Error] `+c.message)),console.log(u.default.yellow("Hint: Use 'xtra project set' to save your passphrase, or pass it using --passphrase"))):console.error(u.default.red(c?.response?.data?.error||"An unexpected error occurred"))}});A.command("set").description("Set one or more secrets (KEY=VALUE)").argument("<secrets...>","Secrets to set (format: KEY=VALUE)").option("-f, --force","Force update (overwrite remote changes without warning)",!1).addHelpText("after",`
|
|
6
7
|
Examples:
|
|
7
8
|
$ xtra secrets set API_KEY=xyz
|
|
8
9
|
$ xtra secrets set DB_USER=admin DB_PASS=secret -e staging
|
|
9
|
-
`).action(async(e,t)=>{let r=
|
|
10
|
+
`).action(async(e,t)=>{let r=A.opts(),{project:s,env:n,branch:i}=r;i||(i=I("branch")||"main"),n={dev:"development",stg:"staging",prod:"production"}[n]||n,s||(s=I("project")),s||(console.error(u.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let p={};if(e.forEach(c=>{let g=c.indexOf("=");if(g===-1){console.warn(u.default.yellow(`Skipping invalid format: ${c} (expected KEY=VALUE)`));return}let l=c.substring(0,g),m=c.substring(g+1);p[l]=m}),Object.keys(p).length===0){console.error(u.default.red("No valid secrets provided."));return}if(n==="production"&&!t.force){let c=require("inquirer"),{confirm:g}=await c.prompt([{type:"confirm",name:"confirm",message:u.default.red(`\u26A0 You are about to SET ${Object.keys(p).length} secret(s) in PRODUCTION. Are you sure?`),default:!1}]);if(!g){console.log(u.default.yellow("Aborted."));return}}let a=(0,B.default)(`Setting ${Object.keys(p).length} secrets for ${n} (branch: ${i})...`);t.force&&a.start();try{let c;if(!t.force){a.text="Fetching current versions...",a.start();try{let g=await b.getSecretVersions(s,n,i);c={},a.stop(),Object.keys(p).forEach(l=>{g[l]&&(c[l]=g[l].version)})}catch{a.warn(u.default.yellow("Could not fetch remote versions. Conflict detection disabled."))}}a.start("Updating secrets..."),await b.setSecrets(s,n,p,c,i),a.succeed("Secrets updated successfully.");try{let{logAudit:g}=(U(),j(O));g("SECRET_UPDATE",s,n,{keys:Object.keys(p),branch:i})}catch{}}catch(c){if(a.stop(),c.response&&c.response.status===409){let g=c.response.data.conflicts||[];console.log(u.default.red(`
|
|
10
11
|
\u26A0 Conflict Detected! The following secrets have changed remotely:
|
|
11
|
-
`));let
|
|
12
|
+
`));let l=[[u.default.bold("Key"),u.default.bold("Remote Version"),u.default.bold("Remote Value")]];g.forEach(v=>{l.push([v.key,v.actual,v.remoteValue])}),console.log((0,te.table)(l));let m=require("inquirer"),{confirm:x}=await m.prompt([{type:"confirm",name:"confirm",message:"Do you want to overwrite these changes exactly as you specified?",default:!1}]);if(x){let v=(0,B.default)("Overwriting secrets...").start();try{await b.setSecrets(s,n,p,void 0,i),v.succeed("Secrets overwritten successfully.");try{let{logAudit:S}=(U(),j(O));S("SECRET_UPDATE_FORCE",s,n,{keys:Object.keys(p),branch:i})}catch{}}catch(S){v.fail("Failed to overwrite secrets."),console.error(u.default.red(S.message))}}else console.log(u.default.yellow("Update cancelled."));return}a.isSpinning&&a.fail("Failed to update secrets"),c.response&&c.response.data&&c.response.data.error?console.error(u.default.red(`Server Error: ${c.response.data.error}`)):console.error(u.default.red(c?.response?.data?.error||"An unexpected error occurred"))}});A.command("link").description("Link a secret to another secret (Reference)").argument("<key>","Key of the secret to create (e.g. DB_URL)").requiredOption("--source <source>","Source path (format: project/env/key)").addHelpText("after",`
|
|
12
13
|
Examples:
|
|
13
14
|
$ xtra secrets link SHARED_DB_URL --source shared-proj/production/DB_URL
|
|
14
|
-
`).action(async(e,t)=>{let r=
|
|
15
|
+
`).action(async(e,t)=>{let r=A.opts(),{project:s,env:n}=r;n={dev:"development",stg:"staging",prod:"production"}[n]||n;let{source:f}=t;s||(s=I("project")),s||(console.error(u.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let p=f.split("/");if(p.length!==3){console.error(u.default.red("Error: Source must be in format 'projectId/env/key'"));return}let[a,c,g]=p,l=(0,B.default)(`Linking ${e} to ${f}...`).start();try{await b.linkSecret(s,n,e,a,c,g),l.succeed(u.default.green(`Secret '${e}' successfully linked to '${g}'`));try{let{logAudit:m}=(U(),j(O));m("SECRET_LINKED",s,n,{key:e,source:f})}catch{}}catch(m){l.fail("Failed to link secret");let x=m?.response?.data?.error||m?.response?.data?.error||"An unexpected error occurred";console.error(u.default.red(`Server Error: ${x}`))}});0&&(module.exports={secretsCommand});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var C=Object.create;var m=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var N=(e,t)=>{for(var s in t)m(e,s,{get:t[s],enumerable:!0})},j=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of P(t))!L.call(e,n)&&n!==s&&m(e,n,{get:()=>t[n],enumerable:!(r=D(t,n))||r.enumerable});return e};var p=(e,t,s)=>(s=e!=null?C(R(e)):{},j(t||!e||!e.__esModule?m(s,"default",{value:e,enumerable:!0}):s,e)),K=e=>j(m({},"__esModule",{value:!0}),e);var _={};N(_,{serviceAccountCommand:()=>d});module.exports=K(_);var A=require("commander");var b=p(require("axios"));var $=p(require("conf"));var w="https://www.xtrasecurity.in/api",u=new $.default({projectName:"xtra-cli",defaults:{apiUrl:w}}),h=u.get("apiUrl");h&&!process.env.XTRA_API_URL&&h.includes("xtra-security.vercel.app")&&u.set("apiUrl",w);var f=()=>({...u.store,apiUrl:process.env.XTRA_API_URL||u.get("apiUrl")||w}),k=e=>u.get(e);var S=()=>u.get("token");var I=p(require("fs")),x=p(require("path")),T=JSON.parse(I.readFileSync(x.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=f(),t=S();return b.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":T.version,...t?{Authorization:`Bearer ${t}`}:{}}})},g={login:async(e,t,s)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,n="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:n})).data,getSecretDetails:async(e,t,s,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,n,c)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:n,sourceKey:c})).data,rotateSecret:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:n})).data,promoteSecret:async(e,t,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let n={format:e};return t&&(n.startDate=t),s&&(n.endDate=s),r&&(n.projectId=r),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await o().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=f(),s=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=f(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await o().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,r)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:r})).data,deleteServiceAccountKey:async(e,t,s)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await o().post(e,t)).data};var a=p(require("chalk")),l=p(require("ora")),v=require("table");var U=p(require("inquirer")),d=new A.Command("service-account").alias("sa").description("Manage service accounts and machine tokens"),y=e=>{let t=e.project||k("project");return t||(console.error(a.default.red("\u2716 Error: No project specified.")),console.log(a.default.yellow(" Use --project <id> or run 'xtra project set' first.")),process.exit(1)),t};d.command("list").alias("ls").description("List all service accounts in a project").option("-p, --project <id>","Project ID").action(async e=>{let t=y(e),s=(0,l.default)("Fetching service accounts...").start();try{let r=await g.getServiceAccounts(t);if(s.stop(),!r||r.length===0){console.log(a.default.yellow("No service accounts found for this project."));return}console.log(a.default.bold(`
|
|
1
|
+
var ie=Object.create;var _=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var F=(e,t)=>()=>(e&&(t=e(e=0)),t);var L=(e,t)=>{for(var r in t)_(e,r,{get:t[r],enumerable:!0})},q=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ge(t))!le.call(e,n)&&n!==r&&_(e,n,{get:()=>t[n],enumerable:!(s=pe(t,n))||s.enumerable});return e};var l=(e,t,r)=>(r=e!=null?ie(ue(e)):{},q(t||!e||!e.__esModule?_(r,"default",{value:e,enumerable:!0}):r,e)),E=e=>q(_({},"__esModule",{value:!0}),e);var N={};L(N,{createWorkloadKeyEnvelope:()=>ve,decrypt:()=>Z,decryptSecretValue:()=>he,decryptWorkloadKeyEnvelope:()=>we,deriveProjectKey:()=>ye,encrypt:()=>Y,encryptSecretValue:()=>fe,hash:()=>de,resolveVaultPassphrase:()=>z,saveVaultPassphrase:()=>me,secureRead:()=>P,secureSave:()=>A});function M(){if(C)return C;let e=B.get("masterKey");e||(e=i.default.randomBytes(32).toString("hex"),B.set("masterKey",e));let t="";try{t=(0,W.machineIdSync)()||""}catch{t=i.default.createHash("sha256").update(y.default.hostname()+(y.default.userInfo?.()?.username||"root")).digest("hex")}let r=y.default.platform(),s=y.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return C=i.default.createHash("sha256").update(n).digest(),C}function ye(e,t){t||(t=z(void 0,e));let r=Buffer.from(`project_salt_${e}`),s=Buffer.from("xtra-e2ee-project-key-v2"),n=i.default.hkdfSync("sha256",Buffer.from(t),r,s,32);return Buffer.from(n).toString("hex")}function fe(e,t){let r=i.default.randomBytes(12),s=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=i.default.createCipheriv("aes-256-gcm",s,r),o=n.update(e,"utf8","hex");o+=n.final("hex");let p=n.getAuthTag().toString("hex");return{ciphertext:o,iv:r.toString("hex"),authTag:p}}function he(e,t){let r=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.authTag,"hex"),o=i.default.createDecipheriv("aes-256-gcm",r,s);o.setAuthTag(n);let p=o.update(e.ciphertext,"hex","utf8");return p+=o.final("utf8"),p}function z(e,t){if(e&&e.trim())return e.trim();if(process.env.XTRA_VAULT_PASSPHRASE&&process.env.XTRA_VAULT_PASSPHRASE.trim())return process.env.XTRA_VAULT_PASSPHRASE.trim();if(process.env.XTRA_MASTER_SECRET&&process.env.XTRA_MASTER_SECRET.trim())return process.env.XTRA_MASTER_SECRET.trim();try{if(t){let s=P(`vault_${t}`);if(s)return s}let r=P("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(D(),E(Q)),s=r();if(s&&s.passphrase)return s.passphrase}catch{}throw new Error("Vault Passphrase or Master Secret is required for Zero-Knowledge E2EE encryption/decryption.")}function me(e,t){t&&A(`vault_${t}`,e),A("vault_passphrase",e)}function ve(e,t){let{publicKey:r,privateKey:s}=i.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),o=i.default.createPublicKey(t),p=i.default.diffieHellman({privateKey:s,publicKey:o}),d=Buffer.from(i.default.hkdfSync("sha256",p,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),u=i.default.randomBytes(12),f=i.default.createCipheriv("aes-256-gcm",d,u),h=f.update(e,"utf8","hex");h+=f.final("hex");let I=f.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:h,iv:u.toString("hex"),authTag:I}}function we(e,t){let r=i.default.createPrivateKey(t),s=i.default.createPublicKey(e.ephemeralPublicKey),n=i.default.diffieHellman({privateKey:r,publicKey:s}),o=Buffer.from(i.default.hkdfSync("sha256",n,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),p=Buffer.from(e.iv,"hex"),d=Buffer.from(e.authTag,"hex"),u=i.default.createDecipheriv("aes-256-gcm",o,p);u.setAuthTag(d);let f=u.update(e.encryptedProjectKey,"hex","utf8");return f+=u.final("utf8"),f}var i,y,G,W,b,J,B,C,Y,Z,de,A,P,U=F(()=>{i=l(require("crypto")),y=l(require("os")),G=l(require("conf")),W=require("node-machine-id"),b=require("child_process"),J="aes-256-gcm",B=new G.default({projectName:"xtra-cli-crypto"}),C=null;Y=e=>{let t=i.default.randomBytes(12),r=M(),s=i.default.createCipheriv(J,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let o=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:o.toString("hex")}},Z=e=>{let t=M(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=i.default.createDecipheriv(J,t,r);n.setAuthTag(s);let o=n.update(e.content,"hex","utf8");return o+=n.final("utf8"),o},de=e=>i.default.createHash("sha256").update(e).digest("hex"),A=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if(y.default.platform()==="darwin"){(0,b.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if(y.default.platform()!=="win32"){if(y.default.platform()==="linux")try{(0,b.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=Y(t);B.set(`secure_${e}`,JSON.stringify(r))},P=e=>{try{let t="XtraSecurityCLI",r=e;if(y.default.platform()==="darwin")return(0,b.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(y.default.platform()!=="win32"){if(y.default.platform()==="linux")try{return(0,b.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=B.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return Z(r)}catch{return null}}});var Q={};L(Q,{clearConfig:()=>xe,deleteConfig:()=>ke,getAuthToken:()=>T,getBreakGlassSession:()=>je,getConfig:()=>K,getConfigValue:()=>H,getProjectConfig:()=>be,getRcConfig:()=>Ae,setBreakGlassSession:()=>$e,setConfig:()=>Se});var te,w,V,O,g,ee,K,H,Se,xe,ke,T,je,$e,be,Ae,D=F(()=>{te=l(require("conf")),w=l(require("fs")),V=l(require("path"));U();O="https://www.xtrasecurity.in/api",g=new te.default({projectName:"xtra-cli",defaults:{apiUrl:O}}),ee=g.get("apiUrl");ee&&!process.env.XTRA_API_URL&&ee.includes("xtra-security.vercel.app")&&g.set("apiUrl",O);K=()=>({...g.store,token:T(),apiUrl:process.env.XTRA_API_URL||g.get("apiUrl")||O}),H=e=>e==="token"?T():g.get(e),Se=(e,t)=>{if(e==="token"&&t&&A("token",t),g.set(e,t),e==="token"&&process.platform!=="win32"&&w.default.existsSync(g.path))try{w.default.chmodSync(g.path,384)}catch{}},xe=()=>g.clear(),ke=e=>g.delete(e),T=()=>P("token")||g.get("token"),je=()=>g.get("breakGlassSessionId"),$e=e=>{e?g.set("breakGlassSessionId",e):g.delete("breakGlassSessionId")},be=async()=>{try{let e=V.default.join(process.cwd(),"xtra.json");if(w.default.existsSync(e)){let t=w.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},Ae=()=>{let e={};try{let t=V.default.join(process.cwd(),".xtrarc");w.default.existsSync(t)&&(e=JSON.parse(w.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||g.get("project")||"",env:e.env||g.get("env")||"development",branch:e.branch||g.get("branch")||"main"}}});var Ke={};L(Ke,{serviceAccountCommand:()=>k});module.exports=E(Ke);var oe=require("commander");var re=l(require("axios"));D();var se=l(require("fs")),ne=l(require("path")),Pe=JSON.parse(se.readFileSync(ne.join(__dirname,"../../package.json"),"utf-8")),a=e=>{let{apiUrl:t}=K(),r=e||T();return re.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Pe.version,...r?{Authorization:`Bearer ${r}`}:{}}})},S={login:async(e,t,r)=>(await a().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,exchangeOidcToken:async(e,t)=>{let r=await a().post("/v2/auth/oidc/token",{provider:e,token:t});return{accessToken:r.data.access_token,envelope:r.data.envelope}},spawnAgentContext:async e=>(await a().post("/agents/ephemeral-context",e)).data,getSecrets:async(e,t,r="main",s,n,o)=>{let d=(await a(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(d&&typeof d=="object"){let u=null,{deriveProjectKey:f,decryptSecretValue:h,resolveVaultPassphrase:I,decryptWorkloadKeyEnvelope:R}=(U(),E(N));for(let[m,$]of Object.entries(d))if(typeof $=="string"&&$.startsWith("{"))try{let v=JSON.parse($);if(v.ciphertext&&v.iv){if(!u)if(o&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)u=R(o,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let ce=I(s,e);u=f(e,ce)}d[m]=h(v,u)}}catch(v){if(v.message&&v.message.includes("Zero-Knowledge"))throw v}}return d},getSecretVersions:async(e,t,r="main")=>(await a().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>{let{deriveProjectKey:o,encryptSecretValue:p,resolveVaultPassphrase:d}=(U(),E(N)),u=d(void 0,e),f=o(e,u),h={};for(let[R,m]of Object.entries(r))if(typeof m=="string"&&m.startsWith("{")&&m.includes("ciphertext"))h[R]=m;else{let $=p(m,f);h[R]=JSON.stringify($)}return(await a().post(`/projects/${e}/envs/${t}/secrets`,{secrets:h,expectedVersions:s,branch:n})).data},getSecretDetails:async(e,t,r,s="main")=>(await a().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,getSecretsV2:async(e,t)=>{let r=t?`&branchId=${t}`:"";return(await a().get(`/v2/secret?projectId=${e}${r}`)).data},createSecretV2:async e=>(await a().post("/v2/secret",e)).data,updateSecretV2:async e=>(await a().put(`/v2/secret?id=${e.id}`,e)).data,deleteSecretV2:async e=>(await a().delete(`/v2/secret?id=${e}`)).data,bulkImportV2:async e=>(await a().post("/v2/secret/bulk",e)).data,syncLogs:async e=>(await a().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,o)=>(await a().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:o})).data,rotateSecret:async(e,t,r,s,n)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await a().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await a().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await a().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await a().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=K(),r=t?`&workspaceId=${t}`:"";return(await a().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await a().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=K(),t=e?`/project?workspaceId=${e}`:"/project";return(await a().get(t)).data},getBranches:async e=>(await a().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await a().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await a().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await a().put("/branch",{id:e,...t})).data,getRoles:async()=>(await a().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await a().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await a().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await a().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await a().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await a().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await a().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await a().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await a().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await a().post("/jit/generate",e)).data,claimJitLink:async e=>(await a().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await a().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await a().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await a().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await a().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await a().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,r,s)=>(await a().post(`/projects/${e}/service-accounts/${t}/keys`,{label:r,expiresAt:s})).data,deleteServiceAccountKey:async(e,t,r)=>(await a().delete(`/projects/${e}/service-accounts/${t}/keys/${r}`)).data,post:async(e,t)=>(await a().post(e,t)).data};var c=l(require("chalk")),x=l(require("ora")),X=require("table");D();var ae=l(require("inquirer")),k=new oe.Command("service-account").alias("sa").description("Manage service accounts and machine tokens"),j=e=>{let t=e.project||H("project");return t||(console.error(c.default.red("\u2716 Error: No project specified.")),console.log(c.default.yellow(" Use --project <id> or run 'xtra project set' first.")),process.exit(1)),t};k.command("list").alias("ls").description("List all service accounts in a project").option("-p, --project <id>","Project ID").action(async e=>{let t=j(e),r=(0,x.default)("Fetching service accounts...").start();try{let s=await S.getServiceAccounts(t);if(r.stop(),!s||s.length===0){console.log(c.default.yellow("No service accounts found for this project."));return}console.log(c.default.bold(`
|
|
2
2
|
Service Accounts for Project ${t}:
|
|
3
|
-
`));let n=[[
|
|
3
|
+
`));let n=[[c.default.bold("ID"),c.default.bold("Name"),c.default.bold("Keys"),c.default.bold("Permissions")]];s.forEach(o=>{n.push([c.default.cyan(o.id),o.name,o._count?.apiKeys||0,o.permissions?.join(", ")||"-"])}),console.log((0,X.table)(n))}catch(s){r.fail("Failed to fetch service accounts"),console.error(c.default.red(s.response?.data?.error||"Unknown error"))}});k.command("create <name>").description("Create a new service account").option("-p, --project <id>","Project ID").option("-d, --description <text>","Description").option("-r, --role <roles>","Comma-separated permissions (read:secrets, write:secrets)","read:secrets").action(async(e,t)=>{let r=j(t),s=t.role.split(",").map(o=>o.trim()),n=(0,x.default)(`Creating service account '${e}'...`).start();try{let o=await S.createServiceAccount(r,{name:e,description:t.description,permissions:s});n.succeed(c.default.green("Service account created successfully!")),console.log(c.default.cyan(`ID: ${o.id}`)),console.log(c.default.gray(`Next: Run 'xtra sa create-key ${o.id}' to generate a token.`))}catch(o){n.fail("Failed to create service account"),console.error(c.default.red(o.response?.data?.error||"Unknown error"))}});k.command("delete <id>").description("Delete a service account").option("-p, --project <id>","Project ID").action(async(e,t)=>{let r=j(t),{confirm:s}=await ae.default.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete service account ${e}? This will invalidate all its keys.`,default:!1}]);if(!s)return;let n=(0,x.default)(`Deleting service account ${e}...`).start();try{await S.deleteServiceAccount(r,e),n.succeed(c.default.green("Service account deleted."))}catch(o){n.fail("Failed to delete service account"),console.error(c.default.red(o.response?.data?.error||"Unknown error"))}});k.command("keys <saId>").description("List keys/tokens for a service account").option("-p, --project <id>","Project ID").action(async(e,t)=>{let r=j(t),s=(0,x.default)("Fetching keys...").start();try{let n=await S.getServiceAccountKeys(r,e);if(s.stop(),!n||n.length===0){console.log(c.default.yellow("No keys found for this service account."));return}console.log(c.default.bold(`
|
|
4
4
|
Keys for Service Account ${e}:
|
|
5
|
-
`));let
|
|
6
|
-
`+
|
|
7
|
-
`),console.log(
|
|
5
|
+
`));let o=[[c.default.bold("ID"),c.default.bold("Label"),c.default.bold("Key Mask"),c.default.bold("Last Used"),c.default.bold("Expires")]];n.forEach(p=>{o.push([c.default.cyan(p.id),p.label||"-",c.default.yellow(p.keyMask||"****"),p.lastUsed?new Date(p.lastUsed).toLocaleString():"Never",p.expiresAt?new Date(p.expiresAt).toLocaleDateString():"Never"])}),console.log((0,X.table)(o))}catch(n){s.fail("Failed to fetch keys"),console.error(c.default.red(n.response?.data?.error||"Unknown error"))}});k.command("create-key <saId>").description("Generate a new token for a service account").option("-p, --project <id>","Project ID").option("-l, --label <text>","Label for the key","CLI Key").option("-e, --expires <days>","Expiration in days (0 for never)","0").action(async(e,t)=>{let r=j(t),s;if(t.expires&&t.expires!=="0"){let o=new Date;o.setDate(o.getDate()+parseInt(t.expires)),s=o.toISOString()}let n=(0,x.default)("Generating new token...").start();try{let o=await S.createServiceAccountKey(r,e,t.label,s);n.succeed(c.default.green("New token generated successfully!")),console.log(`
|
|
6
|
+
`+c.default.bold("SAVE THIS TOKEN NOW. It will NOT be shown again.")),console.log(c.default.black.bgGreen(` ${o.key} `)+`
|
|
7
|
+
`),console.log(c.default.gray("Usage:")),console.log(c.default.white(`$env:XTRA_MACHINE_TOKEN = "${o.key}"`)),console.log(c.default.white("xtra ci run -- npm start"))}catch(o){n.fail("Failed to generate token"),console.error(c.default.red(o.response?.data?.error||"Unknown error"))}});k.command("delete-key <saId> <keyId>").description("Revoke a service account token").option("-p, --project <id>","Project ID").action(async(e,t,r)=>{let s=j(r),n=(0,x.default)(`Revoking key ${t}...`).start();try{await S.deleteServiceAccountKey(s,e,t),n.succeed(c.default.green("Key revoked successfully."))}catch(o){n.fail("Failed to revoke key"),console.error(c.default.red(o.response?.data?.error||"Unknown error"))}});0&&(module.exports={serviceAccountCommand});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var G=Object.create;var u=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var E=(e,t)=>{for(var s in t)u(e,s,{get:t[s],enumerable:!0})},k=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of F(t))!M.call(e,a)&&a!==s&&u(e,a,{get:()=>t[a],enumerable:!(r=W(t,a))||r.enumerable});return e};var c=(e,t,s)=>(s=e!=null?G(K(e)):{},k(t||!e||!e.__esModule?u(s,"default",{value:e,enumerable:!0}):s,e)),H=e=>k(u({},"__esModule",{value:!0}),e);var Q={};E(Q,{simulateCommand:()=>z});module.exports=H(Q);var J=require("commander");var L=c(require("axios"));var I=c(require("conf")),j=c(require("fs")),C=c(require("path")),$="https://www.xtrasecurity.in/api",p=new I.default({projectName:"xtra-cli",defaults:{apiUrl:$}}),R=p.get("apiUrl");R&&!process.env.XTRA_API_URL&&R.includes("xtra-security.vercel.app")&&p.set("apiUrl",$);var y=()=>({...p.store,apiUrl:process.env.XTRA_API_URL||p.get("apiUrl")||$});var A=()=>p.get("token");var U=()=>{let e={};try{let t=C.default.join(process.cwd(),".xtrarc");j.default.existsSync(t)&&(e=JSON.parse(j.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||p.get("project")||"",env:e.env||p.get("env")||"development",branch:e.branch||p.get("branch")||"main"}};var P=c(require("fs")),B=c(require("path")),X=JSON.parse(P.readFileSync(B.join(__dirname,"../../package.json"),"utf-8")),n=()=>{let{apiUrl:e}=y(),t=A();return L.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":X.version,...t?{Authorization:`Bearer ${t}`}:{}}})},_={login:async(e,t,s)=>(await n().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,a="main")=>(await n().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:a})).data,getSecretDetails:async(e,t,s,r="main")=>(await n().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await n().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,a,i)=>(await n().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:a,sourceKey:i})).data,rotateSecret:async(e,t,s,r,a)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:a})).data,promoteSecret:async(e,t,s)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await n().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let a={format:e};return t&&(a.startDate=t),s&&(a.endDate=s),r&&(a.projectId=r),(await n().post("/audit/export",a,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await n().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await n().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=y(),s=t?`&workspaceId=${t}`:"";return(await n().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await n().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=y(),t=e?`/project?workspaceId=${e}`:"/project";return(await n().get(t)).data},getBranches:async e=>(await n().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await n().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await n().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await n().put("/branch",{id:e,...t})).data,getRoles:async()=>(await n().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await n().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await n().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await n().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await n().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await n().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await n().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await n().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await n().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,a)=>(await n().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:a})).data,generateJitLink:async e=>(await n().post("/jit/generate",e)).data,claimJitLink:async e=>(await n().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await n().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await n().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await n().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await n().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await n().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,r)=>(await n().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:r})).data,deleteServiceAccountKey:async(e,t,s)=>(await n().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await n().post(e,t)).data};var o=c(require("chalk")),T=c(require("ora")),D=require("table"),z=new J.Command("simulate").description("Dry-run: show what 'xtra run' would inject without executing the command").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment","development").option("-b, --branch <branch>","Branch","main").argument("[command]","Command that would be executed (display only)").option("--show-values","Reveal secret values in output (default: masked)",!1).option("--diff","Highlight secrets that differ from local .env / process.env",!1).action(async(e,t)=>{let{project:s,env:r,branch:a,showValues:i,diff:g}=t;r={dev:"development",stg:"staging",prod:"production"}[r]||r,s||(s=U().project),s||(console.error(o.default.red("Error: Project ID required. Use -p <id> or run 'xtra project set'.")),process.exit(1));let b=(0,T.default)(`Fetching secrets to simulate injection (${r}/${a})...`).start(),m;try{m=await _.getSecrets(s,r,a),b.stop()}catch(l){b.fail("Failed to fetch secrets."),console.error(o.default.red(l?.response?.data?.error||l?.response?.data?.error||"An unexpected error occurred")),process.exit(1)}let f=Object.keys(m).length,h=process.stdout.columns||100,O=Math.floor(h*.25),V=Math.floor(h*.4),N=Math.floor(h*.15);if(console.log(o.default.bold.cyan(`
|
|
2
|
-
\u25CF Simulation`)+
|
|
3
|
-
`)),console.log(
|
|
4
|
-
`)),f===0){console.log(
|
|
5
|
-
\u2714 Simulation complete.`)+
|
|
1
|
+
var ge=Object.create;var K=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var de=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var H=(e,t)=>()=>(e&&(t=e(e=0)),t);var U=(e,t)=>{for(var r in t)K(e,r,{get:t[r],enumerable:!0})},X=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of le(t))!fe.call(e,n)&&n!==r&&K(e,n,{get:()=>t[n],enumerable:!(s=ue(t,n))||s.enumerable});return e};var y=(e,t,r)=>(r=e!=null?ge(de(e)):{},X(t||!e||!e.__esModule?K(r,"default",{value:e,enumerable:!0}):r,e)),_=e=>X(K({},"__esModule",{value:!0}),e);var O={};U(O,{createWorkloadKeyEnvelope:()=>xe,decrypt:()=>Z,decryptSecretValue:()=>ve,decryptWorkloadKeyEnvelope:()=>Se,deriveProjectKey:()=>he,encrypt:()=>Y,encryptSecretValue:()=>me,hash:()=>ye,resolveVaultPassphrase:()=>z,saveVaultPassphrase:()=>we,secureRead:()=>A,secureSave:()=>k});function F(){if(B)return B;let e=C.get("masterKey");e||(e=c.default.randomBytes(32).toString("hex"),C.set("masterKey",e));let t="";try{t=(0,M.machineIdSync)()||""}catch{t=c.default.createHash("sha256").update(h.default.hostname()+(h.default.userInfo?.()?.username||"root")).digest("hex")}let r=h.default.platform(),s=h.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return B=c.default.createHash("sha256").update(n).digest(),B}function he(e,t){t||(t=z(void 0,e));let r=Buffer.from(`project_salt_${e}`),s=Buffer.from("xtra-e2ee-project-key-v2"),n=c.default.hkdfSync("sha256",Buffer.from(t),r,s,32);return Buffer.from(n).toString("hex")}function me(e,t){let r=c.default.randomBytes(12),s=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=c.default.createCipheriv("aes-256-gcm",s,r),i=n.update(e,"utf8","hex");i+=n.final("hex");let p=n.getAuthTag().toString("hex");return{ciphertext:i,iv:r.toString("hex"),authTag:p}}function ve(e,t){let r=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.authTag,"hex"),i=c.default.createDecipheriv("aes-256-gcm",r,s);i.setAuthTag(n);let p=i.update(e.ciphertext,"hex","utf8");return p+=i.final("utf8"),p}function z(e,t){if(e&&e.trim())return e.trim();if(process.env.XTRA_VAULT_PASSPHRASE&&process.env.XTRA_VAULT_PASSPHRASE.trim())return process.env.XTRA_VAULT_PASSPHRASE.trim();if(process.env.XTRA_MASTER_SECRET&&process.env.XTRA_MASTER_SECRET.trim())return process.env.XTRA_MASTER_SECRET.trim();try{if(t){let s=A(`vault_${t}`);if(s)return s}let r=A("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(E(),_(Q)),s=r();if(s&&s.passphrase)return s.passphrase}catch{}throw new Error("Vault Passphrase or Master Secret is required for Zero-Knowledge E2EE encryption/decryption.")}function we(e,t){t&&k(`vault_${t}`,e),k("vault_passphrase",e)}function xe(e,t){let{publicKey:r,privateKey:s}=c.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),i=c.default.createPublicKey(t),p=c.default.diffieHellman({privateKey:s,publicKey:i}),d=Buffer.from(c.default.hkdfSync("sha256",p,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),u=c.default.randomBytes(12),l=c.default.createCipheriv("aes-256-gcm",d,u),f=l.update(e,"utf8","hex");f+=l.final("hex");let w=l.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:f,iv:u.toString("hex"),authTag:w}}function Se(e,t){let r=c.default.createPrivateKey(t),s=c.default.createPublicKey(e.ephemeralPublicKey),n=c.default.diffieHellman({privateKey:r,publicKey:s}),i=Buffer.from(c.default.hkdfSync("sha256",n,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),p=Buffer.from(e.iv,"hex"),d=Buffer.from(e.authTag,"hex"),u=c.default.createDecipheriv("aes-256-gcm",i,p);u.setAuthTag(d);let l=u.update(e.encryptedProjectKey,"hex","utf8");return l+=u.final("utf8"),l}var c,h,q,M,j,G,C,B,Y,Z,ye,k,A,I=H(()=>{c=y(require("crypto")),h=y(require("os")),q=y(require("conf")),M=require("node-machine-id"),j=require("child_process"),G="aes-256-gcm",C=new q.default({projectName:"xtra-cli-crypto"}),B=null;Y=e=>{let t=c.default.randomBytes(12),r=F(),s=c.default.createCipheriv(G,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let i=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:i.toString("hex")}},Z=e=>{let t=F(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=c.default.createDecipheriv(G,t,r);n.setAuthTag(s);let i=n.update(e.content,"hex","utf8");return i+=n.final("utf8"),i},ye=e=>c.default.createHash("sha256").update(e).digest("hex"),k=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if(h.default.platform()==="darwin"){(0,j.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if(h.default.platform()!=="win32"){if(h.default.platform()==="linux")try{(0,j.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=Y(t);C.set(`secure_${e}`,JSON.stringify(r))},A=e=>{try{let t="XtraSecurityCLI",r=e;if(h.default.platform()==="darwin")return(0,j.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(h.default.platform()!=="win32"){if(h.default.platform()==="linux")try{return(0,j.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=C.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return Z(r)}catch{return null}}});var Q={};U(Q,{clearConfig:()=>je,deleteConfig:()=>ke,getAuthToken:()=>T,getBreakGlassSession:()=>Ae,getConfig:()=>P,getConfigValue:()=>be,getProjectConfig:()=>Te,getRcConfig:()=>J,setBreakGlassSession:()=>Pe,setConfig:()=>$e});var te,b,W,D,g,ee,P,be,$e,je,ke,T,Ae,Pe,Te,J,E=H(()=>{te=y(require("conf")),b=y(require("fs")),W=y(require("path"));I();D="https://www.xtrasecurity.in/api",g=new te.default({projectName:"xtra-cli",defaults:{apiUrl:D}}),ee=g.get("apiUrl");ee&&!process.env.XTRA_API_URL&&ee.includes("xtra-security.vercel.app")&&g.set("apiUrl",D);P=()=>({...g.store,token:T(),apiUrl:process.env.XTRA_API_URL||g.get("apiUrl")||D}),be=e=>e==="token"?T():g.get(e),$e=(e,t)=>{if(e==="token"&&t&&k("token",t),g.set(e,t),e==="token"&&process.platform!=="win32"&&b.default.existsSync(g.path))try{b.default.chmodSync(g.path,384)}catch{}},je=()=>g.clear(),ke=e=>g.delete(e),T=()=>A("token")||g.get("token"),Ae=()=>g.get("breakGlassSessionId"),Pe=e=>{e?g.set("breakGlassSessionId",e):g.delete("breakGlassSessionId")},Te=async()=>{try{let e=W.default.join(process.cwd(),"xtra.json");if(b.default.existsSync(e)){let t=b.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},J=()=>{let e={};try{let t=W.default.join(process.cwd(),".xtrarc");b.default.existsSync(t)&&(e=JSON.parse(b.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||g.get("project")||"",env:e.env||g.get("env")||"development",branch:e.branch||g.get("branch")||"main"}}});var _e={};U(_e,{simulateCommand:()=>Ke});module.exports=_(_e);var ae=require("commander");var re=y(require("axios"));E();var se=y(require("fs")),ne=y(require("path")),Re=JSON.parse(se.readFileSync(ne.join(__dirname,"../../package.json"),"utf-8")),o=e=>{let{apiUrl:t}=P(),r=e||T();return re.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Re.version,...r?{Authorization:`Bearer ${r}`}:{}}})},oe={login:async(e,t,r)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,exchangeOidcToken:async(e,t)=>{let r=await o().post("/v2/auth/oidc/token",{provider:e,token:t});return{accessToken:r.data.access_token,envelope:r.data.envelope}},spawnAgentContext:async e=>(await o().post("/agents/ephemeral-context",e)).data,getSecrets:async(e,t,r="main",s,n,i)=>{let d=(await o(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(d&&typeof d=="object"){let u=null,{deriveProjectKey:l,decryptSecretValue:f,resolveVaultPassphrase:w,decryptWorkloadKeyEnvelope:$}=(I(),_(O));for(let[v,x]of Object.entries(d))if(typeof x=="string"&&x.startsWith("{"))try{let m=JSON.parse(x);if(m.ciphertext&&m.iv){if(!u)if(i&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)u=$(i,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let S=w(s,e);u=l(e,S)}d[v]=f(m,u)}}catch(m){if(m.message&&m.message.includes("Zero-Knowledge"))throw m}}return d},getSecretVersions:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>{let{deriveProjectKey:i,encryptSecretValue:p,resolveVaultPassphrase:d}=(I(),_(O)),u=d(void 0,e),l=i(e,u),f={};for(let[$,v]of Object.entries(r))if(typeof v=="string"&&v.startsWith("{")&&v.includes("ciphertext"))f[$]=v;else{let x=p(v,l);f[$]=JSON.stringify(x)}return(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:f,expectedVersions:s,branch:n})).data},getSecretDetails:async(e,t,r,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,getSecretsV2:async(e,t)=>{let r=t?`&branchId=${t}`:"";return(await o().get(`/v2/secret?projectId=${e}${r}`)).data},createSecretV2:async e=>(await o().post("/v2/secret",e)).data,updateSecretV2:async e=>(await o().put(`/v2/secret?id=${e.id}`,e)).data,deleteSecretV2:async e=>(await o().delete(`/v2/secret?id=${e}`)).data,bulkImportV2:async e=>(await o().post("/v2/secret/bulk",e)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,i)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:i})).data,rotateSecret:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=P(),r=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=P(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await o().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,r,s)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:r,expiresAt:s})).data,deleteServiceAccountKey:async(e,t,r)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${r}`)).data,post:async(e,t)=>(await o().post(e,t)).data};E();var a=y(require("chalk")),ie=y(require("ora")),ce=require("table"),Ke=new ae.Command("simulate").description("Dry-run: show what 'xtra run' would inject without executing the command").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment","development").option("-b, --branch <branch>","Branch","main").argument("[command]","Command that would be executed (display only)").option("--show-values","Reveal secret values in output (default: masked)",!1).option("--diff","Highlight secrets that differ from local .env / process.env",!1).action(async(e,t)=>{let{project:r,env:s,branch:n,showValues:i,diff:p}=t;s={dev:"development",stg:"staging",prod:"production"}[s]||s,r||(r=J().project),r||(console.error(a.default.red("Error: Project ID required. Use -p <id> or run 'xtra project set'.")),process.exit(1));let u=(0,ie.default)(`Fetching secrets to simulate injection (${s}/${n})...`).start(),l;try{l=await oe.getSecrets(r,s,n),u.stop()}catch(S){u.fail("Failed to fetch secrets."),console.error(a.default.red(S?.response?.data?.error||S?.response?.data?.error||"An unexpected error occurred")),process.exit(1)}let f=Object.keys(l).length,w=process.stdout.columns||100,$=Math.floor(w*.25),v=Math.floor(w*.4),x=Math.floor(w*.15);if(console.log(a.default.bold.cyan(`
|
|
2
|
+
\u25CF Simulation`)+a.default.bold(` \u2014 xtra run ${e?a.default.cyan(e):"(no command specified)"}
|
|
3
|
+
`)),console.log(a.default.gray(` Project : ${a.default.white(r)}`)),console.log(a.default.gray(` Env : ${a.default.white(s)}`)),console.log(a.default.gray(` Branch : ${a.default.white(n)}`)),console.log(a.default.gray(` Secrets : ${a.default.white(f)} would be injected
|
|
4
|
+
`)),f===0){console.log(a.default.yellow(" No secrets found for this environment/branch."));return}let m=[[a.default.bold("Key"),a.default.bold("Injected Value"),a.default.bold("Local .env"),a.default.bold("Status")]];for(let[S,N]of Object.entries(l)){let V=process.env[S],pe=i?a.default.cyan(N):a.default.gray("\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"),R=a.default.green("Injected"),L="-";p&&V!==void 0?(L=i?a.default.yellow(V):a.default.gray("\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"),V===N?R=a.default.gray("Same"):R=a.default.yellow("\u26A1 Override")):p&&(R=a.default.blue("New"),L=a.default.gray("(not set)")),m.push([a.default.white(S),pe,p?L:"-",R])}console.log((0,ce.table)(m,{columns:[{width:$,wrapWord:!0},{width:v,wrapWord:!0},{width:x,wrapWord:!0},{width:10}],border:{topBody:"\u2500",topJoin:"\u252C",topLeft:"\u250C",topRight:"\u2510",bottomBody:"\u2500",bottomJoin:"\u2534",bottomLeft:"\u2514",bottomRight:"\u2518",bodyLeft:"\u2502",bodyRight:"\u2502",bodyJoin:"\u2502",joinBody:"\u2500",joinLeft:"\u251C",joinRight:"\u2524",joinJoin:"\u253C"}})),i||console.log(a.default.gray(" Tip: use --show-values to reveal actual secret values")),p||console.log(a.default.gray(" Tip: use --diff to compare against your local process.env")),console.log(a.default.bold.green(`
|
|
5
|
+
\u2714 Simulation complete.`)+a.default.bold(` ${f} secret(s) would be injected.`)),console.log(a.default.gray(` Run without 'simulate' to actually execute the command.
|
|
6
6
|
`))});0&&(module.exports={simulateCommand});
|
package/dist/commands/status.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var q=Object.create;var m=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var V=(e,t)=>{for(var s in t)m(e,s,{get:t[s],enumerable:!0})},$=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of K(t))!H.call(e,o)&&o!==s&&m(e,o,{get:()=>t[o],enumerable:!(n=J(t,o))||n.enumerable});return e};var c=(e,t,s)=>(s=e!=null?q(G(e)):{},$(t||!e||!e.__esModule?m(s,"default",{value:e,enumerable:!0}):s,e)),X=e=>$(m({},"__esModule",{value:!0}),e);var Z={};V(Z,{statusCommand:()=>Y});module.exports=X(Z);var O=require("commander");var C=c(require("axios"));var I=c(require("conf")),v=c(require("fs")),k=c(require("path")),w="https://www.xtrasecurity.in/api",g=new I.default({projectName:"xtra-cli",defaults:{apiUrl:w}}),b=g.get("apiUrl");b&&!process.env.XTRA_API_URL&&b.includes("xtra-security.vercel.app")&&g.set("apiUrl",w);var y=()=>({...g.store,apiUrl:process.env.XTRA_API_URL||g.get("apiUrl")||w});var A=()=>g.get("token");var S=()=>{let e={};try{let t=k.default.join(process.cwd(),".xtrarc");v.default.existsSync(t)&&(e=JSON.parse(v.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||g.get("project")||"",env:e.env||g.get("env")||"development",branch:e.branch||g.get("branch")||"main"}};var R=c(require("fs")),U=c(require("path")),z=JSON.parse(R.readFileSync(U.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=y(),t=A();return C.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":z.version,...t?{Authorization:`Bearer ${t}`}:{}}})},E={login:async(e,t,s)=>(await r().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,o="main")=>(await r().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:o})).data,getSecretDetails:async(e,t,s,n="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await r().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,o,i)=>(await r().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:i})).data,rotateSecret:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await r().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),n&&(o.projectId=n),(await r().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await r().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await r().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=y(),s=t?`&workspaceId=${t}`:"";return(await r().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await r().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=y(),t=e?`/project?workspaceId=${e}`:"/project";return(await r().get(t)).data},getBranches:async e=>(await r().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await r().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await r().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await r().put("/branch",{id:e,...t})).data,getRoles:async()=>(await r().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await r().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await r().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await r().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await r().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await r().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await r().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:o})).data,generateJitLink:async e=>(await r().post("/jit/generate",e)).data,claimJitLink:async e=>(await r().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await r().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await r().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await r().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await r().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await r().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,n)=>(await r().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:n})).data,deleteServiceAccountKey:async(e,t,s)=>(await r().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await r().post(e,t)).data};var a=c(require("chalk")),B=c(require("ora")),F=require("table");var j=c(require("fs")),x=c(require("path")),W=x.default.join(process.cwd(),".xtra"),N=x.default.join(W,"manifest.json");function D(){if(!j.default.existsSync(N))return null;try{let e=j.default.readFileSync(N,"utf-8");return JSON.parse(e)}catch{return null}}var M=c(require("crypto")),P=c(require("conf")),Q=require("node-machine-id");var oe=new P.default({projectName:"xtra-cli-crypto"});var L=e=>M.default.createHash("sha256").update(e).digest("hex");var Y=new O.Command("status").description("Check synchronization status with XtraSync platform").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Environment (dev, stg, prod)","dev").option("-b, --branch <branchName>","Branch Name").action(async e=>{let{project:t,env:s,branch:n}=e;t||(t=S().project),n||(n=S().branch||"main"),t||(console.error(a.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1)),s={dev:"development",stg:"staging",prod:"production"}[s]||s;let i=D();if(!i){console.log(a.default.yellow("No local manifest found. Run 'xtra run' or 'xtra generate' first."));return}(i.projectId!==t||i.environment!==s)&&(console.log(a.default.yellow(`Manifest found for DIFFERENT project/env (${i.projectId}/${i.environment}).`)),console.log("Checking status against requested target anyway..."));let h=(0,B.default)(`Fetching remote state for ${s} (branch: ${n})...`).start();try{let l=await E.getSecrets(t,s,n);h.stop();let d=[[a.default.bold("Secret Key"),a.default.bold("Status"),a.default.bold("Local Last Updated")]],u=0;Object.entries(l).forEach(([p,T])=>{let _=L(T),f=i.secrets[p];f?f.hash!==_?(d.push([p,a.default.yellow("MODIFIED"),f.updatedAt]),u++):d.push([p,a.default.cyan("Synced"),f.updatedAt]):(d.push([p,a.default.green("NEW (Remote)"),"-"]),u++)}),Object.keys(i.secrets).forEach(p=>{l[p]||(d.push([p,a.default.red("DELETED (Remote)"),i.secrets[p].updatedAt]),u++)}),console.log(""),console.log((0,F.table)(d)),u===0?console.log(a.default.green("\u2714 Everything is in sync.")):(console.log(a.default.yellow(`\u26A0 Found ${u} difference(s).
|
|
2
|
-
`)),console.log(
|
|
1
|
+
var ge=Object.create;var R=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var de=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var M=(e,t)=>()=>(e&&(t=e(e=0)),t);var B=(e,t)=>{for(var r in t)R(e,r,{get:t[r],enumerable:!0})},F=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of le(t))!fe.call(e,n)&&n!==r&&R(e,n,{get:()=>t[n],enumerable:!(s=ue(t,n))||s.enumerable});return e};var y=(e,t,r)=>(r=e!=null?ge(de(e)):{},F(t||!e||!e.__esModule?R(r,"default",{value:e,enumerable:!0}):r,e)),K=e=>F(R({},"__esModule",{value:!0}),e);var V={};B(V,{createWorkloadKeyEnvelope:()=>Se,decrypt:()=>G,decryptSecretValue:()=>me,decryptWorkloadKeyEnvelope:()=>xe,deriveProjectKey:()=>ye,encrypt:()=>W,encryptSecretValue:()=>he,hash:()=>O,resolveVaultPassphrase:()=>z,saveVaultPassphrase:()=>ve,secureRead:()=>A,secureSave:()=>b});function J(){if(I)return I;let e=E.get("masterKey");e||(e=i.default.randomBytes(32).toString("hex"),E.set("masterKey",e));let t="";try{t=(0,H.machineIdSync)()||""}catch{t=i.default.createHash("sha256").update(m.default.hostname()+(m.default.userInfo?.()?.username||"root")).digest("hex")}let r=m.default.platform(),s=m.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return I=i.default.createHash("sha256").update(n).digest(),I}function ye(e,t){t||(t=z(void 0,e));let r=Buffer.from(`project_salt_${e}`),s=Buffer.from("xtra-e2ee-project-key-v2"),n=i.default.hkdfSync("sha256",Buffer.from(t),r,s,32);return Buffer.from(n).toString("hex")}function he(e,t){let r=i.default.randomBytes(12),s=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=i.default.createCipheriv("aes-256-gcm",s,r),a=n.update(e,"utf8","hex");a+=n.final("hex");let f=n.getAuthTag().toString("hex");return{ciphertext:a,iv:r.toString("hex"),authTag:f}}function me(e,t){let r=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.authTag,"hex"),a=i.default.createDecipheriv("aes-256-gcm",r,s);a.setAuthTag(n);let f=a.update(e.ciphertext,"hex","utf8");return f+=a.final("utf8"),f}function z(e,t){if(e&&e.trim())return e.trim();if(process.env.XTRA_VAULT_PASSPHRASE&&process.env.XTRA_VAULT_PASSPHRASE.trim())return process.env.XTRA_VAULT_PASSPHRASE.trim();if(process.env.XTRA_MASTER_SECRET&&process.env.XTRA_MASTER_SECRET.trim())return process.env.XTRA_MASTER_SECRET.trim();try{if(t){let s=A(`vault_${t}`);if(s)return s}let r=A("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(_(),K(Y)),s=r();if(s&&s.passphrase)return s.passphrase}catch{}throw new Error("Vault Passphrase or Master Secret is required for Zero-Knowledge E2EE encryption/decryption.")}function ve(e,t){t&&b(`vault_${t}`,e),b("vault_passphrase",e)}function Se(e,t){let{publicKey:r,privateKey:s}=i.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),a=i.default.createPublicKey(t),f=i.default.diffieHellman({privateKey:s,publicKey:a}),l=Buffer.from(i.default.hkdfSync("sha256",f,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),p=i.default.randomBytes(12),d=i.default.createCipheriv("aes-256-gcm",l,p),g=d.update(e,"utf8","hex");g+=d.final("hex");let x=d.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:g,iv:p.toString("hex"),authTag:x}}function xe(e,t){let r=i.default.createPrivateKey(t),s=i.default.createPublicKey(e.ephemeralPublicKey),n=i.default.diffieHellman({privateKey:r,publicKey:s}),a=Buffer.from(i.default.hkdfSync("sha256",n,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),f=Buffer.from(e.iv,"hex"),l=Buffer.from(e.authTag,"hex"),p=i.default.createDecipheriv("aes-256-gcm",a,f);p.setAuthTag(l);let d=p.update(e.encryptedProjectKey,"hex","utf8");return d+=p.final("utf8"),d}var i,m,X,H,$,q,E,I,W,G,O,b,A,k=M(()=>{i=y(require("crypto")),m=y(require("os")),X=y(require("conf")),H=require("node-machine-id"),$=require("child_process"),q="aes-256-gcm",E=new X.default({projectName:"xtra-cli-crypto"}),I=null;W=e=>{let t=i.default.randomBytes(12),r=J(),s=i.default.createCipheriv(q,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let a=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:a.toString("hex")}},G=e=>{let t=J(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=i.default.createDecipheriv(q,t,r);n.setAuthTag(s);let a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a},O=e=>i.default.createHash("sha256").update(e).digest("hex"),b=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if(m.default.platform()==="darwin"){(0,$.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if(m.default.platform()!=="win32"){if(m.default.platform()==="linux")try{(0,$.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=W(t);E.set(`secure_${e}`,JSON.stringify(r))},A=e=>{try{let t="XtraSecurityCLI",r=e;if(m.default.platform()==="darwin")return(0,$.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(m.default.platform()!=="win32"){if(m.default.platform()==="linux")try{return(0,$.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=E.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return G(r)}catch{return null}}});var Y={};B(Y,{clearConfig:()=>$e,deleteConfig:()=>be,getAuthToken:()=>T,getBreakGlassSession:()=>Ae,getConfig:()=>P,getConfigValue:()=>we,getProjectConfig:()=>Pe,getRcConfig:()=>C,setBreakGlassSession:()=>ke,setConfig:()=>je});var Q,S,U,L,u,Z,P,we,je,$e,be,T,Ae,ke,Pe,C,_=M(()=>{Q=y(require("conf")),S=y(require("fs")),U=y(require("path"));k();L="https://www.xtrasecurity.in/api",u=new Q.default({projectName:"xtra-cli",defaults:{apiUrl:L}}),Z=u.get("apiUrl");Z&&!process.env.XTRA_API_URL&&Z.includes("xtra-security.vercel.app")&&u.set("apiUrl",L);P=()=>({...u.store,token:T(),apiUrl:process.env.XTRA_API_URL||u.get("apiUrl")||L}),we=e=>e==="token"?T():u.get(e),je=(e,t)=>{if(e==="token"&&t&&b("token",t),u.set(e,t),e==="token"&&process.platform!=="win32"&&S.default.existsSync(u.path))try{S.default.chmodSync(u.path,384)}catch{}},$e=()=>u.clear(),be=e=>u.delete(e),T=()=>A("token")||u.get("token"),Ae=()=>u.get("breakGlassSessionId"),ke=e=>{e?u.set("breakGlassSessionId",e):u.delete("breakGlassSessionId")},Pe=async()=>{try{let e=U.default.join(process.cwd(),"xtra.json");if(S.default.existsSync(e)){let t=S.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},C=()=>{let e={};try{let t=U.default.join(process.cwd(),".xtrarc");S.default.existsSync(t)&&(e=JSON.parse(S.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||u.get("project")||"",env:e.env||u.get("env")||"development",branch:e.branch||u.get("branch")||"main"}}});var Ie={};B(Ie,{statusCommand:()=>Ke});module.exports=K(Ie);var ae=require("commander");var ee=y(require("axios"));_();var te=y(require("fs")),re=y(require("path")),Te=JSON.parse(te.readFileSync(re.join(__dirname,"../../package.json"),"utf-8")),o=e=>{let{apiUrl:t}=P(),r=e||T();return ee.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Te.version,...r?{Authorization:`Bearer ${r}`}:{}}})},se={login:async(e,t,r)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,exchangeOidcToken:async(e,t)=>{let r=await o().post("/v2/auth/oidc/token",{provider:e,token:t});return{accessToken:r.data.access_token,envelope:r.data.envelope}},spawnAgentContext:async e=>(await o().post("/agents/ephemeral-context",e)).data,getSecrets:async(e,t,r="main",s,n,a)=>{let l=(await o(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(l&&typeof l=="object"){let p=null,{deriveProjectKey:d,decryptSecretValue:g,resolveVaultPassphrase:x,decryptWorkloadKeyEnvelope:w}=(k(),K(V));for(let[h,j]of Object.entries(l))if(typeof j=="string"&&j.startsWith("{"))try{let v=JSON.parse(j);if(v.ciphertext&&v.iv){if(!p)if(a&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)p=w(a,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let pe=x(s,e);p=d(e,pe)}l[h]=g(v,p)}}catch(v){if(v.message&&v.message.includes("Zero-Knowledge"))throw v}}return l},getSecretVersions:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>{let{deriveProjectKey:a,encryptSecretValue:f,resolveVaultPassphrase:l}=(k(),K(V)),p=l(void 0,e),d=a(e,p),g={};for(let[w,h]of Object.entries(r))if(typeof h=="string"&&h.startsWith("{")&&h.includes("ciphertext"))g[w]=h;else{let j=f(h,d);g[w]=JSON.stringify(j)}return(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:g,expectedVersions:s,branch:n})).data},getSecretDetails:async(e,t,r,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,getSecretsV2:async(e,t)=>{let r=t?`&branchId=${t}`:"";return(await o().get(`/v2/secret?projectId=${e}${r}`)).data},createSecretV2:async e=>(await o().post("/v2/secret",e)).data,updateSecretV2:async e=>(await o().put(`/v2/secret?id=${e.id}`,e)).data,deleteSecretV2:async e=>(await o().delete(`/v2/secret?id=${e}`)).data,bulkImportV2:async e=>(await o().post("/v2/secret/bulk",e)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,a)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:a})).data,rotateSecret:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=P(),r=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=P(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await o().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,r,s)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:r,expiresAt:s})).data,deleteServiceAccountKey:async(e,t,r)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${r}`)).data,post:async(e,t)=>(await o().post(e,t)).data};var c=y(require("chalk")),ie=y(require("ora")),ce=require("table");var N=y(require("fs")),D=y(require("path")),Re=D.default.join(process.cwd(),".xtra"),ne=D.default.join(Re,"manifest.json");function oe(){if(!N.default.existsSync(ne))return null;try{let e=N.default.readFileSync(ne,"utf-8");return JSON.parse(e)}catch{return null}}k();_();var Ke=new ae.Command("status").description("Check synchronization status with XtraSync platform").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Environment (dev, stg, prod)","dev").option("-b, --branch <branchName>","Branch Name").action(async e=>{let{project:t,env:r,branch:s}=e;t||(t=C().project),s||(s=C().branch||"main"),t||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1)),r={dev:"development",stg:"staging",prod:"production"}[r]||r;let a=oe();if(!a){console.log(c.default.yellow("No local manifest found. Run 'xtra run' or 'xtra generate' first."));return}(a.projectId!==t||a.environment!==r)&&(console.log(c.default.yellow(`Manifest found for DIFFERENT project/env (${a.projectId}/${a.environment}).`)),console.log("Checking status against requested target anyway..."));let f=(0,ie.default)(`Fetching remote state for ${r} (branch: ${s})...`).start();try{let l=await se.getSecrets(t,r,s);f.stop();let p=[[c.default.bold("Secret Key"),c.default.bold("Status"),c.default.bold("Local Last Updated")]],d=0;Object.entries(l).forEach(([g,x])=>{let w=O(x),h=a.secrets[g];h?h.hash!==w?(p.push([g,c.default.yellow("MODIFIED"),h.updatedAt]),d++):p.push([g,c.default.cyan("Synced"),h.updatedAt]):(p.push([g,c.default.green("NEW (Remote)"),"-"]),d++)}),Object.keys(a.secrets).forEach(g=>{l[g]||(p.push([g,c.default.red("DELETED (Remote)"),a.secrets[g].updatedAt]),d++)}),console.log(""),console.log((0,ce.table)(p)),d===0?console.log(c.default.green("\u2714 Everything is in sync.")):(console.log(c.default.yellow(`\u26A0 Found ${d} difference(s).
|
|
2
|
+
`)),console.log(c.default.bold(" Next steps:")),console.log(c.default.gray(" xtra generate ")+c.default.white("# pull cloud secrets \xE2\u2020\u2019 .env (merge)")),console.log(c.default.gray(" xtra generate -f json ")+c.default.white("# pull cloud secrets \xE2\u2020\u2019 secrets.json")),console.log(c.default.gray(" xtra run node app.js ")+c.default.white("# inject secrets at runtime (no file)")),console.log(c.default.gray(" xtra local sync ")+c.default.white("# pull cloud secrets \xE2\u2020\u2019 .env.local (offline mode)")))}catch(l){f.fail("Failed to fetch remote secrets."),console.error(c.default.red(l?.response?.data?.error||"An unexpected error occurred"))}});0&&(module.exports={statusCommand});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var fe=Object.create;var k=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var he=Object.getPrototypeOf,ve=Object.prototype.hasOwnProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var q=(e,t)=>{for(var s in t)k(e,s,{get:t[s],enumerable:!0})},G=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ye(t))!ve.call(e,r)&&r!==s&&k(e,r,{get:()=>t[r],enumerable:!(n=me(t,r))||n.enumerable});return e};var l=(e,t,s)=>(s=e!=null?fe(he(e)):{},G(t||!e||!e.__esModule?k(s,"default",{value:e,enumerable:!0}):s,e)),M=e=>G(k({},"__esModule",{value:!0}),e);var V,U,Y,L,h,H,w,z,B,I=R(()=>{V=l(require("conf")),U=l(require("fs")),Y=l(require("path")),L="https://www.xtrasecurity.in/api",h=new V.default({projectName:"xtra-cli",defaults:{apiUrl:L}}),H=h.get("apiUrl");H&&!process.env.XTRA_API_URL&&H.includes("xtra-security.vercel.app")&&h.set("apiUrl",L);w=()=>({...h.store,apiUrl:process.env.XTRA_API_URL||h.get("apiUrl")||L}),z=()=>h.get("token"),B=()=>{let e={};try{let t=Y.default.join(process.cwd(),".xtrarc");U.default.existsSync(t)&&(e=JSON.parse(U.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||h.get("project")||"",env:e.env||h.get("env")||"development",branch:e.branch||h.get("branch")||"main"}}});var X,W,Z,$e,o,b,K=R(()=>{X=l(require("axios"));I();W=l(require("fs")),Z=l(require("path")),$e=JSON.parse(W.readFileSync(Z.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=w(),t=z();return X.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":$e.version,...t?{Authorization:`Bearer ${t}`}:{}}})},b={login:async(e,t,s)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,r="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:r})).data,getSecretDetails:async(e,t,s,n="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,r,c)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:r,sourceKey:c})).data,rotateSecret:async(e,t,s,n,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:r})).data,promoteSecret:async(e,t,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let r={format:e};return t&&(r.startDate=t),s&&(r.endDate=s),n&&(r.projectId=n),(await o().post("/audit/export",r,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await o().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=w(),s=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=w(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await o().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,r)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:r})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,n)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:n})).data,deleteServiceAccountKey:async(e,t,s)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});function ne(){let e=Q.get("masterKey");e||(e=x.default.randomBytes(32).toString("hex"),Q.set("masterKey",e));let t=(0,te.machineIdSync)();return x.default.createHash("sha256").update(e+t).digest()}var x,ee,te,se,Q,re,oe,ae=R(()=>{x=l(require("crypto")),ee=l(require("conf")),te=require("node-machine-id"),se="aes-256-gcm",Q=new ee.default({projectName:"xtra-cli-crypto"});re=e=>{let t=x.default.randomBytes(16),s=ne(),n=x.default.createCipheriv(se,s,t),r=n.update(e,"utf8","hex");r+=n.final("hex");let c=n.getAuthTag();return{iv:t.toString("hex"),content:r,tag:c.toString("hex")}},oe=e=>{let t=ne(),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),r=x.default.createDecipheriv(se,t,s);r.setAuthTag(n);let c=r.update(e.content,"hex","utf8");return c+=r.final("utf8"),c}});var pe={};q(pe,{loadAuditLogs:()=>E,logAudit:()=>xe,saveAuditLogs:()=>C,syncAuditLogs:()=>je});function we(e){if(!e||typeof e!="object")return e;let t={...e},s=["password","token","secret","value","apiKey","secretValue"];for(let n of Object.keys(t))s.some(r=>n.toLowerCase().includes(r))&&(t[n]="[REDACTED]");return t}async function ie(e){try{if(!w().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:we(e.details),timestamp:e.timestamp,projectId:e.projectId};return await b.post("/audit/cli-logs",{logs:[s]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function xe(e,t,s,n){let r={id:(0,ce.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:n,synced:!1},c=E();c.push(r),C(c),ie(r).then(d=>{if(d){r.synced=!0;let u=E(),i=u.findIndex(p=>p.id===r.id);i!==-1&&(u[i].synced=!0,C(u))}}).catch(()=>{})}function E(){if(!j.default.existsSync(_))return[];try{let e=j.default.readFileSync(_,"utf-8"),t=JSON.parse(e),s=oe(t);return JSON.parse(s)}catch{return[]}}function C(e){j.default.existsSync(O)||j.default.mkdirSync(O,{recursive:!0});let t=JSON.stringify(e),s=re(t);j.default.writeFileSync(_,JSON.stringify(s),"utf-8")}async function je(){let e=E(),t=e.filter(n=>!n.synced);if(t.length===0)return 0;let s=0;for(let n of t)await ie(n)&&(n.synced=!0,s++);return s>0&&C(e),s}var j,F,ce,O,_,le=R(()=>{j=l(require("fs")),F=l(require("path")),ce=require("uuid");ae();I();K();O=F.default.join(process.cwd(),".xtra"),_=F.default.join(O,"audit.enc")});var Se={};q(Se,{templateCommand:()=>D});module.exports=M(Se);var ge=require("commander");K();I();var a=l(require("chalk")),N=l(require("ora")),m=l(require("fs")),$=l(require("path")),P=/\{\{\s*(secrets|env)\.([A-Z0-9_a-z]+)(?:\s*\|\s*([^}]*?))?\s*\}\}/g;function de(e,t,s){let n=[],r=[],c=0;return{output:e.replace(P,(u,i,p,S)=>{let g;if(i==="secrets"?g=t[p]:i==="env"&&(g=s[p]),g!==void 0&&g!=="")return c++,g;if(S!==void 0){let f=S.trim();return r.push(`${i}.${p} \xE2\u2020\u2019 "${f}"`),c++,f}return n.push(`${i}.${p}`),`{{ ${i}.${p} }}`}),replacedCount:c,missingKeys:n,usedDefaults:r}}var D=new ge.Command("template").description("Secret templating engine \xE2\u20AC\u201D inject secrets into config file templates").addHelpText("after",`
|
|
1
|
+
var Re=Object.create;var U=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Ke=Object.getPrototypeOf,_e=Object.prototype.hasOwnProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var V=(e,t)=>{for(var r in t)U(e,r,{get:t[r],enumerable:!0})},ie=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ee(t))!_e.call(e,n)&&n!==r&&U(e,n,{get:()=>t[n],enumerable:!(s=Te(t,n))||s.enumerable});return e};var m=(e,t,r)=>(r=e!=null?Re(Ke(e)):{},ie(t||!e||!e.__esModule?U(r,"default",{value:e,enumerable:!0}):r,e)),P=e=>ie(U({},"__esModule",{value:!0}),e);var q={};V(q,{createWorkloadKeyEnvelope:()=>Ue,decrypt:()=>J,decryptSecretValue:()=>De,decryptWorkloadKeyEnvelope:()=>Le,deriveProjectKey:()=>Ce,encrypt:()=>H,encryptSecretValue:()=>Be,hash:()=>Ie,resolveVaultPassphrase:()=>le,saveVaultPassphrase:()=>Oe,secureRead:()=>_,secureSave:()=>K});function ge(){if(N)return N;let e=F.get("masterKey");e||(e=u.default.randomBytes(32).toString("hex"),F.set("masterKey",e));let t="";try{t=(0,ae.machineIdSync)()||""}catch{t=u.default.createHash("sha256").update($.default.hostname()+($.default.userInfo?.()?.username||"root")).digest("hex")}let r=$.default.platform(),s=$.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return N=u.default.createHash("sha256").update(n).digest(),N}function Ce(e,t){t||(t=le(void 0,e));let r=Buffer.from(`project_salt_${e}`),s=Buffer.from("xtra-e2ee-project-key-v2"),n=u.default.hkdfSync("sha256",Buffer.from(t),r,s,32);return Buffer.from(n).toString("hex")}function Be(e,t){let r=u.default.randomBytes(12),s=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=u.default.createCipheriv("aes-256-gcm",s,r),i=n.update(e,"utf8","hex");i+=n.final("hex");let g=n.getAuthTag().toString("hex");return{ciphertext:i,iv:r.toString("hex"),authTag:g}}function De(e,t){let r=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.authTag,"hex"),i=u.default.createDecipheriv("aes-256-gcm",r,s);i.setAuthTag(n);let g=i.update(e.ciphertext,"hex","utf8");return g+=i.final("utf8"),g}function le(e,t){if(e&&e.trim())return e.trim();if(process.env.XTRA_VAULT_PASSPHRASE&&process.env.XTRA_VAULT_PASSPHRASE.trim())return process.env.XTRA_VAULT_PASSPHRASE.trim();if(process.env.XTRA_MASTER_SECRET&&process.env.XTRA_MASTER_SECRET.trim())return process.env.XTRA_MASTER_SECRET.trim();try{if(t){let s=_(`vault_${t}`);if(s)return s}let r=_("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(I(),P(ue)),s=r();if(s&&s.passphrase)return s.passphrase}catch{}throw new Error("Vault Passphrase or Master Secret is required for Zero-Knowledge E2EE encryption/decryption.")}function Oe(e,t){t&&K(`vault_${t}`,e),K("vault_passphrase",e)}function Ue(e,t){let{publicKey:r,privateKey:s}=u.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),i=u.default.createPublicKey(t),g=u.default.diffieHellman({privateKey:s,publicKey:i}),l=Buffer.from(u.default.hkdfSync("sha256",g,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),c=u.default.randomBytes(12),p=u.default.createCipheriv("aes-256-gcm",l,c),h=p.update(e,"utf8","hex");h+=p.final("hex");let d=p.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:h,iv:c.toString("hex"),authTag:d}}function Le(e,t){let r=u.default.createPrivateKey(t),s=u.default.createPublicKey(e.ephemeralPublicKey),n=u.default.diffieHellman({privateKey:r,publicKey:s}),i=Buffer.from(u.default.hkdfSync("sha256",n,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),g=Buffer.from(e.iv,"hex"),l=Buffer.from(e.authTag,"hex"),c=u.default.createDecipheriv("aes-256-gcm",i,g);c.setAuthTag(l);let p=c.update(e.encryptedProjectKey,"hex","utf8");return p+=c.final("utf8"),p}var u,$,ce,ae,E,pe,F,N,H,J,Ie,K,_,R=L(()=>{u=m(require("crypto")),$=m(require("os")),ce=m(require("conf")),ae=require("node-machine-id"),E=require("child_process"),pe="aes-256-gcm",F=new ce.default({projectName:"xtra-cli-crypto"}),N=null;H=e=>{let t=u.default.randomBytes(12),r=ge(),s=u.default.createCipheriv(pe,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let i=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:i.toString("hex")}},J=e=>{let t=ge(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=u.default.createDecipheriv(pe,t,r);n.setAuthTag(s);let i=n.update(e.content,"hex","utf8");return i+=n.final("utf8"),i},Ie=e=>u.default.createHash("sha256").update(e).digest("hex"),K=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if($.default.platform()==="darwin"){(0,E.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if($.default.platform()!=="win32"){if($.default.platform()==="linux")try{(0,E.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=H(t);F.set(`secure_${e}`,JSON.stringify(r))},_=e=>{try{let t="XtraSecurityCLI",r=e;if($.default.platform()==="darwin")return(0,E.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if($.default.platform()!=="win32"){if($.default.platform()==="linux")try{return(0,E.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=F.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return J(r)}catch{return null}}});var ue={};V(ue,{clearConfig:()=>Fe,deleteConfig:()=>He,getAuthToken:()=>C,getBreakGlassSession:()=>Je,getConfig:()=>A,getConfigValue:()=>Ve,getProjectConfig:()=>We,getRcConfig:()=>W,setBreakGlassSession:()=>qe,setConfig:()=>Ne});var fe,b,Q,ee,y,de,A,Ve,Ne,Fe,He,C,Je,qe,We,W,I=L(()=>{fe=m(require("conf")),b=m(require("fs")),Q=m(require("path"));R();ee="https://www.xtrasecurity.in/api",y=new fe.default({projectName:"xtra-cli",defaults:{apiUrl:ee}}),de=y.get("apiUrl");de&&!process.env.XTRA_API_URL&&de.includes("xtra-security.vercel.app")&&y.set("apiUrl",ee);A=()=>({...y.store,token:C(),apiUrl:process.env.XTRA_API_URL||y.get("apiUrl")||ee}),Ve=e=>e==="token"?C():y.get(e),Ne=(e,t)=>{if(e==="token"&&t&&K("token",t),y.set(e,t),e==="token"&&process.platform!=="win32"&&b.default.existsSync(y.path))try{b.default.chmodSync(y.path,384)}catch{}},Fe=()=>y.clear(),He=e=>y.delete(e),C=()=>_("token")||y.get("token"),Je=()=>y.get("breakGlassSessionId"),qe=e=>{e?y.set("breakGlassSessionId",e):y.delete("breakGlassSessionId")},We=async()=>{try{let e=Q.default.join(process.cwd(),"xtra.json");if(b.default.existsSync(e)){let t=b.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},W=()=>{let e={};try{let t=Q.default.join(process.cwd(),".xtrarc");b.default.existsSync(t)&&(e=JSON.parse(b.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||y.get("project")||"",env:e.env||y.get("env")||"development",branch:e.branch||y.get("branch")||"main"}}});var ye,me,he,Xe,o,B,te=L(()=>{ye=m(require("axios"));I();me=m(require("fs")),he=m(require("path")),Xe=JSON.parse(me.readFileSync(he.join(__dirname,"../../package.json"),"utf-8")),o=e=>{let{apiUrl:t}=A(),r=e||C();return ye.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Xe.version,...r?{Authorization:`Bearer ${r}`}:{}}})},B={login:async(e,t,r)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,exchangeOidcToken:async(e,t)=>{let r=await o().post("/v2/auth/oidc/token",{provider:e,token:t});return{accessToken:r.data.access_token,envelope:r.data.envelope}},spawnAgentContext:async e=>(await o().post("/agents/ephemeral-context",e)).data,getSecrets:async(e,t,r="main",s,n,i)=>{let l=(await o(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(l&&typeof l=="object"){let c=null,{deriveProjectKey:p,decryptSecretValue:h,resolveVaultPassphrase:d,decryptWorkloadKeyEnvelope:f}=(R(),P(q));for(let[x,v]of Object.entries(l))if(typeof v=="string"&&v.startsWith("{"))try{let S=JSON.parse(v);if(S.ciphertext&&S.iv){if(!c)if(i&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)c=f(i,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let D=d(s,e);c=p(e,D)}l[x]=h(S,c)}}catch(S){if(S.message&&S.message.includes("Zero-Knowledge"))throw S}}return l},getSecretVersions:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>{let{deriveProjectKey:i,encryptSecretValue:g,resolveVaultPassphrase:l}=(R(),P(q)),c=l(void 0,e),p=i(e,c),h={};for(let[f,x]of Object.entries(r))if(typeof x=="string"&&x.startsWith("{")&&x.includes("ciphertext"))h[f]=x;else{let v=g(x,p);h[f]=JSON.stringify(v)}return(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:h,expectedVersions:s,branch:n})).data},getSecretDetails:async(e,t,r,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,getSecretsV2:async(e,t)=>{let r=t?`&branchId=${t}`:"";return(await o().get(`/v2/secret?projectId=${e}${r}`)).data},createSecretV2:async e=>(await o().post("/v2/secret",e)).data,updateSecretV2:async e=>(await o().put(`/v2/secret?id=${e.id}`,e)).data,deleteSecretV2:async e=>(await o().delete(`/v2/secret?id=${e}`)).data,bulkImportV2:async e=>(await o().post("/v2/secret/bulk",e)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,i)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:i})).data,rotateSecret:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=A(),r=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=A(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await o().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await o().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await o().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await o().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await o().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,r,s)=>(await o().post(`/projects/${e}/service-accounts/${t}/keys`,{label:r,expiresAt:s})).data,deleteServiceAccountKey:async(e,t,r)=>(await o().delete(`/projects/${e}/service-accounts/${t}/keys/${r}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});var Se={};V(Se,{loadAuditLogs:()=>X,logAudit:()=>Ge,saveAuditLogs:()=>M,syncAuditLogs:()=>Ye});function Me(e){if(!e||typeof e!="object")return e;let t={...e},r=["password","token","secret","value","apiKey","secretValue"];for(let s of Object.keys(t))r.some(n=>s.toLowerCase().includes(n))&&(t[s]="[REDACTED]");return t}async function xe(e){try{if(!A().token)return!1;let r={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:Me(e.details),timestamp:e.timestamp,projectId:e.projectId};return await B.post("/audit/cli-logs",{logs:[r]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function Ge(e,t,r,s){let n={id:(0,ve.randomUUID)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:r,details:s,synced:!1},i=X();i.push(n),M(i),xe(n).then(g=>{if(g){n.synced=!0;let l=X(),c=l.findIndex(p=>p.id===n.id);c!==-1&&(l[c].synced=!0,M(l))}}).catch(()=>{})}function X(){if(!T.default.existsSync(se))return[];try{let e=T.default.readFileSync(se,"utf-8"),t=JSON.parse(e),r=J(t);return JSON.parse(r)}catch{return[]}}function M(e){T.default.existsSync(re)||T.default.mkdirSync(re,{recursive:!0});let t=JSON.stringify(e),r=H(t);T.default.writeFileSync(se,JSON.stringify(r),"utf-8")}async function Ye(){let e=X(),t=e.filter(s=>!s.synced);if(t.length===0)return 0;let r=0;for(let s of t)await xe(s)&&(s.synced=!0,r++);return r>0&&M(e),r}var T,ne,ve,re,se,we=L(()=>{T=m(require("fs")),ne=m(require("path")),ve=require("crypto");R();I();te();re=ne.default.join(process.cwd(),".xtra"),se=ne.default.join(re,"audit.enc")});var ze={};V(ze,{templateCommand:()=>Y});module.exports=P(ze);var $e=require("commander");te();I();var a=m(require("chalk")),oe=m(require("ora")),j=m(require("fs")),k=m(require("path")),G=/\{\{\s*(secrets|env)\.([A-Z0-9_a-z]+)(?:\s*\|\s*([^}]*?))?\s*\}\}/g;function je(e,t,r){let s=[],n=[],i=0;return{output:e.replace(G,(l,c,p,h)=>{let d;if(c==="secrets"?d=t[p]:c==="env"&&(d=r[p]),d!==void 0&&d!=="")return i++,d;if(h!==void 0){let f=h.trim();return n.push(`${c}.${p} \xE2\u2020\u2019 "${f}"`),i++,f}return s.push(`${c}.${p}`),`{{ ${c}.${p} }}`}),replacedCount:i,missingKeys:s,usedDefaults:n}}var Y=new $e.Command("template").description("Secret templating engine \xE2\u20AC\u201D inject secrets into config file templates").addHelpText("after",`
|
|
2
2
|
Template Syntax:
|
|
3
3
|
{{ secrets.KEY }} Replace with secret value
|
|
4
4
|
{{ secrets.KEY | default }} Replace with secret value, fall back to "default"
|
|
@@ -10,13 +10,13 @@ Examples:
|
|
|
10
10
|
$ xtra template render nginx.conf.tpl -p proj123 -e production | sudo tee /etc/nginx/nginx.conf
|
|
11
11
|
$ xtra template check config.yaml.tpl -p proj123 -e production
|
|
12
12
|
$ xtra template list config.yaml.tpl
|
|
13
|
-
`);
|
|
13
|
+
`);Y.command("render <templateFile>").description("Render a template file by injecting secrets and environment variables").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment (default: development)","development").option("-b, --branch <branch>","Branch name","main").option("-o, --output <file>","Output file (default: stdout)").option("--strict","Exit with error if any placeholder is unresolved",!1).action(async(e,t)=>{let{project:r,env:s,branch:n,output:i,strict:g}=t;s={dev:"development",stg:"staging",prod:"production"}[s]||s,r||(r=W().project),r||(console.error(a.default.red("Error: Project ID required. Use -p <id> or run 'xtra project set'.")),process.exit(1));let c=k.resolve(process.cwd(),e);j.existsSync(c)||(console.error(a.default.red(`Error: Template file not found: ${c}`)),process.exit(1));let p=j.readFileSync(c,"utf8");[...p.matchAll(G)].length===0&&console.warn(a.default.yellow("Warning: No {{ secrets.* }} or {{ env.* }} placeholders found in template."));let d=(0,oe.default)(`Fetching secrets for ${r}/${s}...`).start(),f={};try{f=await B.getSecrets(r,s,n),d.succeed(`Loaded ${Object.keys(f).length} secrets.`);try{let{deriveProjectKey:w,decryptSecretValue:z,resolveVaultPassphrase:be}=(R(),P(q)),Ae=be(void 0,r),ke=w(r,Ae);for(let[Pe,Z]of Object.entries(f))if(typeof Z=="string"&&Z.startsWith("{"))try{let O=JSON.parse(Z);O.ciphertext&&O.iv&&(f[Pe]=z(O,ke))}catch{}}catch{}}catch(w){d.fail("Failed to fetch secrets.");let z=w?.response?.data?.error||w?.response?.data?.error||"An unexpected error occurred";console.error(a.default.red(z)),process.exit(1)}let{output:x,replacedCount:v,missingKeys:S,usedDefaults:D}=je(p,f,process.env);if(console.log(a.default.green(`\u2705 Replaced ${v} placeholder(s).`)),D.length>0&&console.log(a.default.yellow(`\u26A0 Used defaults for: ${D.join(", ")}`)),S.length>0&&(console.log(a.default.red(`\u2717 Unresolved placeholders: ${S.join(", ")}`)),g&&(console.error(a.default.red("Aborting due to --strict mode.")),process.exit(1))),i){let w=k.resolve(process.cwd(),i);j.writeFileSync(w,x,"utf8"),console.log(a.default.blue(`\xE2\u2020\u2019 Written to: ${w}`))}else process.stdout.write(x);try{let{logAudit:w}=(we(),P(Se));w("TEMPLATE_RENDERED",r,s,{template:e,output:i||"stdout",replacedCount:v,missingKeys:S})}catch{}});Y.command("check <templateFile>").description("Validate that all template placeholders have matching secrets (dry-run)").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment","development").option("-b, --branch <branch>","Branch name","main").action(async(e,t)=>{let{project:r,env:s,branch:n}=t;s={dev:"development",stg:"staging",prod:"production"}[s]||s,r||(r=W().project),r||(console.error(a.default.red("Error: Project ID required.")),process.exit(1));let g=k.resolve(process.cwd(),e);j.existsSync(g)||(console.error(a.default.red(`Template file not found: ${g}`)),process.exit(1));let l=j.readFileSync(g,"utf8"),c=(0,oe.default)("Fetching secrets for check...").start(),p={};try{p=await B.getSecrets(r,s,n),c.stop()}catch{c.fail("Failed to fetch secrets."),process.exit(1)}let{replacedCount:h,missingKeys:d,usedDefaults:f}=je(l,p,process.env),x=[...l.matchAll(G)].length;console.log(a.default.bold(`
|
|
14
14
|
Template Check: ${e}
|
|
15
|
-
`)),console.log(` Total placeholders : ${
|
|
16
|
-
Defaults used:`)),f.forEach(v=>console.log(` - ${v}`))),
|
|
17
|
-
Missing secrets (no default):`)),
|
|
18
|
-
\u2705 All placeholders are resolvable!`))});
|
|
19
|
-
Placeholders in ${
|
|
20
|
-
`)),
|
|
21
|
-
Total: ${a.default.bold(
|
|
15
|
+
`)),console.log(` Total placeholders : ${x}`),console.log(` Resolved : ${a.default.green(h)}`),console.log(` Using defaults : ${a.default.yellow(f.length)}`),console.log(` Unresolved : ${a.default.red(d.length)}`),f.length>0&&(console.log(a.default.yellow(`
|
|
16
|
+
Defaults used:`)),f.forEach(v=>console.log(` - ${v}`))),d.length>0?(console.log(a.default.red(`
|
|
17
|
+
Missing secrets (no default):`)),d.forEach(v=>console.log(a.default.red(` \u2717 ${v}`))),process.exit(1)):console.log(a.default.green(`
|
|
18
|
+
\u2705 All placeholders are resolvable!`))});Y.command("list <templateFile>").description("List all placeholders found in a template file (no API call needed)").action(e=>{let t=k.resolve(process.cwd(),e);j.existsSync(t)||(console.error(a.default.red(`Template file not found: ${t}`)),process.exit(1));let s=[...j.readFileSync(t,"utf8").matchAll(G)];if(s.length===0){console.log(a.default.yellow("No placeholders found in this template."));return}console.log(a.default.bold(`
|
|
19
|
+
Placeholders in ${k.basename(e)}:
|
|
20
|
+
`)),s.forEach(n=>{let[,i,g,l]=n,c=l?a.default.gray(` (default: "${l.trim()}")`):"";console.log(` ${i==="secrets"?"\u{1F512}":"\u{1F4E6}"} ${a.default.cyan(`{{ ${i}.${g} }}`)}${c}`)}),console.log(`
|
|
21
|
+
Total: ${a.default.bold(s.length)} placeholder(s)
|
|
22
22
|
`)});0&&(module.exports={templateCommand});
|
package/dist/commands/ui.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var de=Object.create;var T=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var he=Object.getPrototypeOf,me=Object.prototype.hasOwnProperty;var ye=(e,t)=>{for(var s in t)T(e,s,{get:t[s],enumerable:!0})},J=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ue(t))!me.call(e,o)&&o!==s&&T(e,o,{get:()=>t[o],enumerable:!(r=le(t,o))||r.enumerable});return e};var b=(e,t,s)=>(s=e!=null?de(he(e)):{},J(t||!e||!e.__esModule?T(s,"default",{value:e,enumerable:!0}):s,e)),fe=e=>J(T({},"__esModule",{value:!0}),e);var ve={};ye(ve,{uiCommand:()=>xe});module.exports=fe(ve);var ee=require("commander"),n=b(require("chalk")),te=b(require("readline"));var X=b(require("axios"));var K=b(require("conf")),_=b(require("fs")),F=b(require("path")),M="https://www.xtrasecurity.in/api",x=new K.default({projectName:"xtra-cli",defaults:{apiUrl:M}}),H=x.get("apiUrl");H&&!process.env.XTRA_API_URL&&H.includes("xtra-security.vercel.app")&&x.set("apiUrl",M);var P=()=>({...x.store,apiUrl:process.env.XTRA_API_URL||x.get("apiUrl")||M});var W=()=>x.get("token");var Q=()=>{let e={};try{let t=F.default.join(process.cwd(),".xtrarc");_.default.existsSync(t)&&(e=JSON.parse(_.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||x.get("project")||"",env:e.env||x.get("env")||"development",branch:e.branch||x.get("branch")||"main"}};var Y=b(require("fs")),z=b(require("path")),we=JSON.parse(Y.readFileSync(z.join(__dirname,"../../package.json"),"utf-8")),a=()=>{let{apiUrl:e}=P(),t=W();return X.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":we.version,...t?{Authorization:`Bearer ${t}`}:{}}})},O={login:async(e,t,s)=>(await a().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await a().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await a().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,r,o="main")=>(await a().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:r,branch:o})).data,getSecretDetails:async(e,t,s,r="main")=>(await a().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${r}`)).data,syncLogs:async e=>(await a().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,r,o,c)=>(await a().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:r,sourceEnv:o,sourceKey:c})).data,rotateSecret:async(e,t,s,r,o)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:r,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await a().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,r)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),r&&(o.projectId=r),(await a().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,r)=>(await a().post("/access/request",{projectId:e,secretId:r,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await a().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=P(),s=t?`&workspaceId=${t}`:"";return(await a().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await a().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=P(),t=e?`/project?workspaceId=${e}`:"/project";return(await a().get(t)).data},getBranches:async e=>(await a().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await a().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await a().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await a().put("/branch",{id:e,...t})).data,getRoles:async()=>(await a().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await a().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await a().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await a().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await a().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await a().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await a().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await a().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,r)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:r})).data,cloneEnvironment:async(e,t,s,r,o)=>(await a().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:r,branch:o})).data,generateJitLink:async e=>(await a().post("/jit/generate",e)).data,claimJitLink:async e=>(await a().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await a().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await a().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await a().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await a().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await a().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,s,r)=>(await a().post(`/projects/${e}/service-accounts/${t}/keys`,{label:s,expiresAt:r})).data,deleteServiceAccountKey:async(e,t,s)=>(await a().delete(`/projects/${e}/service-accounts/${t}/keys/${s}`)).data,post:async(e,t)=>(await a().post(e,t)).data};var u=["development","staging","production"],U={development:n.default.green,staging:n.default.yellow,production:n.default.red},V=process.stdout.columns||120,$={tl:"\u256D",tr:"\u256E",bl:"\u2570",br:"\u256F",h:"\u2500",v:"\u2502",x:"\u253C",lt:"\u251C",rt:"\u2524",tt:"\u252C",bt:"\u2534"};function j(e,t=$.h){return t.repeat(e)}function D(e,t,s,r){let o=r?n.default.cyan:n.default.hex("#2d3a4d"),c=s-2,h=g=>g.padEnd(c).slice(0,c),k=r?n.default.bold.cyan(` ${e} `):n.default.hex("#4a5568")(` ${e} `),S=o($.tl)+k+o(j(c-e.length-2))+o($.tr),B=t.map(g=>o($.v)+g.slice(0,c).padEnd(c)+o($.v)),E=o($.bl)+o(j(c))+o($.br);return[S,...B,E]}function Z(){process.stdout.write("\x1B[H\x1B[2J\x1B[3J")}async function be(){let e="projects",t=[],s=0,r=0,o=[],c=0,h="Loading\u2026",k=!1,S=!1;async function B(){h="Loading projects\u2026",g();try{let d=await O.getProjects();t=Array.isArray(d)?d:d.projects??[],h=t.length>0?`${t.length} project(s) found \xB7 \u2191\u2193 navigate \xB7 Enter to load secrets`:"No projects found. Run `xtra login` first."}catch(d){h=n.default.red(`\u2717 ${d?.response?.data?.error||"An unexpected error occurred"}`)}g()}async function E(){if(t[s]){k=!0,h=`Fetching secrets for ${n.default.cyan(t[s].name)} / ${U[u[r]](u[r])}\u2026`,g();try{let p=Q().branch||"main",f=await O.getSecrets(t[s].id,u[r],p);f&&typeof f=="object"&&!Array.isArray(f)?o=Object.entries(f).map(([m,v])=>({id:m,key:m,value:String(v),updatedAt:new Date().toISOString()})):Array.isArray(f)?o=f:o=[],c=0,h=o.length>0?`${o.length} secret(s) \xB7 V toggle values \xB7 Tab switch panel \xB7 Q quit`:"No secrets in this environment."}catch(d){o=[],h=n.default.red(`\u2717 ${d?.response?.data?.error||"An unexpected error occurred"}`)}k=!1,g()}}function g(){Z();let d=n.default.bold.cyan(" \u{1F512} XtraSecurity")+n.default.hex("#4a5a6b")(" \u2014 Interactive Secrets Shell"),p=U[u[r]]?U[u[r]](u[r]):n.default.white(u[r]),f=t[s]?n.default.hex("#4a5568")(` ${t[s].name} `)+n.default.hex("#4a5568")("/")+n.default.hex("#4a5568")(` ${u[r]}`):n.default.hex("#4a5568")(" No project selected");console.log(),console.log(d+n.default.hex("#2d3a4d")(" \u2502")+f),console.log(n.default.hex("#1e293b")(j(V))),console.log();let m=26,v=V-m-3,se=(t.length>0?t:[{id:"",name:"(loading\u2026)"}]).map((i,y)=>{let l=y===s,A=l?n.default.cyan("\u25B6 "):" ",I=l&&e==="projects"?n.default.bold.bgCyan.black(` ${i.name} `.padEnd(m-4)):l?n.default.bold.cyan(i.name):n.default.hex("#6b7c93")(i.name);return` ${A}${I}`}),ne=D("PROJECTS",se,m,e==="projects"),re=u.map((i,y)=>{let l=y===r,A=l?n.default.cyan("\u25B6 "):" ",I=U[i]??n.default.white,L=l&&e==="env"?n.default.bold.bgCyan.black(` ${i} `.padEnd(m-4)):l?I.bold(i):n.default.hex("#6b7c93")(i);return` ${A}${L}`}),oe=D("ENVIRONMENT",re,m,e==="env"),R=Math.floor((v-3)*.45),w=Math.floor((v-3)*.35),N=v-R-w-4,ae=n.default.bold.hex("#64748b")("KEY".padEnd(R))+" "+n.default.bold.hex("#64748b")("VALUE".padEnd(w))+" "+n.default.bold.hex("#64748b")("UPDATED".padEnd(N)),ce=n.default.hex("#1e293b")(j(R)+" "+j(w)+" "+j(N)),C;k?C=[` ${n.default.cyan("\u280B")} Loading\u2026`]:o.length===0?C=[` ${n.default.hex("#4a5568")("No secrets in this environment.")}`]:C=[" "+ae," "+ce,...o.map((i,y)=>{let l=y===c&&e==="secrets",A=i.key.padEnd(R).slice(0,R),I=S?i.value.padEnd(w).slice(0,w):"\u25CF".repeat(Math.min(8,w)).padEnd(w).slice(0,w),L=new Date(i.updatedAt).toLocaleDateString("en-GB",{day:"2-digit",month:"short"}).padEnd(N);return l?n.default.bold.bgHex("#0e243e")(" \u25B6 "+n.default.cyan(A)+" "+n.default.greenBright(I)+" "+n.default.hex("#4a9eff")(L)+" "):" "+n.default.white(A)+" "+n.default.hex("#4a5568")(I)+" "+n.default.hex("#374151")(L)})];let G=D(`SECRETS (${o.length})`,C,v,e==="secrets"),q=[...ne,"","",...oe],ie=Math.max(q.length,G.length),pe=n.default.hex("#1e293b")(" \u2502 ");for(let i=0;i<ie;i++){let y=q[i]??" ".repeat(m),l=G[i]??" ".repeat(v);console.log(y+pe+l)}console.log(),console.log(n.default.hex("#1e293b")(j(V)));let ge=[[n.default.hex("#64748b")("\u2191\u2193"),"Navigate"],[n.default.hex("#64748b")("Enter"),"Select"],[n.default.hex("#64748b")("Tab"),"Switch Panel"],[n.default.hex("#64748b")("V"),S?n.default.green("Hide values"):n.default.yellow("Show values")],[n.default.hex("#64748b")("Q"),"Quit"]].map(([i,y])=>`${i} ${n.default.hex("#374151")(y)}`).join(n.default.hex("#1e293b")(" \xB7 "));console.log(" "+ge),console.log(),console.log(" "+(h||""))}te.emitKeypressEvents(process.stdin),process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.on("keypress",async(d,p)=>{if(p){if((p.name==="q"||p.ctrl&&p.name==="c")&&(process.stdin.isTTY&&process.stdin.setRawMode(!1),Z(),console.log(n.default.cyan(` Goodbye! \u{1F44B}
|
|
2
|
-
`)),process.exit(0)),
|
|
1
|
+
var _e=Object.create;var M=Object.defineProperty;var Be=Object.getOwnPropertyDescriptor;var Ie=Object.getOwnPropertyNames;var Ce=Object.getPrototypeOf,Ve=Object.prototype.hasOwnProperty;var oe=(e,t)=>()=>(e&&(t=e(e=0)),t);var F=(e,t)=>{for(var r in t)M(e,r,{get:t[r],enumerable:!0})},ae=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ie(t))!Ve.call(e,n)&&n!==r&&M(e,n,{get:()=>t[n],enumerable:!(s=Be(t,n))||s.enumerable});return e};var b=(e,t,r)=>(r=e!=null?_e(Ce(e)):{},ae(t||!e||!e.__esModule?M(r,"default",{value:e,enumerable:!0}):r,e)),H=e=>ae(M({},"__esModule",{value:!0}),e);var Y={};F(Y,{createWorkloadKeyEnvelope:()=>He,decrypt:()=>le,decryptSecretValue:()=>Ne,decryptWorkloadKeyEnvelope:()=>We,deriveProjectKey:()=>Ue,encrypt:()=>ue,encryptSecretValue:()=>Oe,hash:()=>Le,resolveVaultPassphrase:()=>de,saveVaultPassphrase:()=>Me,secureRead:()=>V,secureSave:()=>C});function ge(){if(W)return W;let e=D.get("masterKey");e||(e=p.default.randomBytes(32).toString("hex"),D.set("masterKey",e));let t="";try{t=(0,ie.machineIdSync)()||""}catch{t=p.default.createHash("sha256").update($.default.hostname()+($.default.userInfo?.()?.username||"root")).digest("hex")}let r=$.default.platform(),s=$.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return W=p.default.createHash("sha256").update(n).digest(),W}function Ue(e,t){t||(t=de(void 0,e));let r=Buffer.from(`project_salt_${e}`),s=Buffer.from("xtra-e2ee-project-key-v2"),n=p.default.hkdfSync("sha256",Buffer.from(t),r,s,32);return Buffer.from(n).toString("hex")}function Oe(e,t){let r=p.default.randomBytes(12),s=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=p.default.createCipheriv("aes-256-gcm",s,r),c=n.update(e,"utf8","hex");c+=n.final("hex");let g=n.getAuthTag().toString("hex");return{ciphertext:c,iv:r.toString("hex"),authTag:g}}function Ne(e,t){let r=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.authTag,"hex"),c=p.default.createDecipheriv("aes-256-gcm",r,s);c.setAuthTag(n);let g=c.update(e.ciphertext,"hex","utf8");return g+=c.final("utf8"),g}function de(e,t){if(e&&e.trim())return e.trim();if(process.env.XTRA_VAULT_PASSPHRASE&&process.env.XTRA_VAULT_PASSPHRASE.trim())return process.env.XTRA_VAULT_PASSPHRASE.trim();if(process.env.XTRA_MASTER_SECRET&&process.env.XTRA_MASTER_SECRET.trim())return process.env.XTRA_MASTER_SECRET.trim();try{if(t){let s=V(`vault_${t}`);if(s)return s}let r=V("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(q(),H(fe)),s=r();if(s&&s.passphrase)return s.passphrase}catch{}throw new Error("Vault Passphrase or Master Secret is required for Zero-Knowledge E2EE encryption/decryption.")}function Me(e,t){t&&C(`vault_${t}`,e),C("vault_passphrase",e)}function He(e,t){let{publicKey:r,privateKey:s}=p.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),c=p.default.createPublicKey(t),g=p.default.diffieHellman({privateKey:s,publicKey:c}),f=Buffer.from(p.default.hkdfSync("sha256",g,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),u=p.default.randomBytes(12),v=p.default.createCipheriv("aes-256-gcm",f,u),w=v.update(e,"utf8","hex");w+=v.final("hex");let d=v.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:w,iv:u.toString("hex"),authTag:d}}function We(e,t){let r=p.default.createPrivateKey(t),s=p.default.createPublicKey(e.ephemeralPublicKey),n=p.default.diffieHellman({privateKey:r,publicKey:s}),c=Buffer.from(p.default.hkdfSync("sha256",n,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),g=Buffer.from(e.iv,"hex"),f=Buffer.from(e.authTag,"hex"),u=p.default.createDecipheriv("aes-256-gcm",c,g);u.setAuthTag(f);let v=u.update(e.encryptedProjectKey,"hex","utf8");return v+=u.final("utf8"),v}var p,$,ce,ie,I,pe,D,W,ue,le,Le,C,V,X=oe(()=>{p=b(require("crypto")),$=b(require("os")),ce=b(require("conf")),ie=require("node-machine-id"),I=require("child_process"),pe="aes-256-gcm",D=new ce.default({projectName:"xtra-cli-crypto"}),W=null;ue=e=>{let t=p.default.randomBytes(12),r=ge(),s=p.default.createCipheriv(pe,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let c=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:c.toString("hex")}},le=e=>{let t=ge(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=p.default.createDecipheriv(pe,t,r);n.setAuthTag(s);let c=n.update(e.content,"hex","utf8");return c+=n.final("utf8"),c},Le=e=>p.default.createHash("sha256").update(e).digest("hex"),C=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if($.default.platform()==="darwin"){(0,I.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if($.default.platform()!=="win32"){if($.default.platform()==="linux")try{(0,I.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=ue(t);D.set(`secure_${e}`,JSON.stringify(r))},V=e=>{try{let t="XtraSecurityCLI",r=e;if($.default.platform()==="darwin")return(0,I.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if($.default.platform()!=="win32"){if($.default.platform()==="linux")try{return(0,I.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=D.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return le(r)}catch{return null}}});var fe={};F(fe,{clearConfig:()=>qe,deleteConfig:()=>Je,getAuthToken:()=>U,getBreakGlassSession:()=>Ge,getConfig:()=>L,getConfigValue:()=>De,getProjectConfig:()=>Ye,getRcConfig:()=>z,setBreakGlassSession:()=>Fe,setConfig:()=>Xe});var ye,P,Q,Z,y,he,L,De,Xe,qe,Je,U,Ge,Fe,Ye,z,q=oe(()=>{ye=b(require("conf")),P=b(require("fs")),Q=b(require("path"));X();Z="https://www.xtrasecurity.in/api",y=new ye.default({projectName:"xtra-cli",defaults:{apiUrl:Z}}),he=y.get("apiUrl");he&&!process.env.XTRA_API_URL&&he.includes("xtra-security.vercel.app")&&y.set("apiUrl",Z);L=()=>({...y.store,token:U(),apiUrl:process.env.XTRA_API_URL||y.get("apiUrl")||Z}),De=e=>e==="token"?U():y.get(e),Xe=(e,t)=>{if(e==="token"&&t&&C("token",t),y.set(e,t),e==="token"&&process.platform!=="win32"&&P.default.existsSync(y.path))try{P.default.chmodSync(y.path,384)}catch{}},qe=()=>y.clear(),Je=e=>y.delete(e),U=()=>V("token")||y.get("token"),Ge=()=>y.get("breakGlassSessionId"),Fe=e=>{e?y.set("breakGlassSessionId",e):y.delete("breakGlassSessionId")},Ye=async()=>{try{let e=Q.default.join(process.cwd(),"xtra.json");if(P.default.existsSync(e)){let t=P.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},z=()=>{let e={};try{let t=Q.default.join(process.cwd(),".xtrarc");P.default.existsSync(t)&&(e=JSON.parse(P.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||y.get("project")||"",env:e.env||y.get("env")||"development",branch:e.branch||y.get("branch")||"main"}}});var et={};F(et,{uiCommand:()=>ze});module.exports=H(et);var Se=require("commander"),o=b(require("chalk")),be=b(require("readline"));var me=b(require("axios"));q();var ve=b(require("fs")),xe=b(require("path")),Qe=JSON.parse(ve.readFileSync(xe.join(__dirname,"../../package.json"),"utf-8")),a=e=>{let{apiUrl:t}=L(),r=e||U();return me.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Qe.version,...r?{Authorization:`Bearer ${r}`}:{}}})},ee={login:async(e,t,r)=>(await a().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,exchangeOidcToken:async(e,t)=>{let r=await a().post("/v2/auth/oidc/token",{provider:e,token:t});return{accessToken:r.data.access_token,envelope:r.data.envelope}},spawnAgentContext:async e=>(await a().post("/agents/ephemeral-context",e)).data,getSecrets:async(e,t,r="main",s,n,c)=>{let f=(await a(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(f&&typeof f=="object"){let u=null,{deriveProjectKey:v,decryptSecretValue:w,resolveVaultPassphrase:d,decryptWorkloadKeyEnvelope:m}=(X(),H(Y));for(let[i,x]of Object.entries(f))if(typeof x=="string"&&x.startsWith("{"))try{let h=JSON.parse(x);if(h.ciphertext&&h.iv){if(!u)if(c&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)u=m(c,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let A=d(s,e);u=v(e,A)}f[i]=w(h,u)}}catch(h){if(h.message&&h.message.includes("Zero-Knowledge"))throw h}}return f},getSecretVersions:async(e,t,r="main")=>(await a().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>{let{deriveProjectKey:c,encryptSecretValue:g,resolveVaultPassphrase:f}=(X(),H(Y)),u=f(void 0,e),v=c(e,u),w={};for(let[m,i]of Object.entries(r))if(typeof i=="string"&&i.startsWith("{")&&i.includes("ciphertext"))w[m]=i;else{let x=g(i,v);w[m]=JSON.stringify(x)}return(await a().post(`/projects/${e}/envs/${t}/secrets`,{secrets:w,expectedVersions:s,branch:n})).data},getSecretDetails:async(e,t,r,s="main")=>(await a().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,getSecretsV2:async(e,t)=>{let r=t?`&branchId=${t}`:"";return(await a().get(`/v2/secret?projectId=${e}${r}`)).data},createSecretV2:async e=>(await a().post("/v2/secret",e)).data,updateSecretV2:async e=>(await a().put(`/v2/secret?id=${e.id}`,e)).data,deleteSecretV2:async e=>(await a().delete(`/v2/secret?id=${e}`)).data,bulkImportV2:async e=>(await a().post("/v2/secret/bulk",e)).data,syncLogs:async e=>(await a().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,c)=>(await a().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:c})).data,rotateSecret:async(e,t,r,s,n)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await a().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await a().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await a().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await a().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=L(),r=t?`&workspaceId=${t}`:"";return(await a().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await a().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=L(),t=e?`/project?workspaceId=${e}`:"/project";return(await a().get(t)).data},getBranches:async e=>(await a().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await a().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await a().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await a().put("/branch",{id:e,...t})).data,getRoles:async()=>(await a().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await a().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await a().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await a().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await a().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await a().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await a().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await a().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await a().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await a().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await a().post("/jit/generate",e)).data,claimJitLink:async e=>(await a().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await a().get(`/jit/${e}`)).data,getServiceAccounts:async e=>(await a().get(`/projects/${e}/service-accounts`)).data,createServiceAccount:async(e,t)=>(await a().post(`/projects/${e}/service-accounts`,t)).data,deleteServiceAccount:async(e,t)=>(await a().delete(`/projects/${e}/service-accounts/${t}`)).data,getServiceAccountKeys:async(e,t)=>(await a().get(`/projects/${e}/service-accounts/${t}/keys`)).data,createServiceAccountKey:async(e,t,r,s)=>(await a().post(`/projects/${e}/service-accounts/${t}/keys`,{label:r,expiresAt:s})).data,deleteServiceAccountKey:async(e,t,r)=>(await a().delete(`/projects/${e}/service-accounts/${t}/keys/${r}`)).data,post:async(e,t)=>(await a().post(e,t)).data};q();var j=["development","staging","production"],J={development:o.default.green,staging:o.default.yellow,production:o.default.red},te=process.stdout.columns||120,R={tl:"\u256D",tr:"\u256E",bl:"\u2570",br:"\u256F",h:"\u2500",v:"\u2502",x:"\u253C",lt:"\u251C",rt:"\u2524",tt:"\u252C",bt:"\u2534"};function E(e,t=R.h){return t.repeat(e)}function re(e,t,r,s){let n=s?o.default.cyan:o.default.hex("#2d3a4d"),c=r-2,g=d=>d.padEnd(c).slice(0,c),f=s?o.default.bold.cyan(` ${e} `):o.default.hex("#4a5568")(` ${e} `),u=n(R.tl)+f+n(E(c-e.length-2))+n(R.tr),v=t.map(d=>n(R.v)+d.slice(0,c).padEnd(c)+n(R.v)),w=n(R.bl)+n(E(c))+n(R.br);return[u,...v,w]}function we(){process.stdout.write("\x1B[H\x1B[2J\x1B[3J")}async function Ze(){let e="projects",t=[],r=0,s=0,n=[],c=0,g="Loading\u2026",f=!1,u=!1;async function v(){g="Loading projects\u2026",d();try{let m=await ee.getProjects();t=Array.isArray(m)?m:m.projects??[],g=t.length>0?`${t.length} project(s) found \xB7 \u2191\u2193 navigate \xB7 Enter to load secrets`:"No projects found. Run `xtra login` first."}catch(m){g=o.default.red(`\u2717 ${m?.response?.data?.error||"An unexpected error occurred"}`)}d()}async function w(){if(t[r]){f=!0,g=`Fetching secrets for ${o.default.cyan(t[r].name)} / ${J[j[s]](j[s])}\u2026`,d();try{let i=z().branch||"main",x=await ee.getSecrets(t[r].id,j[s],i);x&&typeof x=="object"&&!Array.isArray(x)?n=Object.entries(x).map(([h,A])=>({id:h,key:h,value:String(A),updatedAt:new Date().toISOString()})):Array.isArray(x)?n=x:n=[],c=0,g=n.length>0?`${n.length} secret(s) \xB7 V toggle values \xB7 Tab switch panel \xB7 Q quit`:"No secrets in this environment."}catch(m){n=[],g=o.default.red(`\u2717 ${m?.response?.data?.error||"An unexpected error occurred"}`)}f=!1,d()}}function d(){we();let m=o.default.bold.cyan(" \u{1F512} XtraSecurity")+o.default.hex("#4a5a6b")(" \u2014 Interactive Secrets Shell"),i=J[j[s]]?J[j[s]](j[s]):o.default.white(j[s]),x=t[r]?o.default.hex("#4a5568")(` ${t[r].name} `)+o.default.hex("#4a5568")("/")+o.default.hex("#4a5568")(` ${j[s]}`):o.default.hex("#4a5568")(" No project selected");console.log(),console.log(m+o.default.hex("#2d3a4d")(" \u2502")+x),console.log(o.default.hex("#1e293b")(E(te))),console.log();let h=26,A=te-h-3,$e=(t.length>0?t:[{id:"",name:"(loading\u2026)"}]).map((l,T)=>{let S=T===r,K=S?o.default.cyan("\u25B6 "):" ",_=S&&e==="projects"?o.default.bold.bgCyan.black(` ${l.name} `.padEnd(h-4)):S?o.default.bold.cyan(l.name):o.default.hex("#6b7c93")(l.name);return` ${K}${_}`}),je=re("PROJECTS",$e,h,e==="projects"),Ae=j.map((l,T)=>{let S=T===s,K=S?o.default.cyan("\u25B6 "):" ",_=J[l]??o.default.white,N=S&&e==="env"?o.default.bold.bgCyan.black(` ${l} `.padEnd(h-4)):S?_.bold(l):o.default.hex("#6b7c93")(l);return` ${K}${N}`}),Te=re("ENVIRONMENT",Ae,h,e==="env"),B=Math.floor((A-3)*.45),k=Math.floor((A-3)*.35),G=A-B-k-4,ke=o.default.bold.hex("#64748b")("KEY".padEnd(B))+" "+o.default.bold.hex("#64748b")("VALUE".padEnd(k))+" "+o.default.bold.hex("#64748b")("UPDATED".padEnd(G)),Pe=o.default.hex("#1e293b")(E(B)+" "+E(k)+" "+E(G)),O;f?O=[` ${o.default.cyan("\u280B")} Loading\u2026`]:n.length===0?O=[` ${o.default.hex("#4a5568")("No secrets in this environment.")}`]:O=[" "+ke," "+Pe,...n.map((l,T)=>{let S=T===c&&e==="secrets",K=l.key.padEnd(B).slice(0,B),_=u?l.value.padEnd(k).slice(0,k):"\u25CF".repeat(Math.min(8,k)).padEnd(k).slice(0,k),N=new Date(l.updatedAt).toLocaleDateString("en-GB",{day:"2-digit",month:"short"}).padEnd(G);return S?o.default.bold.bgHex("#0e243e")(" \u25B6 "+o.default.cyan(K)+" "+o.default.greenBright(_)+" "+o.default.hex("#4a9eff")(N)+" "):" "+o.default.white(K)+" "+o.default.hex("#4a5568")(_)+" "+o.default.hex("#374151")(N)})];let se=re(`SECRETS (${n.length})`,O,A,e==="secrets"),ne=[...je,"","",...Te],Re=Math.max(ne.length,se.length),Ee=o.default.hex("#1e293b")(" \u2502 ");for(let l=0;l<Re;l++){let T=ne[l]??" ".repeat(h),S=se[l]??" ".repeat(A);console.log(T+Ee+S)}console.log(),console.log(o.default.hex("#1e293b")(E(te)));let Ke=[[o.default.hex("#64748b")("\u2191\u2193"),"Navigate"],[o.default.hex("#64748b")("Enter"),"Select"],[o.default.hex("#64748b")("Tab"),"Switch Panel"],[o.default.hex("#64748b")("V"),u?o.default.green("Hide values"):o.default.yellow("Show values")],[o.default.hex("#64748b")("Q"),"Quit"]].map(([l,T])=>`${l} ${o.default.hex("#374151")(T)}`).join(o.default.hex("#1e293b")(" \xB7 "));console.log(" "+Ke),console.log(),console.log(" "+(g||""))}be.emitKeypressEvents(process.stdin),process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.on("keypress",async(m,i)=>{if(i){if((i.name==="q"||i.ctrl&&i.name==="c")&&(process.stdin.isTTY&&process.stdin.setRawMode(!1),we(),console.log(o.default.cyan(` Goodbye! \u{1F44B}
|
|
2
|
+
`)),process.exit(0)),i.name==="v"){u=!u,d();return}if(i.name==="tab"){e=e==="projects"?"env":e==="env"?"secrets":"projects",d();return}if(e==="projects"&&(i.name==="up"&&(r=Math.max(0,r-1)),i.name==="down"&&(r=Math.min(t.length-1,r+1)),i.name==="return")){e="env",d();return}if(e==="env"&&(i.name==="up"&&(s=Math.max(0,s-1)),i.name==="down"&&(s=Math.min(j.length-1,s+1)),i.name==="return")){e="secrets",await w();return}e==="secrets"&&(i.name==="up"&&(c=Math.max(0,c-1)),i.name==="down"&&(c=Math.min(n.length-1,c+1))),d()}}),await v(),t.length>0?await w():d()}var ze=new Se.Command("ui").description("Launch interactive TUI secrets dashboard (arrow keys, Tab, Q to quit)").action(async()=>{await Ze()});0&&(module.exports={uiCommand});
|