icoa-cli 2.19.278 → 2.19.279
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/ctfd-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createWriteStream as e,mkdirSync as t}from"node:fs";import{join as s}from"node:path";import{pipeline as o}from"node:stream/promises";import{Readable as
|
|
1
|
+
import{createWriteStream as e,mkdirSync as t}from"node:fs";import{join as s}from"node:path";import{pipeline as o}from"node:stream/promises";import{Readable as a}from"node:stream";export class CTFdClient{baseUrl;token;sessionCookie;csrfNonce;constructor(e,t,s,o){this.baseUrl=e.replace(/\/+$/,""),this.token=t,this.sessionCookie=s||"",this.csrfNonce=o||""}getAuthHeaders(){if(this.token)return{Authorization:`Token ${this.token}`};if(this.sessionCookie){const e={Cookie:this.sessionCookie};return this.csrfNonce&&(e["CSRF-Token"]=this.csrfNonce),e}return{}}async fetchCsrfNonce(){if(this.csrfNonce)return this.csrfNonce;try{const e=await fetch(this.baseUrl,{headers:this.sessionCookie?{Cookie:this.sessionCookie}:{}}),t=(await e.text()).match(/csrfNonce['":\s]+['"]([^'"]+)['"]/);if(t)return this.csrfNonce=t[1],this.csrfNonce}catch{}return""}async request(e,t,s){this.sessionCookie&&!this.csrfNonce&&await this.fetchCsrfNonce();const o=`${this.baseUrl}/api/v1${t}`,a={...this.getAuthHeaders()};void 0!==s&&(a["Content-Type"]="application/json");const n=await fetch(o,{method:e,headers:a,body:void 0!==s?JSON.stringify(s):void 0});if(!n.ok){const e=await n.text().catch(()=>"Unknown error");throw new Error(`CTFd API error (${n.status}): ${e}`)}const i=await n.json();if(!1===i.success)throw new Error(`CTFd error: ${i.errors?.join(", ")||"Unknown error"}`);return i.data}async testConnection(){try{return await this.request("GET","/users/me")}catch(e){if(this.sessionCookie&&e.message?.includes("403"))return this.testConnectionViaProfile();throw e}}async testConnectionViaProfile(){const e=await fetch(`${this.baseUrl}/settings`,{headers:{Cookie:this.sessionCookie}});if(!e.ok)throw new Error("Session expired or invalid.");const t=await e.text(),s=t.match(/name="name"[^>]*value="([^"]+)"/)||t.match(/<input[^>]*id="name"[^>]*value="([^"]+)"/),o=s?.[1]||"User",a=t.match(/user_id['":\s]+(\d+)/)||t.match(/userId['":\s]+(\d+)/),n=a?parseInt(a[1],10):0,i=t.match(/csrfNonce['":\s]+['"]([^'"]+)['"]/);return i&&(this.csrfNonce=i[1]),{id:n,name:o,score:0,team_id:0,country:""}}async getChallenges(){return this.request("GET","/challenges")}async getChallenge(e){return this.request("GET",`/challenges/${e}`)}async submitFlag(e,t){this.sessionCookie&&!this.csrfNonce&&await this.fetchCsrfNonce();const s=await fetch(`${this.baseUrl}/api/v1/challenges/attempt`,{method:"POST",headers:{...this.getAuthHeaders(),"Content-Type":"application/json"},body:JSON.stringify({challenge_id:e,submission:t})});if(!s.ok){const e=await s.text().catch(()=>"Unknown error");throw new Error(`CTFd API error (${s.status}): ${e}`)}return(await s.json()).data}async getScoreboard(){return this.request("GET","/scoreboard")}async getTeam(){return this.request("GET","/teams/me")}async getCompetitionMeta(){const e=await fetch(this.baseUrl),t=await e.text(),s=t.match(/'start'\s*:\s*(\d+)/),o=t.match(/'end'\s*:\s*(\d+)/),a=t.match(/'userMode'\s*:\s*"([^"]+)"/),n=t.match(/'csrfNonce'\s*:\s*"([^"]+)"/);return{start:s?parseInt(s[1],10):null,end:o?parseInt(o[1],10):null,userMode:a?.[1]||"users",csrfNonce:n?.[1]||""}}async getChallengeFiles(e){return(await this.getChallenge(e)).files||[]}async downloadFile(n,i){t(i,{recursive:!0});const r=n.startsWith("http")?n:`${this.baseUrl}/${n.replace(/^\//,"")}`,c=await fetch(r,{headers:this.getAuthHeaders(),redirect:"follow"});if(!c.ok||!c.body)throw new Error(`Failed to download: ${r}`);const h=(n.split("/").pop()||"file").split("?")[0],l=s(i,h),d=e(l);return await o(a.fromWeb(c.body),d),l}async getTokenViaIcoaApi(e,t){const s=JSON.stringify({name:e,password:t}),o={"Content-Type":"application/json"};try{const e=await fetch(`${this.baseUrl}/api/icoa/token`,{method:"POST",headers:o,body:s,signal:AbortSignal.timeout(5e3)});if(e.ok){const t=await e.json();if(t.success&&t.data?.token)return t.data.token}}catch{}try{const e=await fetch(`${this.baseUrl}:9090/api/icoa/token`,{method:"POST",headers:o,body:s,signal:AbortSignal.timeout(5e3)});if(e.ok){const t=await e.json();if(t.success&&t.data?.token)return t.data.token}}catch{}return null}async loginWithCredentials(e,t){const s=await this.getTokenViaIcoaApi(e,t);if(s)return{token:s,session:"",csrf:""};const o=await fetch(`${this.baseUrl}/login`),a=await o.text(),n=a.match(/name="nonce"[^>]*value="([^"]+)"/)||a.match(/value="([^"]+)"[^>]*name="nonce"/)||a.match(/id="nonce"[^>]*value="([^"]+)"/)||a.match(/csrfNonce['":\s]+['"]([^'"]+)['"]/),i=n?.[1]||"";if(!i)throw new Error("Could not extract CSRF nonce from login page.");const r=o.headers.getSetCookie?.()||[],c=r.map(e=>e.split(";")[0]).join("; "),h=await fetch(`${this.baseUrl}/login`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Cookie:c},body:new URLSearchParams({name:e,password:t,nonce:i,_submit:"Submit"}),redirect:"manual"}),l=h.headers.getSetCookie?.()||[],d=new Map;for(const e of[...r,...l]){const t=e.split(";")[0],s=t.indexOf("=");s>0&&d.set(t.slice(0,s),t.slice(s+1))}const f=[...d.entries()].map(([e,t])=>`${e}=${t}`).join("; "),u=h.headers.get("location")||"";if(!(h.status>=300&&h.status<400)||u.includes("/login"))throw new Error("Invalid username or password.");try{const e=await fetch(`${this.baseUrl}/settings`,{headers:{Cookie:f}}),t=(await e.text()).match(/csrfNonce['":\s]+['"]([^'"]+)['"]/),s=t?.[1]||i,o=await fetch(`${this.baseUrl}/api/v1/tokens`,{method:"POST",headers:{"Content-Type":"application/json",Cookie:f,"CSRF-Token":s},body:JSON.stringify({expiration:"2026-12-31T23:59:59+00:00"})});if(o.ok){const e=await o.json();if(e.success&&e.data?.value)return{token:e.data.value,session:"",csrf:""}}}catch{}let m="";try{const e=await fetch(`${this.baseUrl}/challenges`,{headers:{Cookie:f}}),t=(await e.text()).match(/csrfNonce['":\s]+['"]([^'"]+)['"]/);t&&(m=t[1])}catch{}return{token:"",session:f,csrf:m}}}
|
package/dist/lib/hint-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
(function(a,b){const v=a0b,c=a();while(!![]){try{const d=parseInt(v(0x141))/(0x2*0x11f1+0x17a0+0x3b81*-0x1)+-parseInt(v(0x14b))/(-0x374+-0xb50+0x2*0x763)+parseInt(v(0x146))/(0xb49+-0x3*0xa1d+0x1311)*(parseInt(v(0x144))/(-0x5cf+0x1a11+0x143e*-0x1))+-parseInt(v(0x151))/(-0x4f*0x35+0x1e09+-0xda9)*(parseInt(v(0x145))/(-0x394+0x1c9a+0x20*-0xc8))+-parseInt(v(0x13d))/(0xe48+0x205c+-0x2e9d*0x1)*(parseInt(v(0x13f))/(-0x2*-0x137b+0xeff+-0x35ed))+parseInt(v(0x157))/(-0x26c9*-0x1+0x62+0x1*-0x2722)*(-parseInt(v(0x150))/(0x1a*0x68+0x9*-0x2f9+0x115*0xf))+parseInt(v(0x158))/(0x1834+0x3*0x33b+0x4d6*-0x7);if(d===b)break;else c['push'](c['shift']());}catch(e){c['push'](c['shift']());}}}(a0a,-0x47*-0x103+0x387a*-0x40+0x1a3f8d));function a0b(a,b){a=a-(0x1a3*0x2+-0x20d5+0x1ecc);const c=a0a();let d=c[a];if(a0b['zJfbza']===undefined){var e=function(i){const j='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let l='',m='';for(let n=0x124c+0x1*-0x1cb1+0xa65,o,p,q=0x5*-0x6e5+0x1*-0x1939+-0x3bb2*-0x1;p=i['charAt'](q++);~p&&(o=n%(-0x862*-0x2+0x127*0x5+0x153*-0x11)?o*(0x1*-0x2174+-0x11e2+0xd5*0x3e)+p:p,n++%(-0x25a*0x7+-0x1*-0x16db+-0x661))?l+=String['fromCharCode'](-0xae2+0x9*-0x3d0+-0x19*-0x1d9&o>>(-(0x4*0x43f+-0x1a82+0x988)*n&0x46*-0xf+-0xf*0x1d2+0x1f6e)):0x2*0x1bf+0x1*0x130b+-0x1689){p=j['indexOf'](p);}for(let r=0x1*0xbdb+-0x1af*0x11+0x1d*0x94,s=l['length'];r<s;r++){m+='%'+('00'+l['charCodeAt'](r)['toString'](0x21d0+-0xffd+-0x1*0x11c3))['slice'](-(-0x4*0x7a+-0x2d*0x97+0x1c75*0x1));}return decodeURIComponent(m);};a0b['pVMqxy']=e,a0b['ISukAL']={},a0b['zJfbza']=!![];}const f=c[-0xf77+0x1*-0x16af+0x2626],g=a+f,h=a0b['ISukAL'][g];return!h?(d=a0b['pVMqxy'](d),a0b['ISukAL'][g]=d):d=h,d;}import{getConfig as a0c}from'./config.js';export async function requestHint(d){const w=a0b,f=a0c(),g=f[w(0x155)]||w(0x14e),h=d[w(0x13e)]||f['language']||'en',j=d[w(0x154)]??-0x1*0xb62+0x1f44+0xb5e,k=[g+w(0x156)+d[w(0x14a)]+w(0x142),g+w(0x147)+d[w(0x14a)]+w(0x142)];let l=null;for(const p of k)try{const q=await fetch(p,{'method':w(0x14c),'headers':{'Content-Type':'application/json','User-Agent':w(0x149)},'body':JSON['stringify']({'token':d['token'],'question':d[w(0x143)],'level':d['level'],'lang':h}),'signal':AbortSignal['timeout'](j)}),r=await q['json']()['catch'](()=>({}));if(!q['ok']||!(0x2*0x2b0+-0x7b8*-0x1+0x1*-0xd17)===r[w(0x140)]){if(l={'status':q[w(0x14d)],'message':r?.[w(0x152)]||'hint\x20request\x20failed\x20('+q[w(0x14d)]+')'},q[w(0x14d)]>=0x26c9*0x1+0x21a*-0x11+-0x17f&&q[w(0x14d)]<-0x2fb*0x6+0xb9*0x1f+-0x291)throw l;continue;}return r[w(0x148)];}catch(u){if(u&&w(0x14f)==typeof u&&w(0x14d)in u)throw u;l={'status':0x0,'message':u?.[w(0x152)]||'network\x20error'};}const m={};m['status']=0x0,m[w(0x152)]=w(0x153);throw l||m;}function a0a(){const x=['AgLUDcbbueKGDw5YzwfJAgfIBgu','DgLTzw91De1Z','y3rMzfvYBa','l2fWAs9Py29Hl2v4yw1ZlW','odfbr3vfqK4','mZeWmJaYnJrVt21Twg4','mJiYmZqXwxbRD0vk','BgfUzW','mZKYzuTxq1Hx','C3vJy2vZCW','mJmYmti5DNHOs1fd','l2HPBNq','CxvLC3rPB24','mte0mtaWqvPTqKHx','mJGWotjPshjyB1u','mtiZt0jSsgDg','oJKWotaVyxbPl2LJB2eVzxHHBxmV','zgf0yq','AwnVys1JBgK','zxHHBuLK','mJuYnJmYnhb0q01wrG','ue9tva','C3rHDhvZ','Ahr0Chm6lY9WCMfJDgLJzs5Py29HmJaYnI5HDq','B2jQzwn0','ntaZndeWzuXhqK9P','mtq1CgLNuhj5','BwvZC2fNzq'];a0a=function(){return x;};return a0a();}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "icoa-cli",
|
|
3
|
-
"version": "2.19.
|
|
3
|
+
"version": "2.19.279",
|
|
4
4
|
"description": "ICOA CLI — The world's first CLI-native cyber & AI security olympiad terminal: AI4CTF (Day 1), CTF4AI (Day 2), VLA4CTF (Pioneer Round — embodied AI)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|