nskd-lbr 1.1.6 → 1.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nskd-lbr",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "A JavaScript library for working with NoSkid certificates.",
5
5
  "main": "src/nskd-lbr.js",
6
6
  "scripts": {
package/src/nskd-lbr.js CHANGED
@@ -295,12 +295,16 @@ Certificate Details:
295
295
  if (!match) return null;
296
296
 
297
297
  const certInfoEncoded = match[2];
298
- const certInfoDecoded = atob(certInfoEncoded.replace(/=/g, ''));
298
+ const certInfoDecoded = new TextDecoder("utf-8").decode(
299
+ Uint8Array.from(atob(certInfoEncoded.replace(/=/g, '')), c => c.charCodeAt(0))
300
+ );
299
301
  const usernameMatch = certInfoDecoded.match(/CERT-\d+-(.+)/);
300
302
  const username = usernameMatch ? usernameMatch[1] : null;
301
303
 
302
304
  const dateInfoEncoded = match[3];
303
- const dateInfoDecoded = atob(dateInfoEncoded.replace(/=/g, ''));
305
+ const dateInfoDecoded = new TextDecoder("utf-8").decode(
306
+ Uint8Array.from(atob(dateInfoEncoded.replace(/=/g, '')), c => c.charCodeAt(0))
307
+ );
304
308
  const dateMatch = dateInfoDecoded.match(/CREATED-(.+)/);
305
309
  const creationDate = dateMatch ? dateMatch[1] : null;
306
310
 
@@ -5,4 +5,4 @@ Certificate Details:
5
5
  - Percentage: ${e.percentage}%
6
6
  - Creation Date: ${e.creationDate}
7
7
  - Country: ${e.country} (${e.countryCode})
8
- `.trim()):"No certificate data available"}reset(){this.certificateData=null,this.verificationKey=null,this.localData=null,this.isValid=!1,this.nskdLbrLog("Certificate data reset","info")}readFileAsArrayBuffer(a){return new Promise((t,e)=>{var i=new FileReader;i.onload=e=>t(e.target.result),i.onerror=()=>e(new Error("Error reading file")),i.readAsArrayBuffer(a)})}async extractTextFromPng(i){try{var a=new Uint8Array(i);if(137!==a[0]||80!==a[1]||78!==a[2]||71!==a[3])throw new Error("Not a valid PNG file");let e=8,t=null;for(;e<a.length-12;){var r=a[e]<<24|a[e+1]<<16|a[e+2]<<8|a[e+3];if("tEXt"===String.fromCharCode(a[e+4],a[e+5],a[e+6],a[e+7])){var s=a.slice(e+8,e+8+r),o=new TextDecoder("utf-8").decode(s),c=o.indexOf("\0");if(-1!==c){var n=o.substring(0,c),l=o.substring(c+1);if("noskid-key"===n){t=l;break}}}e+=8+r+4}return t?(this.nskdLbrLog("Certificate data extracted successfully from PNG","success"),t):(this.nskdLbrLog("No 'noskid-key' text chunk found in PNG","error"),null)}catch(e){return this.nskdLbrLog("Error extracting text from PNG: "+e.message,"error"),null}}extractVerificationKey(e){try{var t=/-*BEGIN NOSKID KEY-*\s*([a-f0-9]{64})/i,i=e.match(t);return i?i[1].toLowerCase():null}catch(e){return this.nskdLbrLog("Error extracting verification key: "+e.message,"error"),null}}extractLocalData(e){try{var t,i,a,r,s,o=/-----BEGIN NOSKID KEY-----\s*([a-f0-9]+)\s*([A-Za-z0-9+/=]+)\s*([A-Za-z0-9+/=]+)\s*-----END NOSKID KEY-----/,c=e.match(o);return c?(t=c[2],a=(i=atob(t.replace(/=/g,"")).match(/CERT-\d+-(.+)/))?i[1]:null,r=c[3],{username:a,creationDate:(s=atob(r.replace(/=/g,"")).match(/CREATED-(.+)/))?s[1]:null}):null}catch(e){return this.nskdLbrLog("Error extracting local data: "+e.message,"error"),null}}async verifyWithAPI(){try{this.nskdLbrLog("Verifying certificate with server...","info");let e=new AbortController;var t=setTimeout(()=>e.abort(),this.timeout),i=await fetch(this.apiUrl+"?key="+encodeURIComponent(this.verificationKey),{signal:e.signal,headers:{"User-Agent":"NskdLbr/1.1.0"}});if(clearTimeout(t),!i.ok)throw new Error(`HTTP ${i.status}: `+i.statusText);var a=await i.json();if(!a.success)return this.isValid=!1,this.nskdLbrLog("Certificate verification failed: "+a.message,"error"),{valid:!1,message:a.message,cached:a.cached||!1,strictCheck:this.strictCheck};if(a.data.boosted&&!this.allowAchievements)return this.isValid=!1,this.nskdLbrLog("Certificate uses achievements boost, which is not allowed by allowAchievements","error"),{valid:!1,message:"Certificate uses achievements boost",cached:a.cached||!1,strictCheck:this.strictCheck};if(a.data.boosted&&this.nskdLbrLog("Certificate is achievement-boosted","warning"),this.localData&&this.strictCheck){var r=!this.useLegacyAPI&&a.data.nickname||a.data.username,s=this.compareData(this.localData,{...a.data,username:r});if(!s.valid)return this.isValid=!1,this.nskdLbrLog("Certificate data mismatch!","error"),this.nskdLbrLog("Mismatch reason: "+s.reason,"error"),this.nskdLbrLog("Note: Strict checking is enabled. Set strictCheck to false to skip local data validation.","warning"),{valid:!1,message:"Data mismatch: "+s.reason,cached:a.cached||!1,strictCheck:!0};this.nskdLbrLog("Local data validation passed","success")}else this.localData&&!this.strictCheck&&this.nskdLbrLog("Strict checking disabled - skipping local data validation","warning");return this.isValid=!0,this.certificateData=a.data,this.nskdLbrLog("Certificate is VALID!","success"),{valid:!0,message:"Certificate verified successfully",data:a.data,query:a.query||this.verificationKey,cached:a.cached||!1,strictCheck:this.strictCheck}}catch(e){if("AbortError"===e.name)throw new Error("Request timeout - server took too long to respond");throw new Error("API verification failed: "+e.message)}}compareData(e,t){return e&&t?e.username!==t.username?{valid:!1,reason:`Username mismatch: Local=${e.username}, API=`+t.username}:(e=e.creationDate.substring(0,16))!==(t=t.creationDate.substring(0,16))?{valid:!1,reason:`Creation date mismatch: Local=${e}, API=`+t}:{valid:!0}:{valid:!1,reason:"Missing data for comparison"}}}"undefined"!=typeof module&&module.exports?module.exports=NskdLbr:window.NskdLbr=NskdLbr;
8
+ `.trim()):"No certificate data available"}reset(){this.certificateData=null,this.verificationKey=null,this.localData=null,this.isValid=!1,this.nskdLbrLog("Certificate data reset","info")}readFileAsArrayBuffer(r){return new Promise((t,e)=>{var i=new FileReader;i.onload=e=>t(e.target.result),i.onerror=()=>e(new Error("Error reading file")),i.readAsArrayBuffer(r)})}async extractTextFromPng(i){try{var r=new Uint8Array(i);if(137!==r[0]||80!==r[1]||78!==r[2]||71!==r[3])throw new Error("Not a valid PNG file");let e=8,t=null;for(;e<r.length-12;){var a=r[e]<<24|r[e+1]<<16|r[e+2]<<8|r[e+3];if("tEXt"===String.fromCharCode(r[e+4],r[e+5],r[e+6],r[e+7])){var s=r.slice(e+8,e+8+a),o=new TextDecoder("utf-8").decode(s),c=o.indexOf("\0");if(-1!==c){var n=o.substring(0,c),l=o.substring(c+1);if("noskid-key"===n){t=l;break}}}e+=8+a+4}return t?(this.nskdLbrLog("Certificate data extracted successfully from PNG","success"),t):(this.nskdLbrLog("No 'noskid-key' text chunk found in PNG","error"),null)}catch(e){return this.nskdLbrLog("Error extracting text from PNG: "+e.message,"error"),null}}extractVerificationKey(e){try{var t=/-*BEGIN NOSKID KEY-*\s*([a-f0-9]{64})/i,i=e.match(t);return i?i[1].toLowerCase():null}catch(e){return this.nskdLbrLog("Error extracting verification key: "+e.message,"error"),null}}extractLocalData(e){try{var t,i,r,a,s,o=/-----BEGIN NOSKID KEY-----\s*([a-f0-9]+)\s*([A-Za-z0-9+/=]+)\s*([A-Za-z0-9+/=]+)\s*-----END NOSKID KEY-----/,c=e.match(o);return c?(t=c[2],r=(i=new TextDecoder("utf-8").decode(Uint8Array.from(atob(t.replace(/=/g,"")),e=>e.charCodeAt(0))).match(/CERT-\d+-(.+)/))?i[1]:null,a=c[3],{username:r,creationDate:(s=new TextDecoder("utf-8").decode(Uint8Array.from(atob(a.replace(/=/g,"")),e=>e.charCodeAt(0))).match(/CREATED-(.+)/))?s[1]:null}):null}catch(e){return this.nskdLbrLog("Error extracting local data: "+e.message,"error"),null}}async verifyWithAPI(){try{this.nskdLbrLog("Verifying certificate with server...","info");let e=new AbortController;var t=setTimeout(()=>e.abort(),this.timeout),i=await fetch(this.apiUrl+"?key="+encodeURIComponent(this.verificationKey),{signal:e.signal,headers:{"User-Agent":"NskdLbr/1.1.0"}});if(clearTimeout(t),!i.ok)throw new Error(`HTTP ${i.status}: `+i.statusText);var r=await i.json();if(!r.success)return this.isValid=!1,this.nskdLbrLog("Certificate verification failed: "+r.message,"error"),{valid:!1,message:r.message,cached:r.cached||!1,strictCheck:this.strictCheck};if(r.data.boosted&&!this.allowAchievements)return this.isValid=!1,this.nskdLbrLog("Certificate uses achievements boost, which is not allowed by allowAchievements","error"),{valid:!1,message:"Certificate uses achievements boost",cached:r.cached||!1,strictCheck:this.strictCheck};if(r.data.boosted&&this.nskdLbrLog("Certificate is achievement-boosted","warning"),this.localData&&this.strictCheck){var a=!this.useLegacyAPI&&r.data.nickname||r.data.username,s=this.compareData(this.localData,{...r.data,username:a});if(!s.valid)return this.isValid=!1,this.nskdLbrLog("Certificate data mismatch!","error"),this.nskdLbrLog("Mismatch reason: "+s.reason,"error"),this.nskdLbrLog("Note: Strict checking is enabled. Set strictCheck to false to skip local data validation.","warning"),{valid:!1,message:"Data mismatch: "+s.reason,cached:r.cached||!1,strictCheck:!0};this.nskdLbrLog("Local data validation passed","success")}else this.localData&&!this.strictCheck&&this.nskdLbrLog("Strict checking disabled - skipping local data validation","warning");return this.isValid=!0,this.certificateData=r.data,this.nskdLbrLog("Certificate is VALID!","success"),{valid:!0,message:"Certificate verified successfully",data:r.data,query:r.query||this.verificationKey,cached:r.cached||!1,strictCheck:this.strictCheck}}catch(e){if("AbortError"===e.name)throw new Error("Request timeout - server took too long to respond");throw new Error("API verification failed: "+e.message)}}compareData(e,t){return e&&t?e.username!==t.username?{valid:!1,reason:`Username mismatch: Local=${e.username}, API=`+t.username}:(e=e.creationDate.substring(0,16))!==(t=t.creationDate.substring(0,16))?{valid:!1,reason:`Creation date mismatch: Local=${e}, API=`+t}:{valid:!0}:{valid:!1,reason:"Missing data for comparison"}}}"undefined"!=typeof module&&module.exports?module.exports=NskdLbr:window.NskdLbr=NskdLbr;