nskd-lbr 1.0.0 → 1.0.1

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.0.0",
3
+ "version": "1.0.1",
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
@@ -32,7 +32,7 @@ class NskdLbr {
32
32
  if (this.debug) {
33
33
  const timestamp = new Date().toLocaleTimeString();
34
34
  const prefix = `[${timestamp}] NoSkid:`;
35
-
35
+
36
36
  switch (level) {
37
37
  case 'error':
38
38
  console.error(prefix, message);
@@ -61,7 +61,7 @@ class NskdLbr {
61
61
  async loadFromFile(file) {
62
62
  try {
63
63
  this.nskdLbrLog('Starting certificate verification process...', 'info');
64
-
64
+
65
65
  if (!file) {
66
66
  throw new Error('No file provided');
67
67
  }
@@ -73,7 +73,7 @@ class NskdLbr {
73
73
  this.nskdLbrLog(`Processing certificate file: ${file.name}`, 'info');
74
74
 
75
75
  const arrayBuffer = await this.readFileAsArrayBuffer(file);
76
-
76
+
77
77
  const extractedText = await this.extractTextFromPng(arrayBuffer);
78
78
  if (!extractedText) {
79
79
  throw new Error('Could not extract verification data from file');
@@ -134,9 +134,20 @@ class NskdLbr {
134
134
  * @returns {Object|null} Certificate data or null if not loaded/verified
135
135
  */
136
136
  getCertificateData() {
137
- return this.certificateData;
137
+ if (!this.certificateData) {
138
+ return null;
139
+ }
140
+
141
+ return {
142
+ ...this.certificateData,
143
+ key: this.verificationKey,
144
+ localUsername: this.localData ? this.localData.username : null,
145
+ localCreationDate: this.localData ? this.localData.creationDate : null
146
+ };
138
147
  }
139
148
 
149
+
150
+
140
151
  /**
141
152
  * Check if the certificate is valid
142
153
  * @returns {boolean} True if certificate is valid
@@ -5,4 +5,4 @@ Certificate Details:
5
5
  - Percentage: ${t.percentage}%
6
6
  - Creation Date: ${t.creationDate}
7
7
  - Country: ${t.country} (${t.countryCode})
8
- `.trim()}reset(){this.certificateData=null,this.verificationKey=null,this.localData=null,this.isValid=!1,this.nskdLbrLog("Certificate data reset","info")}readFileAsArrayBuffer(t){return new Promise((e,r)=>{const i=new FileReader;i.onload=a=>e(a.target.result),i.onerror=()=>r(new Error("Error reading file")),i.readAsArrayBuffer(t)})}async extractTextFromPng(t){try{const e=new Uint8Array(t);if(!(e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71))throw new Error("Not a valid PNG file");let r=8,i=null;for(;r<e.length-12;){const a=e[r]<<24|e[r+1]<<16|e[r+2]<<8|e[r+3];if(String.fromCharCode(e[r+4],e[r+5],e[r+6],e[r+7])==="tEXt"){const l=e.slice(r+8,r+8+a),s=new TextDecoder("utf-8").decode(l),o=s.indexOf("\0");if(o!==-1){const n=s.substring(0,o),d=s.substring(o+1);if(n==="noskid-key"){i=d;break}}}r+=8+a+4}return i?(this.nskdLbrLog("Certificate data extracted successfully from PNG","success"),i):(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(t){try{const e=/-*BEGIN NOSKID KEY-*\s*([a-f0-9]{64})/i,r=t.match(e);return r?r[1].toLowerCase():null}catch(e){return this.nskdLbrLog(`Error extracting verification key: ${e.message}`,"error"),null}}extractLocalData(t){try{const e=/-----BEGIN NOSKID KEY-----\s*([a-f0-9]+)\s*([A-Za-z0-9+/=]+)\s*([A-Za-z0-9+/=]+)\s*-----END NOSKID KEY-----/,r=t.match(e);if(!r)return null;const i=r[2],c=atob(i.replace(/=/g,"")).match(/CERT-\d+-(.+)/),l=c?c[1]:null,s=r[3],n=atob(s.replace(/=/g,"")).match(/CREATED-(.+)/),d=n?n[1]:null;return{username:l,creationDate:d}}catch(e){return this.nskdLbrLog(`Error extracting local data: ${e.message}`,"error"),null}}async verifyWithAPI(){try{this.nskdLbrLog("Verifying certificate with server...","info");const t=new AbortController,e=setTimeout(()=>t.abort(),this.timeout),r=await fetch(`${this.apiUrl}?key=${encodeURIComponent(this.verificationKey)}`,{signal:t.signal,headers:{"User-Agent":"NskdLbr/1.0.0"}});if(clearTimeout(e),!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);const i=await r.json();if(!i.success)return this.isValid=!1,this.nskdLbrLog(`Certificate verification failed: ${i.message}`,"error"),{valid:!1,message:i.message,cached:i.cached||!1};if(this.localData&&this.strictCheck){const a=this.compareData(this.localData,i.data);if(!a.valid)return this.isValid=!1,this.nskdLbrLog("Certificate data mismatch!","error"),this.nskdLbrLog(`Mismatch reason: ${a.reason}`,"error"),this.nskdLbrLog("Note: Strict checking is enabled. Set strictCheck to false to skip local data validation.","warning"),{valid:!1,message:`Data mismatch: ${a.reason}`,cached:i.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=i.data,this.nskdLbrLog("Certificate is VALID!","success"),{valid:!0,message:"Certificate verified successfully",data:i.data,cached:i.cached||!1,strictCheck:this.strictCheck}}catch(t){throw t.name==="AbortError"?new Error("Request timeout - server took too long to respond"):new Error(`API verification failed: ${t.message}`)}}compareData(t,e){if(!t||!e)return{valid:!1,reason:"Missing data for comparison"};if(t.username!==e.username)return{valid:!1,reason:`Username mismatch: Local=${t.username}, API=${e.username}`};const r=t.creationDate.substring(0,16),i=e.creationDate.substring(0,16);return r!==i?{valid:!1,reason:`Creation date mismatch: Local=${r}, API=${i}`}:{valid:!0}}}typeof module<"u"&&module.exports?module.exports=NskdLbr:window.NskdLbr=NskdLbr;
8
+ `.trim()}reset(){this.certificateData=null,this.verificationKey=null,this.localData=null,this.isValid=!1,this.nskdLbrLog("Certificate data reset","info")}readFileAsArrayBuffer(t){return new Promise((e,r)=>{const i=new FileReader;i.onload=a=>e(a.target.result),i.onerror=()=>r(new Error("Error reading file")),i.readAsArrayBuffer(t)})}async extractTextFromPng(t){try{const e=new Uint8Array(t);if(!(e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71))throw new Error("Not a valid PNG file");let r=8,i=null;for(;r<e.length-12;){const a=e[r]<<24|e[r+1]<<16|e[r+2]<<8|e[r+3];if(String.fromCharCode(e[r+4],e[r+5],e[r+6],e[r+7])==="tEXt"){const l=e.slice(r+8,r+8+a),s=new TextDecoder("utf-8").decode(l),o=s.indexOf("\0");if(o!==-1){const n=s.substring(0,o),d=s.substring(o+1);if(n==="noskid-key"){i=d;break}}}r+=8+a+4}return i?(this.nskdLbrLog("Certificate data extracted successfully from PNG","success"),i):(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(t){try{const e=/-*BEGIN NOSKID KEY-*\s*([a-f0-9]{64})/i,r=t.match(e);return r?r[1].toLowerCase():null}catch(e){return this.nskdLbrLog(`Error extracting verification key: ${e.message}`,"error"),null}}extractLocalData(t){try{const e=/-----BEGIN NOSKID KEY-----\s*([a-f0-9]+)\s*([A-Za-z0-9+/=]+)\s*([A-Za-z0-9+/=]+)\s*-----END NOSKID KEY-----/,r=t.match(e);if(!r)return null;const i=r[2],c=atob(i.replace(/=/g,"")).match(/CERT-\d+-(.+)/),l=c?c[1]:null,s=r[3],n=atob(s.replace(/=/g,"")).match(/CREATED-(.+)/),d=n?n[1]:null;return{username:l,creationDate:d}}catch(e){return this.nskdLbrLog(`Error extracting local data: ${e.message}`,"error"),null}}async verifyWithAPI(){try{this.nskdLbrLog("Verifying certificate with server...","info");const t=new AbortController,e=setTimeout(()=>t.abort(),this.timeout),r=await fetch(`${this.apiUrl}?key=${encodeURIComponent(this.verificationKey)}`,{signal:t.signal,headers:{"User-Agent":"NskdLbr/1.0.0"}});if(clearTimeout(e),!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);const i=await r.json();if(!i.success)return this.isValid=!1,this.nskdLbrLog(`Certificate verification failed: ${i.message}`,"error"),{valid:!1,message:i.message,cached:i.cached||!1};if(this.localData&&this.strictCheck){const a=this.compareData(this.localData,i.data);if(!a.valid)return this.isValid=!1,this.nskdLbrLog("Certificate data mismatch!","error"),this.nskdLbrLog(`Mismatch reason: ${a.reason}`,"error"),this.nskdLbrLog("Note: Strict checking is enabled. Set strictCheck to false to skip local data validation.","warning"),{valid:!1,message:`Data mismatch: ${a.reason}`,cached:i.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=i.data,this.nskdLbrLog("Certificate is VALID!","success"),{valid:!0,message:"Certificate verified successfully",data:i.data,cached:i.cached||!1,strictCheck:this.strictCheck}}catch(t){throw t.name==="AbortError"?new Error("Request timeout - server took too long to respond"):new Error(`API verification failed: ${t.message}`)}}compareData(t,e){if(!t||!e)return{valid:!1,reason:"Missing data for comparison"};if(t.username!==e.username)return{valid:!1,reason:`Username mismatch: Local=${t.username}, API=${e.username}`};const r=t.creationDate.substring(0,16),i=e.creationDate.substring(0,16);return r!==i?{valid:!1,reason:`Creation date mismatch: Local=${r}, API=${i}`}:{valid:!0}}}typeof module<"u"&&module.exports?module.exports=NskdLbr:window.NskdLbr=NskdLbr;