xtra-cli 1.0.8 → 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.
Files changed (43) hide show
  1. package/dist/bin/xtra.js +2 -2
  2. package/dist/commands/access.js +1 -1
  3. package/dist/commands/admin.js +3 -3
  4. package/dist/commands/agent.js +4 -0
  5. package/dist/commands/audit.js +1 -1
  6. package/dist/commands/branch.js +1 -1
  7. package/dist/commands/checkout.js +1 -1
  8. package/dist/commands/ci.js +10 -10
  9. package/dist/commands/diff.js +6 -6
  10. package/dist/commands/doctor.js +2 -2
  11. package/dist/commands/env.js +2 -2
  12. package/dist/commands/export.js +3 -2
  13. package/dist/commands/generate.js +3 -3
  14. package/dist/commands/history.js +4 -4
  15. package/dist/commands/import.js +1 -1
  16. package/dist/commands/init.js +4 -4
  17. package/dist/commands/integration.js +9 -9
  18. package/dist/commands/jit-run.js +5 -5
  19. package/dist/commands/local.js +5 -5
  20. package/dist/commands/login.js +6 -6
  21. package/dist/commands/logout.js +1 -1
  22. package/dist/commands/logs.js +3 -3
  23. package/dist/commands/oidc-link.js +6 -0
  24. package/dist/commands/project.js +1 -1
  25. package/dist/commands/rollback.js +1 -1
  26. package/dist/commands/rotate.js +2 -2
  27. package/dist/commands/run.js +8 -6
  28. package/dist/commands/scan.js +13 -18
  29. package/dist/commands/secrets.js +6 -5
  30. package/dist/commands/service-account.js +5 -5
  31. package/dist/commands/simulate.js +5 -5
  32. package/dist/commands/status.js +2 -2
  33. package/dist/commands/template.js +9 -9
  34. package/dist/commands/ui.js +2 -2
  35. package/dist/commands/watch.js +13 -13
  36. package/dist/lib/api.js +1 -1
  37. package/dist/lib/audit.js +1 -1
  38. package/dist/lib/config.js +1 -1
  39. package/dist/lib/crypto.js +1 -1
  40. package/package.json +3 -3
  41. package/dist/commands/login.test.js +0 -16
  42. package/dist/lib/api.test.js +0 -1
  43. package/dist/lib/config.test.js +0 -1
@@ -1,17 +1,17 @@
1
- var N=Object.create;var l=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var E=(e,t)=>{for(var s in t)l(e,s,{get:t[s],enumerable:!0})},j=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of D(t))!J.call(e,o)&&o!==s&&l(e,o,{get:()=>t[o],enumerable:!(n=B(t,o))||n.enumerable});return e};var d=(e,t,s)=>(s=e!=null?N(q(e)):{},j(t||!e||!e.__esModule?l(s,"default",{value:e,enumerable:!0}):s,e)),M=e=>j(l({},"__esModule",{value:!0}),e);var H={};E(H,{watchCommand:()=>F});module.exports=M(H);var T=require("commander");var C=d(require("axios"));var x=d(require("conf")),w=d(require("fs")),k=d(require("path")),h="https://www.xtrasecurity.in/api",g=new x.default({projectName:"xtra-cli",defaults:{apiUrl:h}}),S=g.get("apiUrl");S&&!process.env.XTRA_API_URL&&S.includes("xtra-security.vercel.app")&&g.set("apiUrl",h);var u=()=>({...g.store,apiUrl:process.env.XTRA_API_URL||g.get("apiUrl")||h});var b=()=>g.get("token");var I=()=>{let e={};try{let t=k.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 A=d(require("fs")),P=d(require("path")),V=JSON.parse(A.readFileSync(P.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=u(),t=b();return C.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":V.version,...t?{Authorization:`Bearer ${t}`}:{}}})},m={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,c)=>(await r().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:c})).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}=u(),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}=u(),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=d(require("chalk")),L=require("child_process"),p=null,f="";function R(e){return JSON.stringify(Object.keys(e).sort().map(t=>`${t}=${e[t]}`))}async function U(e,t,s,n){p&&(process.stdout.write(a.default.cyan(`
2
- [watch] `)+a.default.yellow(`Secret change detected \u2014 restarting...
3
- `)),p.kill("SIGTERM"),await new Promise(c=>setTimeout(c,500)));let o={...process.env,...s};process.stdout.write(a.default.cyan(" [watch] ")+a.default.green(`Starting: ${e} ${t.join(" ")}
4
- `)),p=(0,L.spawn)(e,t,{env:o,stdio:"inherit",shell:n}),p.on("exit",c=>{c!==null&&c!==0&&process.stdout.write(a.default.cyan(" [watch] ")+a.default.red(`Process exited with code ${c}
5
- `)),p=null}),p.on("error",c=>{process.stdout.write(a.default.cyan(" [watch] ")+a.default.red(`Failed to start: ${c.message}
6
- `)),p=null})}var F=new T.Command("watch").description("Live reload \u2014 auto-restart process when secrets change in cloud").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment","development").option("-b, --branch <branch>","Branch","main").option("--interval <seconds>","Poll interval in seconds","5").option("--shell","Use shell mode for the child process (for npm run etc.)",!1).argument("<command>","Command to run").argument("[args...]","Command arguments").addHelpText("after",`
1
+ var ce=Object.create;var R=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var D=(e,t)=>()=>(e&&(t=e(e=0)),t);var E=(e,t)=>{for(var r in t)R(e,r,{get:t[r],enumerable:!0})},X=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ge(t))!le.call(e,n)&&n!==r&&R(e,n,{get:()=>t[n],enumerable:!(s=pe(t,n))||s.enumerable});return e};var v=(e,t,r)=>(r=e!=null?ce(ue(e)):{},X(t||!e||!e.__esModule?R(r,"default",{value:e,enumerable:!0}):r,e)),K=e=>X(R({},"__esModule",{value:!0}),e);var U={};E(U,{createWorkloadKeyEnvelope:()=>ve,decrypt:()=>F,decryptSecretValue:()=>ye,decryptWorkloadKeyEnvelope:()=>we,deriveProjectKey:()=>fe,encrypt:()=>W,encryptSecretValue:()=>he,hash:()=>de,resolveVaultPassphrase:()=>Y,saveVaultPassphrase:()=>me,secureRead:()=>P,secureSave:()=>b});function M(){if(_)return _;let e=C.get("masterKey");e||(e=i.default.randomBytes(32).toString("hex"),C.set("masterKey",e));let t="";try{t=(0,G.machineIdSync)()||""}catch{t=i.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 _=i.default.createHash("sha256").update(n).digest(),_}function fe(e,t){t||(t=Y(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 g=n.getAuthTag().toString("hex");return{ciphertext:a,iv:r.toString("hex"),authTag:g}}function ye(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 g=a.update(e.ciphertext,"hex","utf8");return g+=a.final("utf8"),g}function Y(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}=(B(),K(Z)),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&&b(`vault_${t}`,e),b("vault_passphrase",e)}function ve(e,t){let{publicKey:r,privateKey:s}=i.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),a=i.default.createPublicKey(t),g=i.default.diffieHellman({privateKey:s,publicKey:a}),d=Buffer.from(i.default.hkdfSync("sha256",g,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),l=i.default.randomBytes(12),f=i.default.createCipheriv("aes-256-gcm",d,l),y=f.update(e,"utf8","hex");y+=f.final("hex");let x=f.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:y,iv:l.toString("hex"),authTag:x}}function we(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)),g=Buffer.from(e.iv,"hex"),d=Buffer.from(e.authTag,"hex"),l=i.default.createDecipheriv("aes-256-gcm",a,g);l.setAuthTag(d);let f=l.update(e.encryptedProjectKey,"hex","utf8");return f+=l.final("utf8"),f}var i,h,q,G,k,J,C,_,W,F,de,b,P,I=D(()=>{i=v(require("crypto")),h=v(require("os")),q=v(require("conf")),G=require("node-machine-id"),k=require("child_process"),J="aes-256-gcm",C=new q.default({projectName:"xtra-cli-crypto"}),_=null;W=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 a=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:a.toString("hex")}},F=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 a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a},de=e=>i.default.createHash("sha256").update(e).digest("hex"),b=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if(h.default.platform()==="darwin"){(0,k.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,k.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=W(t);C.set(`secure_${e}`,JSON.stringify(r))},P=e=>{try{let t="XtraSecurityCLI",r=e;if(h.default.platform()==="darwin")return(0,k.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,k.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 F(r)}catch{return null}}});var Z={};E(Z,{clearConfig:()=>$e,deleteConfig:()=>je,getAuthToken:()=>A,getBreakGlassSession:()=>ke,getConfig:()=>T,getConfigValue:()=>xe,getProjectConfig:()=>Pe,getRcConfig:()=>L,setBreakGlassSession:()=>be,setConfig:()=>Se});var Q,$,V,O,p,z,T,xe,Se,$e,je,A,ke,be,Pe,L,B=D(()=>{Q=v(require("conf")),$=v(require("fs")),V=v(require("path"));I();O="https://www.xtrasecurity.in/api",p=new Q.default({projectName:"xtra-cli",defaults:{apiUrl:O}}),z=p.get("apiUrl");z&&!process.env.XTRA_API_URL&&z.includes("xtra-security.vercel.app")&&p.set("apiUrl",O);T=()=>({...p.store,token:A(),apiUrl:process.env.XTRA_API_URL||p.get("apiUrl")||O}),xe=e=>e==="token"?A():p.get(e),Se=(e,t)=>{if(e==="token"&&t&&b("token",t),p.set(e,t),e==="token"&&process.platform!=="win32"&&$.default.existsSync(p.path))try{$.default.chmodSync(p.path,384)}catch{}},$e=()=>p.clear(),je=e=>p.delete(e),A=()=>P("token")||p.get("token"),ke=()=>p.get("breakGlassSessionId"),be=e=>{e?p.set("breakGlassSessionId",e):p.delete("breakGlassSessionId")},Pe=async()=>{try{let e=V.default.join(process.cwd(),"xtra.json");if($.default.existsSync(e)){let t=$.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},L=()=>{let e={};try{let t=V.default.join(process.cwd(),".xtrarc");$.default.existsSync(t)&&(e=JSON.parse($.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 Re={};E(Re,{watchCommand:()=>Ae});module.exports=K(Re);var oe=require("commander");var ee=v(require("axios"));B();var te=v(require("fs")),re=v(require("path")),Te=JSON.parse(te.readFileSync(re.join(__dirname,"../../package.json"),"utf-8")),o=e=>{let{apiUrl:t}=T(),r=e||A();return ee.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Te.version,...r?{Authorization:`Bearer ${r}`}:{}}})},N={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 d=(await o(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(d&&typeof d=="object"){let l=null,{deriveProjectKey:f,decryptSecretValue:y,resolveVaultPassphrase:x,decryptWorkloadKeyEnvelope:u}=(I(),K(U));for(let[m,j]of Object.entries(d))if(typeof j=="string"&&j.startsWith("{"))try{let S=JSON.parse(j);if(S.ciphertext&&S.iv){if(!l)if(a&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)l=u(a,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let ie=x(s,e);l=f(e,ie)}d[m]=y(S,l)}}catch(S){if(S.message&&S.message.includes("Zero-Knowledge"))throw S}}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:a,encryptSecretValue:g,resolveVaultPassphrase:d}=(I(),K(U)),l=d(void 0,e),f=a(e,l),y={};for(let[u,m]of Object.entries(r))if(typeof m=="string"&&m.startsWith("{")&&m.includes("ciphertext"))y[u]=m;else{let j=g(m,f);y[u]=JSON.stringify(j)}return(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:y,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}=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(),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};B();var c=v(require("chalk")),ae=require("child_process"),w=null,H="";function se(e){return JSON.stringify(Object.keys(e).sort().map(t=>`${t}=${e[t]}`))}async function ne(e,t,r,s){w&&(process.stdout.write(c.default.cyan(`
2
+ [watch] `)+c.default.yellow(`Secret change detected \u2014 restarting...
3
+ `)),w.kill("SIGTERM"),await new Promise(a=>setTimeout(a,500)));let n={...process.env,...r};process.stdout.write(c.default.cyan(" [watch] ")+c.default.green(`Starting: ${e} ${t.join(" ")}
4
+ `)),w=(0,ae.spawn)(e,t,{env:n,stdio:"inherit",shell:s}),w.on("exit",a=>{a!==null&&a!==0&&process.stdout.write(c.default.cyan(" [watch] ")+c.default.red(`Process exited with code ${a}
5
+ `)),w=null}),w.on("error",a=>{process.stdout.write(c.default.cyan(" [watch] ")+c.default.red(`Failed to start: ${a.message}
6
+ `)),w=null})}var Ae=new oe.Command("watch").description("Live reload \u2014 auto-restart process when secrets change in cloud").option("-p, --project <id>","Project ID").option("-e, --env <environment>","Environment","development").option("-b, --branch <branch>","Branch","main").option("--interval <seconds>","Poll interval in seconds","5").option("--shell","Use shell mode for the child process (for npm run etc.)",!1).argument("<command>","Command to run").argument("[args...]","Command arguments").addHelpText("after",`
7
7
  Examples:
8
8
  $ xtra watch -p proj123 -e dev node app.js
9
9
  $ xtra watch -p proj123 -e dev --interval 10 --shell npm run dev
10
10
  $ xtra watch -p proj123 -e dev -- node -r dotenv/config server.js
11
- `).action(async(e,t,s)=>{let{project:n,env:o,branch:c,interval:y,shell:_}=s;o={dev:"development",stg:"staging",prod:"production"}[o]||o,n||(n=I().project),n||(console.error(a.default.red("Error: Project ID required. Use -p <id> or run 'xtra project set'.")),process.exit(1)),o==="production"&&(console.error(a.default.red("\u26A0 xtra watch is not allowed in PRODUCTION for safety reasons.")),console.error(a.default.gray(" Use 'xtra run' for one-shot production injection.")),process.exit(1));let G=Math.max(3,parseInt(y))*1e3,O=process.platform==="win32",v=_||O;console.log(a.default.bold.cyan(`
12
- \u25CF xtra watch`)+a.default.bold(` \u2014 watching ${o}/${c} (every ${y}s)
13
- `)),console.log(a.default.gray(` Press Ctrl+C to stop.
14
- `)),process.on("SIGINT",()=>{p&&p.kill("SIGTERM"),console.log(a.default.cyan(`
15
- [watch] `)+a.default.gray("Stopped.")),process.exit(0)});try{let i=await m.getSecrets(n,o,c);f=R(i),await U(e,t,i,v)}catch(i){console.error(a.default.red("Failed to fetch secrets: "+(i?.response?.data?.error||i?.response?.data?.error||"An unexpected error occurred"))),process.exit(1)}setInterval(async()=>{try{let i=await m.getSecrets(n,o,c),$=R(i);$!==f?(f=$,await U(e,t,i,v)):process.stdout.write(a.default.cyan(" [watch] ")+a.default.gray(`${new Date().toLocaleTimeString()} \u2014 no changes \r`))}catch(i){process.stdout.write(a.default.cyan(`
16
- [watch] `)+a.default.yellow(`Poll failed: ${i?.response?.data?.error||"An unexpected error occurred"}
17
- `))}},G)});0&&(module.exports={watchCommand});
11
+ `).action(async(e,t,r)=>{let{project:s,env:n,branch:a,interval:g,shell:d}=r;n={dev:"development",stg:"staging",prod:"production"}[n]||n,s||(s=L().project),s||(console.error(c.default.red("Error: Project ID required. Use -p <id> or run 'xtra project set'.")),process.exit(1)),n==="production"&&(console.error(c.default.red("\u26A0 xtra watch is not allowed in PRODUCTION for safety reasons.")),console.error(c.default.gray(" Use 'xtra run' for one-shot production injection.")),process.exit(1));let f=Math.max(3,parseInt(g))*1e3,y=process.platform==="win32",x=d||y;console.log(c.default.bold.cyan(`
12
+ \u25CF xtra watch`)+c.default.bold(` \u2014 watching ${n}/${a} (every ${g}s)
13
+ `)),console.log(c.default.gray(` Press Ctrl+C to stop.
14
+ `)),process.on("SIGINT",()=>{w&&w.kill("SIGTERM"),console.log(c.default.cyan(`
15
+ [watch] `)+c.default.gray("Stopped.")),process.exit(0)});try{let u=await N.getSecrets(s,n,a);H=se(u),await ne(e,t,u,x)}catch(u){console.error(c.default.red("Failed to fetch secrets: "+(u?.response?.data?.error||u?.response?.data?.error||"An unexpected error occurred"))),process.exit(1)}setInterval(async()=>{try{let u=await N.getSecrets(s,n,a),m=se(u);m!==H?(H=m,await ne(e,t,u,x)):process.stdout.write(c.default.cyan(" [watch] ")+c.default.gray(`${new Date().toLocaleTimeString()} \u2014 no changes \r`))}catch(u){process.stdout.write(c.default.cyan(`
16
+ [watch] `)+c.default.yellow(`Poll failed: ${u?.response?.data?.error||"An unexpected error occurred"}
17
+ `))}},f)});0&&(module.exports={watchCommand});
package/dist/lib/api.js CHANGED
@@ -1 +1 @@
1
- var v=Object.create;var i=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,b=Object.prototype.hasOwnProperty;var k=(s,e)=>{for(var t in e)i(s,t,{get:e[t],enumerable:!0})},d=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of j(e))!b.call(s,a)&&a!==t&&i(s,a,{get:()=>e[a],enumerable:!(r=h(e,a))||r.enumerable});return s};var p=(s,e,t)=>(t=s!=null?v(S(s)):{},d(e||!s||!s.__esModule?i(t,"default",{value:s,enumerable:!0}):t,s)),x=s=>d(i({},"__esModule",{value:!0}),s);var U={};k(U,{api:()=>I});module.exports=x(U);var m=p(require("axios"));var l=p(require("conf"));var u="https://www.xtrasecurity.in/api",c=new l.default({projectName:"xtra-cli",defaults:{apiUrl:u}}),y=c.get("apiUrl");y&&!process.env.XTRA_API_URL&&y.includes("xtra-security.vercel.app")&&c.set("apiUrl",u);var g=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||u});var w=()=>c.get("token");var $=p(require("fs")),f=p(require("path")),A=JSON.parse($.readFileSync(f.join(__dirname,"../../package.json"),"utf-8")),n=()=>{let{apiUrl:s}=g(),e=w();return m.default.create({baseURL:s,headers:{"Content-Type":"application/json","X-CLI-Version":A.version,...e?{Authorization:`Bearer ${e}`}:{}}})},I={login:async(s,e,t)=>(await n().post("/auth/cli-login",{email:s,password:e,apiKey:t})).data,getSecrets:async(s,e,t="main")=>(await n().get(`/projects/${s}/envs/${e}/secrets?branch=${t}`)).data,getSecretVersions:async(s,e,t="main")=>(await n().get(`/projects/${s}/envs/${e}/secrets?includeVersions=true&branch=${t}`)).data,setSecrets:async(s,e,t,r,a="main")=>(await n().post(`/projects/${s}/envs/${e}/secrets`,{secrets:t,expectedVersions:r,branch:a})).data,getSecretDetails:async(s,e,t,r="main")=>(await n().get(`/projects/${s}/envs/${e}/secrets/${t}?branch=${r}`)).data,syncLogs:async s=>(await n().post("/audit/cli-logs",{logs:s})).data,linkSecret:async(s,e,t,r,a,o)=>(await n().post(`/projects/${s}/envs/${e}/secrets/link`,{key:t,sourceProjectId:r,sourceEnv:a,sourceKey:o})).data,rotateSecret:async(s,e,t,r,a)=>(await n().post(`/projects/${s}/envs/${e}/secrets/${t}/rotate`,{strategy:r,parsedNewValue:a})).data,promoteSecret:async(s,e,t)=>(await n().post(`/projects/${s}/envs/${e}/secrets/${t}/promote`,{})).data,verifyAuditLogs:async()=>(await n().get("/audit/verify")).data,exportAuditLogs:async(s,e,t,r)=>{let a={format:s};return e&&(a.startDate=e),t&&(a.endDate=t),r&&(a.projectId=r),(await n().post("/audit/export",a,{responseType:s==="csv"?"text":"json"})).data},requestAccess:async(s,e,t,r)=>(await n().post("/access/request",{projectId:s,secretId:r,reason:e,duration:t})).data,approveAccess:async(s,e)=>(await n().post("/access/approve",{requestId:s,decision:e})).data,listAccessRequests:async s=>{let{workspace:e}=g(),t=e?`&workspaceId=${e}`:"";return(await n().get(`/access/list?mode=${s}${t}`)).data},getAccessRequestStatus:async s=>(await n().get(`/access/request?id=${s}`)).data,getProjects:async()=>{let{workspace:s}=g(),e=s?`/project?workspaceId=${s}`:"/project";return(await n().get(e)).data},getBranches:async s=>(await n().get(`/branch?projectId=${s}`)).data,createBranch:async(s,e,t)=>(await n().post("/branch",{projectId:s,name:e,description:t})).data,deleteBranch:async s=>(await n().delete(`/branch/${s}`)).data,updateBranch:async(s,e)=>(await n().put("/branch",{id:s,...e})).data,getRoles:async()=>(await n().get("/admin/roles")).data,getUsers:async s=>{let e=s?`?teamId=${s}`:"";return(await n().get(`/admin/users${e}`)).data},setUserRole:async(s,e,t)=>(await n().put("/admin/users/role",{email:s,role:e,teamId:t})).data,getIntegrationStatus:async s=>(await n().get(`/integrations/${s}`)).data,getIntegrationRepos:async s=>(await n().get(`/integrations/${s}/sync`)).data.repos,syncSecretsToGithub:async s=>(await n().post("/integrations/github/sync",s)).data,exportKubernetesSecret:async(s,e)=>{let t=new URLSearchParams(e).toString();return(await n().get(`/projects/${s}/kubernetes?${t}`)).data},getSecretHistory:async(s,e,t)=>(await n().get(`/projects/${s}/envs/${e}/secrets/${t}/history`)).data,rollbackSecret:async(s,e,t,r)=>(await n().post(`/projects/${s}/envs/${e}/secrets/${t}/history`,{version:r})).data,cloneEnvironment:async(s,e,t,r,a)=>(await n().post(`/projects/${s}/envs/clone`,{fromEnv:e,toEnv:t,overwrite:r,branch:a})).data,generateJitLink:async s=>(await n().post("/jit/generate",s)).data,claimJitLink:async s=>(await n().post("/jit/claim",{token:s})).data,getJitInfo:async s=>(await n().get(`/jit/${s}`)).data,getServiceAccounts:async s=>(await n().get(`/projects/${s}/service-accounts`)).data,createServiceAccount:async(s,e)=>(await n().post(`/projects/${s}/service-accounts`,e)).data,deleteServiceAccount:async(s,e)=>(await n().delete(`/projects/${s}/service-accounts/${e}`)).data,getServiceAccountKeys:async(s,e)=>(await n().get(`/projects/${s}/service-accounts/${e}/keys`)).data,createServiceAccountKey:async(s,e,t,r)=>(await n().post(`/projects/${s}/service-accounts/${e}/keys`,{label:t,expiresAt:r})).data,deleteServiceAccountKey:async(s,e,t)=>(await n().delete(`/projects/${s}/service-accounts/${e}/keys/${t}`)).data,post:async(s,e)=>(await n().post(s,e)).data};0&&(module.exports={api});
1
+ var Q=Object.create;var T=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,se=Object.prototype.hasOwnProperty;var U=(e,t)=>()=>(e&&(t=e(e=0)),t);var B=(e,t)=>{for(var r in t)T(e,r,{get:t[r],enumerable:!0})},L=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of te(t))!se.call(e,n)&&n!==r&&T(e,n,{get:()=>t[n],enumerable:!(s=ee(t,n))||s.enumerable});return e};var f=(e,t,r)=>(r=e!=null?Q(re(e)):{},L(t||!e||!e.__esModule?T(r,"default",{value:e,enumerable:!0}):r,e)),P=e=>L(T({},"__esModule",{value:!0}),e);var E={};B(E,{createWorkloadKeyEnvelope:()=>pe,decrypt:()=>J,decryptSecretValue:()=>ie,decryptWorkloadKeyEnvelope:()=>ge,deriveProjectKey:()=>oe,encrypt:()=>q,encryptSecretValue:()=>ae,hash:()=>ne,resolveVaultPassphrase:()=>W,saveVaultPassphrase:()=>ce,secureRead:()=>$,secureSave:()=>w});function N(){if(K)return K;let e=R.get("masterKey");e||(e=i.default.randomBytes(32).toString("hex"),R.set("masterKey",e));let t="";try{t=(0,X.machineIdSync)()||""}catch{t=i.default.createHash("sha256").update(d.default.hostname()+(d.default.userInfo?.()?.username||"root")).digest("hex")}let r=d.default.platform(),s=d.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return K=i.default.createHash("sha256").update(n).digest(),K}function oe(e,t){t||(t=W(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 ae(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 g=n.getAuthTag().toString("hex");return{ciphertext:a,iv:r.toString("hex"),authTag:g}}function ie(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 g=a.update(e.ciphertext,"hex","utf8");return g+=a.final("utf8"),g}function W(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(D)),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 ce(e,t){t&&w(`vault_${t}`,e),w("vault_passphrase",e)}function pe(e,t){let{publicKey:r,privateKey:s}=i.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),a=i.default.createPublicKey(t),g=i.default.diffieHellman({privateKey:s,publicKey:a}),u=Buffer.from(i.default.hkdfSync("sha256",g,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),p=i.default.randomBytes(12),l=i.default.createCipheriv("aes-256-gcm",u,p),y=l.update(e,"utf8","hex");y+=l.final("hex");let b=l.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:y,iv:p.toString("hex"),authTag:b}}function ge(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)),g=Buffer.from(e.iv,"hex"),u=Buffer.from(e.authTag,"hex"),p=i.default.createDecipheriv("aes-256-gcm",a,g);p.setAuthTag(u);let l=p.update(e.encryptedProjectKey,"hex","utf8");return l+=p.final("utf8"),l}var i,d,O,X,x,H,R,K,q,J,ne,w,$,_=U(()=>{i=f(require("crypto")),d=f(require("os")),O=f(require("conf")),X=require("node-machine-id"),x=require("child_process"),H="aes-256-gcm",R=new O.default({projectName:"xtra-cli-crypto"}),K=null;q=e=>{let t=i.default.randomBytes(12),r=N(),s=i.default.createCipheriv(H,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")}},J=e=>{let t=N(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=i.default.createDecipheriv(H,t,r);n.setAuthTag(s);let a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a},ne=e=>i.default.createHash("sha256").update(e).digest("hex"),w=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if(d.default.platform()==="darwin"){(0,x.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if(d.default.platform()!=="win32"){if(d.default.platform()==="linux")try{(0,x.execFileSync)("secret-tool",["store","--label",s,"service",s,"account",n],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=q(t);R.set(`secure_${e}`,JSON.stringify(r))},$=e=>{try{let t="XtraSecurityCLI",r=e;if(d.default.platform()==="darwin")return(0,x.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(d.default.platform()!=="win32"){if(d.default.platform()==="linux")try{return(0,x.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=R.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return J(r)}catch{return null}}});var D={};B(D,{clearConfig:()=>le,deleteConfig:()=>fe,getAuthToken:()=>j,getBreakGlassSession:()=>ye,getConfig:()=>k,getConfigValue:()=>ue,getProjectConfig:()=>me,getRcConfig:()=>ve,setBreakGlassSession:()=>he,setConfig:()=>de});var M,v,C,V,c,G,k,ue,de,le,fe,j,ye,he,me,ve,I=U(()=>{M=f(require("conf")),v=f(require("fs")),C=f(require("path"));_();V="https://www.xtrasecurity.in/api",c=new M.default({projectName:"xtra-cli",defaults:{apiUrl:V}}),G=c.get("apiUrl");G&&!process.env.XTRA_API_URL&&G.includes("xtra-security.vercel.app")&&c.set("apiUrl",V);k=()=>({...c.store,token:j(),apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||V}),ue=e=>e==="token"?j():c.get(e),de=(e,t)=>{if(e==="token"&&t&&w("token",t),c.set(e,t),e==="token"&&process.platform!=="win32"&&v.default.existsSync(c.path))try{v.default.chmodSync(c.path,384)}catch{}},le=()=>c.clear(),fe=e=>c.delete(e),j=()=>$("token")||c.get("token"),ye=()=>c.get("breakGlassSessionId"),he=e=>{e?c.set("breakGlassSessionId",e):c.delete("breakGlassSessionId")},me=async()=>{try{let e=C.default.join(process.cwd(),"xtra.json");if(v.default.existsSync(e)){let t=v.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},ve=()=>{let e={};try{let t=C.default.join(process.cwd(),".xtrarc");v.default.existsSync(t)&&(e=JSON.parse(v.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||c.get("project")||"",env:e.env||c.get("env")||"development",branch:e.branch||c.get("branch")||"main"}}});var we={};B(we,{api:()=>xe});module.exports=P(we);var F=f(require("axios"));I();var Y=f(require("fs")),Z=f(require("path")),Se=JSON.parse(Y.readFileSync(Z.join(__dirname,"../../package.json"),"utf-8")),o=e=>{let{apiUrl:t}=k(),r=e||j();return F.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Se.version,...r?{Authorization:`Bearer ${r}`}:{}}})},xe={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 u=(await o(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(u&&typeof u=="object"){let p=null,{deriveProjectKey:l,decryptSecretValue:y,resolveVaultPassphrase:b,decryptWorkloadKeyEnvelope:A}=(_(),P(E));for(let[h,S]of Object.entries(u))if(typeof S=="string"&&S.startsWith("{"))try{let m=JSON.parse(S);if(m.ciphertext&&m.iv){if(!p)if(a&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)p=A(a,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let z=b(s,e);p=l(e,z)}u[h]=y(m,p)}}catch(m){if(m.message&&m.message.includes("Zero-Knowledge"))throw m}}return u},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:g,resolveVaultPassphrase:u}=(_(),P(E)),p=u(void 0,e),l=a(e,p),y={};for(let[A,h]of Object.entries(r))if(typeof h=="string"&&h.startsWith("{")&&h.includes("ciphertext"))y[A]=h;else{let S=g(h,l);y[A]=JSON.stringify(S)}return(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:y,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}=k(),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}=k(),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};0&&(module.exports={api});
package/dist/lib/audit.js CHANGED
@@ -1 +1 @@
1
- var J=Object.create;var d=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var V=(t,e)=>{for(var s in e)d(t,s,{get:e[s],enumerable:!0})},$=(t,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of F(e))!q.call(t,o)&&o!==s&&d(t,o,{get:()=>e[o],enumerable:!(n=K(e,o))||n.enumerable});return t};var i=(t,e,s)=>(s=t!=null?J(G(t)):{},$(e||!t||!t.__esModule?d(s,"default",{value:t,enumerable:!0}):s,t)),z=t=>$(d({},"__esModule",{value:!0}),t);var W={};V(W,{loadAuditLogs:()=>y,logAudit:()=>M,saveAuditLogs:()=>f,syncAuditLogs:()=>Q});module.exports=z(W);var g=i(require("fs")),v=i(require("path")),D=require("uuid");var c=i(require("crypto")),k=i(require("conf")),b=require("node-machine-id"),A="aes-256-gcm",x=new k.default({projectName:"xtra-cli-crypto"});function I(){let t=x.get("masterKey");t||(t=c.default.randomBytes(32).toString("hex"),x.set("masterKey",t));let e=(0,b.machineIdSync)();return c.default.createHash("sha256").update(t+e).digest()}var C=t=>{let e=c.default.randomBytes(16),s=I(),n=c.default.createCipheriv(A,s,e),o=n.update(t,"utf8","hex");o+=n.final("hex");let a=n.getAuthTag();return{iv:e.toString("hex"),content:o,tag:a.toString("hex")}},U=t=>{let e=I(),s=Buffer.from(t.iv,"hex"),n=Buffer.from(t.tag,"hex"),o=c.default.createDecipheriv(A,e,s);o.setAuthTag(n);let a=o.update(t.content,"hex","utf8");return a+=o.final("utf8"),a};var L=i(require("conf"));var m="https://www.xtrasecurity.in/api",u=new L.default({projectName:"xtra-cli",defaults:{apiUrl:m}}),R=u.get("apiUrl");R&&!process.env.XTRA_API_URL&&R.includes("xtra-security.vercel.app")&&u.set("apiUrl",m);var p=()=>({...u.store,apiUrl:process.env.XTRA_API_URL||u.get("apiUrl")||m});var B=()=>u.get("token");var O=i(require("axios"));var T=i(require("fs")),P=i(require("path")),H=JSON.parse(T.readFileSync(P.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:t}=p(),e=B();return O.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":H.version,...e?{Authorization:`Bearer ${e}`}:{}}})},_={login:async(t,e,s)=>(await r().post("/auth/cli-login",{email:t,password:e,apiKey:s})).data,getSecrets:async(t,e,s="main")=>(await r().get(`/projects/${t}/envs/${e}/secrets?branch=${s}`)).data,getSecretVersions:async(t,e,s="main")=>(await r().get(`/projects/${t}/envs/${e}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(t,e,s,n,o="main")=>(await r().post(`/projects/${t}/envs/${e}/secrets`,{secrets:s,expectedVersions:n,branch:o})).data,getSecretDetails:async(t,e,s,n="main")=>(await r().get(`/projects/${t}/envs/${e}/secrets/${s}?branch=${n}`)).data,syncLogs:async t=>(await r().post("/audit/cli-logs",{logs:t})).data,linkSecret:async(t,e,s,n,o,a)=>(await r().post(`/projects/${t}/envs/${e}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:a})).data,rotateSecret:async(t,e,s,n,o)=>(await r().post(`/projects/${t}/envs/${e}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:o})).data,promoteSecret:async(t,e,s)=>(await r().post(`/projects/${t}/envs/${e}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await r().get("/audit/verify")).data,exportAuditLogs:async(t,e,s,n)=>{let o={format:t};return e&&(o.startDate=e),s&&(o.endDate=s),n&&(o.projectId=n),(await r().post("/audit/export",o,{responseType:t==="csv"?"text":"json"})).data},requestAccess:async(t,e,s,n)=>(await r().post("/access/request",{projectId:t,secretId:n,reason:e,duration:s})).data,approveAccess:async(t,e)=>(await r().post("/access/approve",{requestId:t,decision:e})).data,listAccessRequests:async t=>{let{workspace:e}=p(),s=e?`&workspaceId=${e}`:"";return(await r().get(`/access/list?mode=${t}${s}`)).data},getAccessRequestStatus:async t=>(await r().get(`/access/request?id=${t}`)).data,getProjects:async()=>{let{workspace:t}=p(),e=t?`/project?workspaceId=${t}`:"/project";return(await r().get(e)).data},getBranches:async t=>(await r().get(`/branch?projectId=${t}`)).data,createBranch:async(t,e,s)=>(await r().post("/branch",{projectId:t,name:e,description:s})).data,deleteBranch:async t=>(await r().delete(`/branch/${t}`)).data,updateBranch:async(t,e)=>(await r().put("/branch",{id:t,...e})).data,getRoles:async()=>(await r().get("/admin/roles")).data,getUsers:async t=>{let e=t?`?teamId=${t}`:"";return(await r().get(`/admin/users${e}`)).data},setUserRole:async(t,e,s)=>(await r().put("/admin/users/role",{email:t,role:e,teamId:s})).data,getIntegrationStatus:async t=>(await r().get(`/integrations/${t}`)).data,getIntegrationRepos:async t=>(await r().get(`/integrations/${t}/sync`)).data.repos,syncSecretsToGithub:async t=>(await r().post("/integrations/github/sync",t)).data,exportKubernetesSecret:async(t,e)=>{let s=new URLSearchParams(e).toString();return(await r().get(`/projects/${t}/kubernetes?${s}`)).data},getSecretHistory:async(t,e,s)=>(await r().get(`/projects/${t}/envs/${e}/secrets/${s}/history`)).data,rollbackSecret:async(t,e,s,n)=>(await r().post(`/projects/${t}/envs/${e}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(t,e,s,n,o)=>(await r().post(`/projects/${t}/envs/clone`,{fromEnv:e,toEnv:s,overwrite:n,branch:o})).data,generateJitLink:async t=>(await r().post("/jit/generate",t)).data,claimJitLink:async t=>(await r().post("/jit/claim",{token:t})).data,getJitInfo:async t=>(await r().get(`/jit/${t}`)).data,getServiceAccounts:async t=>(await r().get(`/projects/${t}/service-accounts`)).data,createServiceAccount:async(t,e)=>(await r().post(`/projects/${t}/service-accounts`,e)).data,deleteServiceAccount:async(t,e)=>(await r().delete(`/projects/${t}/service-accounts/${e}`)).data,getServiceAccountKeys:async(t,e)=>(await r().get(`/projects/${t}/service-accounts/${e}/keys`)).data,createServiceAccountKey:async(t,e,s,n)=>(await r().post(`/projects/${t}/service-accounts/${e}/keys`,{label:s,expiresAt:n})).data,deleteServiceAccountKey:async(t,e,s)=>(await r().delete(`/projects/${t}/service-accounts/${e}/keys/${s}`)).data,post:async(t,e)=>(await r().post(t,e)).data};var h=v.default.join(process.cwd(),".xtra"),w=v.default.join(h,"audit.enc");function X(t){if(!t||typeof t!="object")return t;let e={...t},s=["password","token","secret","value","apiKey","secretValue"];for(let n of Object.keys(e))s.some(o=>n.toLowerCase().includes(o))&&(e[n]="[REDACTED]");return e}async function N(t){try{if(!p().token)return!1;let s={action:t.action,entity:"cli-project",entityId:t.projectId||"global",details:X(t.details),timestamp:t.timestamp,projectId:t.projectId};return await _.post("/audit/cli-logs",{logs:[s]}),!0}catch(e){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",e),!1}}function M(t,e,s,n){let o={id:(0,D.v4)(),timestamp:new Date().toISOString(),action:t,projectId:e,environment:s,details:n,synced:!1},a=y();a.push(o),f(a),N(o).then(S=>{if(S){o.synced=!0;let l=y(),j=l.findIndex(E=>E.id===o.id);j!==-1&&(l[j].synced=!0,f(l))}}).catch(()=>{})}function y(){if(!g.default.existsSync(w))return[];try{let t=g.default.readFileSync(w,"utf-8"),e=JSON.parse(t),s=U(e);return JSON.parse(s)}catch{return[]}}function f(t){g.default.existsSync(h)||g.default.mkdirSync(h,{recursive:!0});let e=JSON.stringify(t),s=C(e);g.default.writeFileSync(w,JSON.stringify(s),"utf-8")}async function Q(){let t=y(),e=t.filter(n=>!n.synced);if(e.length===0)return 0;let s=0;for(let n of e)await N(n)&&(n.synced=!0,s++);return s>0&&f(t),s}0&&(module.exports={loadAuditLogs,logAudit,saveAuditLogs,syncAuditLogs});
1
+ var ce=Object.create;var K=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,de=Object.prototype.hasOwnProperty;var q=(e,t)=>()=>(e&&(t=e(e=0)),t);var L=(e,t)=>{for(var r in t)K(e,r,{get:t[r],enumerable:!0})},W=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ge(t))!de.call(e,n)&&n!==r&&K(e,n,{get:()=>t[n],enumerable:!(s=pe(t,n))||s.enumerable});return e};var f=(e,t,r)=>(r=e!=null?ce(ue(e)):{},W(t||!e||!e.__esModule?K(r,"default",{value:e,enumerable:!0}):r,e)),R=e=>W(K({},"__esModule",{value:!0}),e);var M={};L(M,{clearConfig:()=>ye,deleteConfig:()=>he,getAuthToken:()=>k,getBreakGlassSession:()=>me,getConfig:()=>S,getConfigValue:()=>fe,getProjectConfig:()=>Se,getRcConfig:()=>xe,setBreakGlassSession:()=>ve,setConfig:()=>le});var G,v,V,D,c,F,S,fe,le,ye,he,k,me,ve,Se,xe,_=q(()=>{G=f(require("conf")),v=f(require("fs")),V=f(require("path"));A();D="https://www.xtrasecurity.in/api",c=new G.default({projectName:"xtra-cli",defaults:{apiUrl:D}}),F=c.get("apiUrl");F&&!process.env.XTRA_API_URL&&F.includes("xtra-security.vercel.app")&&c.set("apiUrl",D);S=()=>({...c.store,token:k(),apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||D}),fe=e=>e==="token"?k():c.get(e),le=(e,t)=>{if(e==="token"&&t&&$("token",t),c.set(e,t),e==="token"&&process.platform!=="win32"&&v.default.existsSync(c.path))try{v.default.chmodSync(c.path,384)}catch{}},ye=()=>c.clear(),he=e=>c.delete(e),k=()=>j("token")||c.get("token"),me=()=>c.get("breakGlassSessionId"),ve=e=>{e?c.set("breakGlassSessionId",e):c.delete("breakGlassSessionId")},Se=async()=>{try{let e=V.default.join(process.cwd(),"xtra.json");if(v.default.existsSync(e)){let t=v.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},xe=()=>{let e={};try{let t=V.default.join(process.cwd(),".xtrarc");v.default.existsSync(t)&&(e=JSON.parse(v.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||c.get("project")||"",env:e.env||c.get("env")||"development",branch:e.branch||c.get("branch")||"main"}}});var N={};L(N,{createWorkloadKeyEnvelope:()=>be,decrypt:()=>C,decryptSecretValue:()=>je,decryptWorkloadKeyEnvelope:()=>Te,deriveProjectKey:()=>ke,encrypt:()=>B,encryptSecretValue:()=>$e,hash:()=>we,resolveVaultPassphrase:()=>ee,saveVaultPassphrase:()=>Ae,secureRead:()=>j,secureSave:()=>$});function Q(){if(I)return I;let e=E.get("masterKey");e||(e=a.default.randomBytes(32).toString("hex"),E.set("masterKey",e));let t="";try{t=(0,Y.machineIdSync)()||""}catch{t=a.default.createHash("sha256").update(l.default.hostname()+(l.default.userInfo?.()?.username||"root")).digest("hex")}let r=l.default.platform(),s=l.default.userInfo?.()?.username||"default_user",n=`${r}:${s}:${t}:${e}`;return I=a.default.createHash("sha256").update(n).digest(),I}function ke(e,t){t||(t=ee(void 0,e));let r=Buffer.from(`project_salt_${e}`),s=Buffer.from("xtra-e2ee-project-key-v2"),n=a.default.hkdfSync("sha256",Buffer.from(t),r,s,32);return Buffer.from(n).toString("hex")}function $e(e,t){let r=a.default.randomBytes(12),s=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=a.default.createCipheriv("aes-256-gcm",s,r),i=n.update(e,"utf8","hex");i+=n.final("hex");let u=n.getAuthTag().toString("hex");return{ciphertext:i,iv:r.toString("hex"),authTag:u}}function je(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=a.default.createDecipheriv("aes-256-gcm",r,s);i.setAuthTag(n);let u=i.update(e.ciphertext,"hex","utf8");return u+=i.final("utf8"),u}function ee(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=j(`vault_${t}`);if(s)return s}let r=j("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(_(),R(M)),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 Ae(e,t){t&&$(`vault_${t}`,e),$("vault_passphrase",e)}function be(e,t){let{publicKey:r,privateKey:s}=a.default.generateKeyPairSync("x25519"),n=r.export({type:"spki",format:"pem"}).toString(),i=a.default.createPublicKey(t),u=a.default.diffieHellman({privateKey:s,publicKey:i}),g=Buffer.from(a.default.hkdfSync("sha256",u,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),p=a.default.randomBytes(12),d=a.default.createCipheriv("aes-256-gcm",g,p),y=d.update(e,"utf8","hex");y+=d.final("hex");let T=d.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:n,encryptedProjectKey:y,iv:p.toString("hex"),authTag:T}}function Te(e,t){let r=a.default.createPrivateKey(t),s=a.default.createPublicKey(e.ephemeralPublicKey),n=a.default.diffieHellman({privateKey:r,publicKey:s}),i=Buffer.from(a.default.hkdfSync("sha256",n,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),u=Buffer.from(e.iv,"hex"),g=Buffer.from(e.authTag,"hex"),p=a.default.createDecipheriv("aes-256-gcm",i,u);p.setAuthTag(g);let d=p.update(e.encryptedProjectKey,"hex","utf8");return d+=p.final("utf8"),d}var a,l,z,Y,b,Z,E,I,B,C,we,$,j,A=q(()=>{a=f(require("crypto")),l=f(require("os")),z=f(require("conf")),Y=require("node-machine-id"),b=require("child_process"),Z="aes-256-gcm",E=new z.default({projectName:"xtra-cli-crypto"}),I=null;B=e=>{let t=a.default.randomBytes(12),r=Q(),s=a.default.createCipheriv(Z,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")}},C=e=>{let t=Q(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=a.default.createDecipheriv(Z,t,r);n.setAuthTag(s);let i=n.update(e.content,"hex","utf8");return i+=n.final("utf8"),i},we=e=>a.default.createHash("sha256").update(e).digest("hex"),$=(e,t)=>{try{let s="XtraSecurityCLI",n=e;if(l.default.platform()==="darwin"){(0,b.execFileSync)("security",["add-generic-password","-s",s,"-a",n,"-w",t,"-U"],{stdio:"ignore"});return}else if(l.default.platform()!=="win32"){if(l.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=B(t);E.set(`secure_${e}`,JSON.stringify(r))},j=e=>{try{let t="XtraSecurityCLI",r=e;if(l.default.platform()==="darwin")return(0,b.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(l.default.platform()!=="win32"){if(l.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=E.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return C(r)}catch{return null}}});var Ie={};L(Ie,{loadAuditLogs:()=>O,logAudit:()=>Re,saveAuditLogs:()=>U,syncAuditLogs:()=>_e});module.exports=R(Ie);var x=f(require("fs")),H=f(require("path")),oe=require("crypto");A();_();var te=f(require("axios"));_();var re=f(require("fs")),se=f(require("path")),Pe=JSON.parse(re.readFileSync(se.join(__dirname,"../../package.json"),"utf-8")),o=e=>{let{apiUrl:t}=S(),r=e||k();return te.default.create({baseURL:t,headers:{"Content-Type":"application/json","X-CLI-Version":Pe.version,...r?{Authorization:`Bearer ${r}`}:{}}})},ne={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 g=(await o(n).get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data;if(g&&typeof g=="object"){let p=null,{deriveProjectKey:d,decryptSecretValue:y,resolveVaultPassphrase:T,decryptWorkloadKeyEnvelope:P}=(A(),R(N));for(let[h,w]of Object.entries(g))if(typeof w=="string"&&w.startsWith("{"))try{let m=JSON.parse(w);if(m.ciphertext&&m.iv){if(!p)if(i&&process.env.XTRA_WORKLOAD_PRIVATE_KEY)p=P(i,process.env.XTRA_WORKLOAD_PRIVATE_KEY);else{let ae=T(s,e);p=d(e,ae)}g[h]=y(m,p)}}catch(m){if(m.message&&m.message.includes("Zero-Knowledge"))throw m}}return g},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:u,resolveVaultPassphrase:g}=(A(),R(N)),p=g(void 0,e),d=i(e,p),y={};for(let[P,h]of Object.entries(r))if(typeof h=="string"&&h.startsWith("{")&&h.includes("ciphertext"))y[P]=h;else{let w=u(h,d);y[P]=JSON.stringify(w)}return(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:y,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}=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};var J=H.default.join(process.cwd(),".xtra"),X=H.default.join(J,"audit.enc");function Ke(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:Ke(e.details),timestamp:e.timestamp,projectId:e.projectId};return await ne.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 Re(e,t,r,s){let n={id:(0,oe.randomUUID)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:r,details:s,synced:!1},i=O();i.push(n),U(i),ie(n).then(u=>{if(u){n.synced=!0;let g=O(),p=g.findIndex(d=>d.id===n.id);p!==-1&&(g[p].synced=!0,U(g))}}).catch(()=>{})}function O(){if(!x.default.existsSync(X))return[];try{let e=x.default.readFileSync(X,"utf-8"),t=JSON.parse(e),r=C(t);return JSON.parse(r)}catch{return[]}}function U(e){x.default.existsSync(J)||x.default.mkdirSync(J,{recursive:!0});let t=JSON.stringify(e),r=B(t);x.default.writeFileSync(X,JSON.stringify(r),"utf-8")}async function _e(){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&&U(e),r}0&&(module.exports={loadAuditLogs,logAudit,saveAuditLogs,syncAuditLogs});
@@ -1 +1 @@
1
- var x=Object.create;var c=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var n in t)c(e,n,{get:t[n],enumerable:!0})},l=(e,t,n,g)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of y(t))!u.call(e,o)&&o!==n&&c(e,o,{get:()=>t[o],enumerable:!(g=S(t,o))||g.enumerable});return e};var i=(e,t,n)=>(n=e!=null?x(d(e)):{},l(t||!e||!e.__esModule?c(n,"default",{value:e,enumerable:!0}):n,e)),k=e=>l(c({},"__esModule",{value:!0}),e);var R={};m(R,{clearConfig:()=>b,deleteConfig:()=>v,getAuthToken:()=>_,getBreakGlassSession:()=>w,getConfig:()=>C,getConfigValue:()=>U,getProjectConfig:()=>A,getRcConfig:()=>P,setBreakGlassSession:()=>I,setConfig:()=>j});module.exports=k(R);var h=i(require("conf")),s=i(require("fs")),p=i(require("path")),a="https://www.xtrasecurity.in/api",r=new h.default({projectName:"xtra-cli",defaults:{apiUrl:a}}),f=r.get("apiUrl");f&&!process.env.XTRA_API_URL&&f.includes("xtra-security.vercel.app")&&r.set("apiUrl",a);var C=()=>({...r.store,apiUrl:process.env.XTRA_API_URL||r.get("apiUrl")||a}),U=e=>r.get(e),j=(e,t)=>{if(r.set(e,t),e==="token"&&process.platform!=="win32"&&s.default.existsSync(r.path))try{s.default.chmodSync(r.path,384)}catch{}},b=()=>r.clear(),v=e=>r.delete(e),_=()=>r.get("token"),w=()=>r.get("breakGlassSessionId"),I=e=>{e?r.set("breakGlassSessionId",e):r.delete("breakGlassSessionId")},A=async()=>{try{let e=p.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}},P=()=>{let e={};try{let t=p.default.join(process.cwd(),".xtrarc");s.default.existsSync(t)&&(e=JSON.parse(s.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||r.get("project")||"",env:e.env||r.get("env")||"development",branch:e.branch||r.get("branch")||"main"}};0&&(module.exports={clearConfig,deleteConfig,getAuthToken,getBreakGlassSession,getConfig,getConfigValue,getProjectConfig,getRcConfig,setBreakGlassSession,setConfig});
1
+ var R=Object.create;var g=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var x=(e,t)=>()=>(e&&(t=e(e=0)),t);var U=(e,t)=>{for(var r in t)g(e,r,{get:t[r],enumerable:!0})},v=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of E(t))!j.call(e,s)&&s!==r&&g(e,s,{get:()=>t[s],enumerable:!(n=b(t,s))||n.enumerable});return e};var p=(e,t,r)=>(r=e!=null?R(C(e)):{},v(t||!e||!e.__esModule?g(r,"default",{value:e,enumerable:!0}):r,e)),I=e=>v(g({},"__esModule",{value:!0}),e);function k(){if(l)return l;let e=h.get("masterKey");e||(e=c.default.randomBytes(32).toString("hex"),h.set("masterKey",e));let t="";try{t=(0,P.machineIdSync)()||""}catch{t=c.default.createHash("sha256").update(i.default.hostname()+(i.default.userInfo?.()?.username||"root")).digest("hex")}let r=i.default.platform(),n=i.default.userInfo?.()?.username||"default_user",s=`${r}:${n}:${t}:${e}`;return l=c.default.createHash("sha256").update(s).digest(),l}var c,i,S,P,u,T,h,l,H,X,_,K,A=x(()=>{c=p(require("crypto")),i=p(require("os")),S=p(require("conf")),P=require("node-machine-id"),u=require("child_process"),T="aes-256-gcm",h=new S.default({projectName:"xtra-cli-crypto"}),l=null;H=e=>{let t=c.default.randomBytes(12),r=k(),n=c.default.createCipheriv(T,r,t),s=n.update(e,"utf8","hex");s+=n.final("hex");let f=n.getAuthTag();return{iv:t.toString("hex"),content:s,tag:f.toString("hex")}},X=e=>{let t=k(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),s=c.default.createDecipheriv(T,t,r);s.setAuthTag(n);let f=s.update(e.content,"hex","utf8");return f+=s.final("utf8"),f},_=(e,t)=>{try{let n="XtraSecurityCLI",s=e;if(i.default.platform()==="darwin"){(0,u.execFileSync)("security",["add-generic-password","-s",n,"-a",s,"-w",t,"-U"],{stdio:"ignore"});return}else if(i.default.platform()!=="win32"){if(i.default.platform()==="linux")try{(0,u.execFileSync)("secret-tool",["store","--label",n,"service",n,"account",s],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=H(t);h.set(`secure_${e}`,JSON.stringify(r))},K=e=>{try{let t="XtraSecurityCLI",r=e;if(i.default.platform()==="darwin")return(0,u.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(i.default.platform()!=="win32"){if(i.default.platform()==="linux")try{return(0,u.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=h.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return X(r)}catch{return null}}});var M={};U(M,{clearConfig:()=>G,deleteConfig:()=>N,getAuthToken:()=>y,getBreakGlassSession:()=>O,getConfig:()=>V,getConfigValue:()=>$,getProjectConfig:()=>D,getRcConfig:()=>J,setBreakGlassSession:()=>W,setConfig:()=>L});module.exports=I(M);var w,a,d,m,o,B,V,$,L,G,N,y,O,W,D,J,F=x(()=>{w=p(require("conf")),a=p(require("fs")),d=p(require("path"));A();m="https://www.xtrasecurity.in/api",o=new w.default({projectName:"xtra-cli",defaults:{apiUrl:m}}),B=o.get("apiUrl");B&&!process.env.XTRA_API_URL&&B.includes("xtra-security.vercel.app")&&o.set("apiUrl",m);V=()=>({...o.store,token:y(),apiUrl:process.env.XTRA_API_URL||o.get("apiUrl")||m}),$=e=>e==="token"?y():o.get(e),L=(e,t)=>{if(e==="token"&&t&&_("token",t),o.set(e,t),e==="token"&&process.platform!=="win32"&&a.default.existsSync(o.path))try{a.default.chmodSync(o.path,384)}catch{}},G=()=>o.clear(),N=e=>o.delete(e),y=()=>K("token")||o.get("token"),O=()=>o.get("breakGlassSessionId"),W=e=>{e?o.set("breakGlassSessionId",e):o.delete("breakGlassSessionId")},D=async()=>{try{let e=d.default.join(process.cwd(),"xtra.json");if(a.default.existsSync(e)){let t=a.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},J=()=>{let e={};try{let t=d.default.join(process.cwd(),".xtrarc");a.default.existsSync(t)&&(e=JSON.parse(a.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||o.get("project")||"",env:e.env||o.get("env")||"development",branch:e.branch||o.get("branch")||"main"}}});F();0&&(module.exports={clearConfig,deleteConfig,getAuthToken,getBreakGlassSession,getConfig,getConfigValue,getProjectConfig,getRcConfig,setBreakGlassSession,setConfig});
@@ -1 +1 @@
1
- var d=Object.create;var a=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var v=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var B=(t,e)=>{for(var r in e)a(t,r,{get:e[r],enumerable:!0})},c=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of y(e))!l.call(t,n)&&n!==r&&a(t,n,{get:()=>e[n],enumerable:!(o=x(e,n))||o.enumerable});return t};var g=(t,e,r)=>(r=t!=null?d(v(t)):{},c(e||!t||!t.__esModule?a(r,"default",{value:t,enumerable:!0}):r,t)),S=t=>c(a({},"__esModule",{value:!0}),t);var C={};B(C,{decrypt:()=>K,encrypt:()=>k,hash:()=>A});module.exports=S(C);var s=g(require("crypto")),f=g(require("conf")),p=require("node-machine-id"),m="aes-256-gcm",h=new f.default({projectName:"xtra-cli-crypto"});function u(){let t=h.get("masterKey");t||(t=s.default.randomBytes(32).toString("hex"),h.set("masterKey",t));let e=(0,p.machineIdSync)();return s.default.createHash("sha256").update(t+e).digest()}var k=t=>{let e=s.default.randomBytes(16),r=u(),o=s.default.createCipheriv(m,r,e),n=o.update(t,"utf8","hex");n+=o.final("hex");let i=o.getAuthTag();return{iv:e.toString("hex"),content:n,tag:i.toString("hex")}},K=t=>{let e=u(),r=Buffer.from(t.iv,"hex"),o=Buffer.from(t.tag,"hex"),n=s.default.createDecipheriv(m,e,r);n.setAuthTag(o);let i=n.update(t.content,"hex","utf8");return i+=n.final("utf8"),i},A=t=>s.default.createHash("sha256").update(t).digest("hex");0&&(module.exports={decrypt,encrypt,hash});
1
+ var N=Object.create;var y=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var D=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var K=(e,t)=>()=>(e&&(t=e(e=0)),t);var A=(e,t)=>{for(var r in t)y(e,r,{get:t[r],enumerable:!0})},B=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of W(t))!J.call(e,s)&&s!==r&&y(e,s,{get:()=>t[s],enumerable:!(n=O(t,s))||n.enumerable});return e};var l=(e,t,r)=>(r=e!=null?N(D(e)):{},B(t||!e||!e.__esModule?y(r,"default",{value:e,enumerable:!0}):r,e)),w=e=>B(y({},"__esModule",{value:!0}),e);var E={};A(E,{clearConfig:()=>Z,deleteConfig:()=>z,getAuthToken:()=>k,getBreakGlassSession:()=>Q,getConfig:()=>M,getConfigValue:()=>F,getProjectConfig:()=>ee,getRcConfig:()=>te,setBreakGlassSession:()=>Y,setConfig:()=>q});var b,p,P,T,c,R,M,F,q,Z,z,k,Q,Y,ee,te,C=K(()=>{b=l(require("conf")),p=l(require("fs")),P=l(require("path"));j();T="https://www.xtrasecurity.in/api",c=new b.default({projectName:"xtra-cli",defaults:{apiUrl:T}}),R=c.get("apiUrl");R&&!process.env.XTRA_API_URL&&R.includes("xtra-security.vercel.app")&&c.set("apiUrl",T);M=()=>({...c.store,token:k(),apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||T}),F=e=>e==="token"?k():c.get(e),q=(e,t)=>{if(e==="token"&&t&&h("token",t),c.set(e,t),e==="token"&&process.platform!=="win32"&&p.default.existsSync(c.path))try{p.default.chmodSync(c.path,384)}catch{}},Z=()=>c.clear(),z=e=>c.delete(e),k=()=>d("token")||c.get("token"),Q=()=>c.get("breakGlassSessionId"),Y=e=>{e?c.set("breakGlassSessionId",e):c.delete("breakGlassSessionId")},ee=async()=>{try{let e=P.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}},te=()=>{let e={};try{let t=P.default.join(process.cwd(),".xtrarc");p.default.existsSync(t)&&(e=JSON.parse(p.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||c.get("project")||"",env:e.env||c.get("env")||"development",branch:e.branch||c.get("branch")||"main"}}});var fe={};A(fe,{createWorkloadKeyEnvelope:()=>ce,decrypt:()=>$,decryptSecretValue:()=>oe,decryptWorkloadKeyEnvelope:()=>ae,deriveProjectKey:()=>ne,encrypt:()=>V,encryptSecretValue:()=>se,hash:()=>re,resolveVaultPassphrase:()=>L,saveVaultPassphrase:()=>ie,secureRead:()=>d,secureSave:()=>h});module.exports=w(fe);function X(){if(x)return x;let e=v.get("masterKey");e||(e=o.default.randomBytes(32).toString("hex"),v.set("masterKey",e));let t="";try{t=(0,I.machineIdSync)()||""}catch{t=o.default.createHash("sha256").update(a.default.hostname()+(a.default.userInfo?.()?.username||"root")).digest("hex")}let r=a.default.platform(),n=a.default.userInfo?.()?.username||"default_user",s=`${r}:${n}:${t}:${e}`;return x=o.default.createHash("sha256").update(s).digest(),x}function ne(e,t){t||(t=L(void 0,e));let r=Buffer.from(`project_salt_${e}`),n=Buffer.from("xtra-e2ee-project-key-v2"),s=o.default.hkdfSync("sha256",Buffer.from(t),r,n,32);return Buffer.from(s).toString("hex")}function se(e,t){let r=o.default.randomBytes(12),n=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),s=o.default.createCipheriv("aes-256-gcm",n,r),i=s.update(e,"utf8","hex");i+=s.final("hex");let f=s.getAuthTag().toString("hex");return{ciphertext:i,iv:r.toString("hex"),authTag:f}}function oe(e,t){let r=Buffer.from(t.slice(0,64).padEnd(64,"0"),"hex"),n=Buffer.from(e.iv,"hex"),s=Buffer.from(e.authTag,"hex"),i=o.default.createDecipheriv("aes-256-gcm",r,n);i.setAuthTag(s);let f=i.update(e.ciphertext,"hex","utf8");return f+=i.final("utf8"),f}function L(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 n=d(`vault_${t}`);if(n)return n}let r=d("vault_passphrase");if(r)return r}catch{}try{let{getRcConfig:r}=(C(),w(E)),n=r();if(n&&n.passphrase)return n.passphrase}catch{}throw new Error("Vault Passphrase or Master Secret is required for Zero-Knowledge E2EE encryption/decryption.")}function ie(e,t){t&&h(`vault_${t}`,e),h("vault_passphrase",e)}function ce(e,t){let{publicKey:r,privateKey:n}=o.default.generateKeyPairSync("x25519"),s=r.export({type:"spki",format:"pem"}).toString(),i=o.default.createPublicKey(t),f=o.default.diffieHellman({privateKey:n,publicKey:i}),S=Buffer.from(o.default.hkdfSync("sha256",f,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),u=o.default.randomBytes(12),g=o.default.createCipheriv("aes-256-gcm",S,u),_=g.update(e,"utf8","hex");_+=g.final("hex");let G=g.getAuthTag().toString("hex");return{targetPublicKey:t,ephemeralPublicKey:s,encryptedProjectKey:_,iv:u.toString("hex"),authTag:G}}function ae(e,t){let r=o.default.createPrivateKey(t),n=o.default.createPublicKey(e.ephemeralPublicKey),s=o.default.diffieHellman({privateKey:r,publicKey:n}),i=Buffer.from(o.default.hkdfSync("sha256",s,Buffer.alloc(0),Buffer.from("xtra-workload-envelope"),32)),f=Buffer.from(e.iv,"hex"),S=Buffer.from(e.authTag,"hex"),u=o.default.createDecipheriv("aes-256-gcm",i,f);u.setAuthTag(S);let g=u.update(e.encryptedProjectKey,"hex","utf8");return g+=u.final("utf8"),g}var o,a,U,I,m,H,v,x,V,$,re,h,d,j=K(()=>{o=l(require("crypto")),a=l(require("os")),U=l(require("conf")),I=require("node-machine-id"),m=require("child_process"),H="aes-256-gcm",v=new U.default({projectName:"xtra-cli-crypto"}),x=null;V=e=>{let t=o.default.randomBytes(12),r=X(),n=o.default.createCipheriv(H,r,t),s=n.update(e,"utf8","hex");s+=n.final("hex");let i=n.getAuthTag();return{iv:t.toString("hex"),content:s,tag:i.toString("hex")}},$=e=>{let t=X(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),s=o.default.createDecipheriv(H,t,r);s.setAuthTag(n);let i=s.update(e.content,"hex","utf8");return i+=s.final("utf8"),i},re=e=>o.default.createHash("sha256").update(e).digest("hex"),h=(e,t)=>{try{let n="XtraSecurityCLI",s=e;if(a.default.platform()==="darwin"){(0,m.execFileSync)("security",["add-generic-password","-s",n,"-a",s,"-w",t,"-U"],{stdio:"ignore"});return}else if(a.default.platform()!=="win32"){if(a.default.platform()==="linux")try{(0,m.execFileSync)("secret-tool",["store","--label",n,"service",n,"account",s],{input:t,stdio:["pipe","ignore","ignore"]});return}catch{}}}catch{}let r=V(t);v.set(`secure_${e}`,JSON.stringify(r))},d=e=>{try{let t="XtraSecurityCLI",r=e;if(a.default.platform()==="darwin")return(0,m.execFileSync)("security",["find-generic-password","-s",t,"-a",r,"-w"],{stdio:["ignore","pipe","ignore"]}).toString().trim();if(a.default.platform()!=="win32"){if(a.default.platform()==="linux")try{return(0,m.execFileSync)("secret-tool",["lookup","service",t,"account",r],{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{}}}catch{}try{let t=v.get(`secure_${e}`);if(!t)return null;let r=JSON.parse(t);return $(r)}catch{return null}}});j();0&&(module.exports={createWorkloadKeyEnvelope,decrypt,decryptSecretValue,decryptWorkloadKeyEnvelope,deriveProjectKey,encrypt,encryptSecretValue,hash,resolveVaultPassphrase,saveVaultPassphrase,secureRead,secureSave});
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "xtra-cli",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "CLI for XtraSecurity Platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "xtra": "dist/bin/xtra.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsup src/bin/xtra.ts src/commands/*.ts src/lib/*.ts --format cjs --out-dir dist --minify --clean",
10
+ "build": "tsup src/bin/xtra.ts src/commands/*.ts src/lib/*.ts \"!src/**/*.test.ts\" --format cjs --out-dir dist --minify --clean",
11
11
  "start": "node dist/bin/xtra.js",
12
12
  "dev": "ts-node src/bin/xtra.ts",
13
- "test": "jest",
13
+ "test": "jest --runInBand",
14
14
  "test:watch": "jest --watch",
15
15
  "prepublishOnly": "npm run build"
16
16
  },
@@ -1,16 +0,0 @@
1
- var ie=Object.create;var j=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,de=Object.prototype.hasOwnProperty;var x=(e,t)=>()=>(e&&(t=e(e=0)),t);var H=(e,t)=>{for(var s in t)j(e,s,{get:t[s],enumerable:!0})},K=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of pe(t))!de.call(e,r)&&r!==s&&j(e,r,{get:()=>t[r],enumerable:!(n=ce(t,r))||n.enumerable});return e};var c=(e,t,s)=>(s=e!=null?ie(ge(e)):{},K(t||!e||!e.__esModule?j(s,"default",{value:e,enumerable:!0}):s,e)),le=e=>K(j({},"__esModule",{value:!0}),e);var G={};H(G,{clearConfig:()=>me,deleteConfig:()=>ye,getAuthToken:()=>U,getBreakGlassSession:()=>fe,getConfig:()=>y,getConfigValue:()=>ue,getProjectConfig:()=>we,getRcConfig:()=>ke,setBreakGlassSession:()=>he,setConfig:()=>l});var D,m,O,R,i,q,y,ue,l,me,ye,U,fe,he,we,ke,w=x(()=>{D=c(require("conf")),m=c(require("fs")),O=c(require("path")),R="https://www.xtrasecurity.in/api",i=new D.default({projectName:"xtra-cli",defaults:{apiUrl:R}}),q=i.get("apiUrl");q&&!process.env.XTRA_API_URL&&q.includes("xtra-security.vercel.app")&&i.set("apiUrl",R);y=()=>({...i.store,apiUrl:process.env.XTRA_API_URL||i.get("apiUrl")||R}),ue=e=>i.get(e),l=(e,t)=>{if(i.set(e,t),e==="token"&&process.platform!=="win32"&&m.default.existsSync(i.path))try{m.default.chmodSync(i.path,384)}catch{}},me=()=>i.clear(),ye=e=>i.delete(e),U=()=>i.get("token"),fe=()=>i.get("breakGlassSessionId"),he=e=>{e?i.set("breakGlassSessionId",e):i.delete("breakGlassSessionId")},we=async()=>{try{let e=O.default.join(process.cwd(),"xtra.json");if(m.default.existsSync(e)){let t=m.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},ke=()=>{let e={};try{let t=O.default.join(process.cwd(),".xtrarc");m.default.existsSync(t)&&(e=JSON.parse(m.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||i.get("project")||"",env:e.env||i.get("env")||"development",branch:e.branch||i.get("branch")||"main"}}});var V,J,F,ve,o,f,$=x(()=>{V=c(require("axios"));w();J=c(require("fs")),F=c(require("path")),ve=JSON.parse(J.readFileSync(F.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=y(),t=U();return V.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":ve.version,...t?{Authorization:`Bearer ${t}`}:{}}})},f={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,a)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:r,sourceKey:a})).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}=y(),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}=y(),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 Y(){let e=M.get("masterKey");e||(e=k.default.randomBytes(32).toString("hex"),M.set("masterKey",e));let t=(0,X.machineIdSync)();return k.default.createHash("sha256").update(e+t).digest()}var k,W,X,z,M,Q,Z,ee=x(()=>{k=c(require("crypto")),W=c(require("conf")),X=require("node-machine-id"),z="aes-256-gcm",M=new W.default({projectName:"xtra-cli-crypto"});Q=e=>{let t=k.default.randomBytes(16),s=Y(),n=k.default.createCipheriv(z,s,t),r=n.update(e,"utf8","hex");r+=n.final("hex");let a=n.getAuthTag();return{iv:t.toString("hex"),content:r,tag:a.toString("hex")}},Z=e=>{let t=Y(),s=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),r=k.default.createDecipheriv(z,t,s);r.setAuthTag(n);let a=r.update(e.content,"hex","utf8");return a+=r.final("utf8"),a}});var I={};H(I,{loadAuditLogs:()=>b,logAudit:()=>je,saveAuditLogs:()=>A,syncAuditLogs:()=>xe});function Se(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 se(e){try{if(!y().token)return!1;let s={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:Se(e.details),timestamp:e.timestamp,projectId:e.projectId};return await f.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 je(e,t,s,n){let r={id:(0,te.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:s,details:n,synced:!1},a=b();a.push(r),A(a),se(r).then(p=>{if(p){r.synced=!0;let g=b(),d=g.findIndex(u=>u.id===r.id);d!==-1&&(g[d].synced=!0,A(g))}}).catch(()=>{})}function b(){if(!v.default.existsSync(E))return[];try{let e=v.default.readFileSync(E,"utf-8"),t=JSON.parse(e),s=Z(t);return JSON.parse(s)}catch{return[]}}function A(e){v.default.existsSync(_)||v.default.mkdirSync(_,{recursive:!0});let t=JSON.stringify(e),s=Q(t);v.default.writeFileSync(E,JSON.stringify(s),"utf-8")}async function xe(){let e=b(),t=e.filter(n=>!n.synced);if(t.length===0)return 0;let s=0;for(let n of t)await se(n)&&(n.synced=!0,s++);return s>0&&A(e),s}var v,T,te,_,E,C=x(()=>{v=c(require("fs")),T=c(require("path")),te=require("uuid");ee();w();$();_=T.default.join(process.cwd(),".xtra"),E=T.default.join(_,"audit.enc")});var oe=require("commander"),S=c(require("inquirer"));$();w();var h=c(require("chalk")),P=c(require("ora")),L=new oe.Command("login").description("Authenticate with XtraSecurity").option("-k, --key <key>","Login using an Access Key").option("-e, --email <email>","Login using Email").option("--sso","Login via Web (SSO)").action(async e=>{try{if(!e.key&&!e.email&&!e.sso){let{method:t}=await S.default.prompt([{type:"list",name:"method",message:"How would you like to login?",choices:[{name:"Browser Login (SSO)",value:"sso"},{name:"Access Key",value:"key"},{name:"Email & Password",value:"email"}]}]);if(t==="sso"){await re();return}else if(t==="key"){let{key:s}=await S.default.prompt([{type:"password",name:"key",message:"Enter Access Key:"}]);await ne(s);return}}if(e.sso)await re();else if(e.key)await ne(e.key);else{let{email:t}=e;t||(t=(await S.default.prompt([{type:"input",name:"email",message:"Email:"}])).email);let n=(await S.default.prompt([{type:"password",name:"password",message:"Password:"}])).password,r=(0,P.default)("Authenticating...").start(),a=await f.login(t,n);l("token",a.token),r.succeed("Logged in successfully!");try{let{logAudit:p}=await Promise.resolve().then(()=>(C(),I));p("USER_LOGIN",null,null,{method:"email",email:t})}catch{}}}catch(t){t.response?console.error(h.default.red(`
2
- Error: ${t.response.data.error||"Login failed"}`)):console.error(h.default.red(`
3
- Error: ${t?.response?.data?.error||"An unexpected error occurred"}`)),process.exit(1)}});async function ne(e){let t=(0,P.default)("Authenticating with Access Key...").start(),s=await f.login(void 0,void 0,e);l("token",s.token),s.user&&console.log(h.default.green(`
4
- Logged in as ${s.user.email}`)),t.succeed("Logged in successfully!");try{let{logAudit:n}=await Promise.resolve().then(()=>(C(),I));n("USER_LOGIN",null,null,{method:"api_key",email:s.user?.email})}catch{}}async function re(){let e=require("http"),{default:t}=await import("open");return new Promise(s=>{let n=e.createServer(async(r,a)=>{let p=new URL(r.url,`http://${r.headers.host}`),g=p.searchParams.get("token"),d=p.searchParams.get("email"),u=p.searchParams.get("workspaceId"),B=p.searchParams.get("workspaceName");if(g){l("token",g),u&&l("workspace",u),a.writeHead(200,{"Content-Type":"text/html"}),a.write(`
5
- <html>
6
- <body style="background:#111;color:#eee;font-family:sans-serif;text-align:center;padding:50px;">
7
- <h1>Login Successful</h1>
8
- <p>You have successfully logged in to XtraSync.</p>
9
- <p>You can now close this tab and return to your terminal.</p>
10
- <script>
11
- setTimeout(function() { window.close(); }, 1000);
12
- </script>
13
- </body>
14
- </html>
15
- `),console.log(h.default.green(`
16
- \u2714 SS0 Login Successful! Logged in as ${d}`)),u&&console.log(h.default.dim(`Selected Workspace: ${B} (${u})`));try{let{logAudit:N}=await Promise.resolve().then(()=>(C(),I));N("USER_LOGIN","global","cli",{method:"sso",email:d,workspaceId:u,workspaceName:B})}catch{}a.end(()=>{n.close(),setTimeout(()=>{process.exit(0)},1e3)})}else a.writeHead(400),a.end("Missing token")});n.listen(0,async()=>{let r=n.address(),p=`http://localhost:${typeof r=="string"?0:r?.port}`,{apiUrl:g}=(w(),le(G)).getConfig(),d=`${g}/auth/cli/sso?callbackUrl=${encodeURIComponent(p)}`;console.log(h.default.blue(`Waiting for browser login... (Opening ${d})`)),await t(d)})})}$();w();var ae=c(require("inquirer"));jest.mock("../lib/api");jest.mock("../lib/config");jest.mock("inquirer");jest.mock("ora",()=>jest.fn(()=>({start:jest.fn().mockReturnThis(),succeed:jest.fn().mockReturnThis(),fail:jest.fn().mockReturnThis()})));describe("Login Command",()=>{let e=f,t=ae.default;beforeEach(()=>{jest.clearAllMocks()}),it("should login with API key option",async()=>{e.login.mockResolvedValue({token:"test-token-from-key"});let s={key:"xtra_key_abc123"};await L._actionHandler(s),expect(e.login).toHaveBeenCalledWith(void 0,void 0,"xtra_key_abc123"),expect(l).toHaveBeenCalledWith("token","test-token-from-key")}),it("should prompt for email and password if no options provided",async()=>{t.prompt.mockResolvedValueOnce({method:"email"}).mockResolvedValueOnce({email:"test@example.com"}).mockResolvedValueOnce({password:"password123"}),e.login.mockResolvedValue({token:"email-token"}),await L._actionHandler({}),expect(t.prompt).toHaveBeenCalledTimes(3),expect(e.login).toHaveBeenCalledWith("test@example.com","password123",void 0)}),it("should handle login failure gracefully",async()=>{e.login.mockRejectedValue(new Error("Invalid credentials"));let s={key:"bad-key"};await expect(L._actionHandler(s)).rejects.toThrow("Invalid credentials")})});
@@ -1 +0,0 @@
1
- var v=Object.create;var l=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var b=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $(t))!x.call(e,o)&&o!==s&&l(e,o,{get:()=>t[o],enumerable:!(n=j(t,o))||n.enumerable});return e};var p=(e,t,s)=>(s=e!=null?v(S(e)):{},b(t||!e||!e.__esModule?l(s,"default",{value:e,enumerable:!0}):s,e));var w=p(require("axios"));var m=p(require("conf"));var d="https://www.xtrasecurity.in/api",g=new m.default({projectName:"xtra-cli",defaults:{apiUrl:d}}),y=g.get("apiUrl");y&&!process.env.XTRA_API_URL&&y.includes("xtra-security.vercel.app")&&g.set("apiUrl",d);var c=()=>({...g.store,apiUrl:process.env.XTRA_API_URL||g.get("apiUrl")||d});var u=()=>g.get("token");var h=p(require("fs")),f=p(require("path")),A=JSON.parse(h.readFileSync(f.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=c(),t=u();return w.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":A.version,...t?{Authorization:`Bearer ${t}`}:{}}})},a={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}=c(),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}=c(),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 k=p(require("axios"));jest.mock("axios");jest.mock("./config");var R=k.default;describe("API Client",()=>{let e=jest.fn(),t=jest.fn(),s=jest.fn();beforeAll(()=>{R.create=e,c.mockReturnValue({apiUrl:"http://localhost:3000/api"}),u.mockReturnValue("test-token-123"),e.mockReturnValue({get:t,post:s})}),beforeEach(()=>{jest.clearAllMocks()}),describe("login",()=>{it("should send login request with email and password",async()=>{s.mockResolvedValue({data:{token:"new-token"}});let n=await a.login("user@example.com","password123");expect(s).toHaveBeenCalledWith("/auth/cli-login",{email:"user@example.com",password:"password123",apiKey:void 0}),expect(n).toEqual({token:"new-token"})}),it("should send login request with API key",async()=>{s.mockResolvedValue({data:{token:"api-key-token"}});let n=await a.login(void 0,void 0,"xtra_key_abc123");expect(s).toHaveBeenCalledWith("/auth/cli-login",{email:void 0,password:void 0,apiKey:"xtra_key_abc123"}),expect(n).toEqual({token:"api-key-token"})})}),describe("getSecrets",()=>{it("should fetch secrets for project and environment",async()=>{let n={secrets:[{key:"DB_URL",value:"postgres://..."}]};t.mockResolvedValue({data:n});let o=await a.getSecrets("proj-123","production","main");expect(t).toHaveBeenCalledWith("/projects/proj-123/envs/production/secrets?branch=main"),expect(o).toEqual(n)}),it("should use default branch if not specified",async()=>{t.mockResolvedValue({data:{secrets:[]}}),await a.getSecrets("proj-123","dev"),expect(t).toHaveBeenCalledWith("/projects/proj-123/envs/dev/secrets?branch=main")})}),describe("setSecrets",()=>{it("should post secrets to API",async()=>{let n={DB_URL:"postgres://new",API_KEY:"key123"};s.mockResolvedValue({data:{success:!0}});let o=await a.setSecrets("proj-123","staging",n);expect(s).toHaveBeenCalledWith("/projects/proj-123/envs/staging/secrets",{secrets:n,expectedVersions:void 0,branch:"main"}),expect(o).toEqual({success:!0})})}),describe("rotateSecret",()=>{it("should rotate secret with strategy",async()=>{s.mockResolvedValue({data:{newValue:"rotated-value"}});let n=await a.rotateSecret("proj-123","prod","API_KEY","regenerate");expect(s).toHaveBeenCalledWith("/projects/proj-123/envs/prod/secrets/API_KEY/rotate",{strategy:"regenerate",parsedNewValue:void 0}),expect(n).toEqual({newValue:"rotated-value"})})})});
@@ -1 +0,0 @@
1
- var h=Object.create;var f=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty;var C=(e,t,o,g)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of y(t))!S.call(e,s)&&s!==o&&f(e,s,{get:()=>t[s],enumerable:!(g=x(t,s))||g.enumerable});return e};var r=(e,t,o)=>(o=e!=null?h(j(e)):{},C(t||!e||!e.__esModule?f(o,"default",{value:e,enumerable:!0}):o,e));var d=r(require("conf")),a=r(require("fs")),m=r(require("path")),p="https://www.xtrasecurity.in/api",c=new d.default({projectName:"xtra-cli",defaults:{apiUrl:p}}),u=c.get("apiUrl");u&&!process.env.XTRA_API_URL&&u.includes("xtra-security.vercel.app")&&c.set("apiUrl",p);var l=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||p});var i=async()=>{try{let e=m.default.join(process.cwd(),"xtra.json");if(a.default.existsSync(e)){let t=a.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}};var n=r(require("fs"));jest.mock("conf");describe("Config Management",()=>{beforeEach(()=>{jest.clearAllMocks()}),describe("getConfig",()=>{it("should return config with API URL from env if set",()=>{process.env.XTRA_API_URL="https://api.production.com";let e=l();expect(e.apiUrl).toBe("https://api.production.com"),delete process.env.XTRA_API_URL}),it("should fallback to default API URL",()=>{delete process.env.XTRA_API_URL;let e=l();expect(e.apiUrl).toBeDefined()})}),describe("getProjectConfig",()=>{it("should return null if xtra.json does not exist",async()=>{jest.spyOn(n.default,"existsSync").mockReturnValue(!1);let e=await i();expect(e).toBeNull()}),it("should parse and return xtra.json if it exists",async()=>{let e={projectId:"test-project",env:"production"};jest.spyOn(n.default,"existsSync").mockReturnValue(!0),jest.spyOn(n.default,"readFileSync").mockReturnValue(JSON.stringify(e));let t=await i();expect(t).toEqual(e)}),it("should return null if JSON parsing fails",async()=>{jest.spyOn(n.default,"existsSync").mockReturnValue(!0),jest.spyOn(n.default,"readFileSync").mockReturnValue("invalid json{");let e=await i();expect(e).toBeNull()})})});