nskd-lbr 1.0.3 → 1.1.0

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/README.md CHANGED
@@ -1,21 +1,24 @@
1
1
  # NoSkid Certificate Library
2
2
 
3
- A JavaScript library for working with NoSkid certificates.
3
+ A modern JavaScript library for verifying NoSkid certificates and implementing certificate-based authentication.
4
4
 
5
5
  ## Table of Contents
6
6
 
7
7
  - [Installation](#installation)
8
- - [Usage](#usage)
9
- - [API Reference](#api-reference)
8
+ - [Quick Start](#quick-start)
9
+ - [Constructor Options](#constructor-options)
10
+ - [Methods](#methods)
11
+ - [Login with NoSkid](#login-with-noskid)
12
+ - [Response Objects](#response-objects)
10
13
  - [Examples](#examples)
11
- - [Configuration](#configuration)
12
14
  - [Error Handling](#error-handling)
15
+ - [Browser Support](#browser-support)
13
16
  - [Contributing](#contributing)
14
17
  - [License](#license)
15
18
 
16
19
  ## Installation
17
20
 
18
- ### Browser
21
+ ### Browser (CDN)
19
22
 
20
23
  ```html
21
24
  <script src="https://lbr.noskid.today"></script>
@@ -31,137 +34,462 @@ npm install nskd-lbr
31
34
  const NskdLbr = require('nskd-lbr');
32
35
  ```
33
36
 
34
- ## Usage
35
-
36
- ### Basic Usage
37
+ ## Quick Start
37
38
 
38
39
  ```js
39
40
  // Initialize the library
40
- const nskd = new NskdLbr();
41
+ const noskid = new NskdLbr(); //eventually specify parameters, well let the default ones here
41
42
 
42
- // Verify a certificate from a file
43
+ // Verify a certificate from file upload
43
44
  const fileInput = document.getElementById('certificate-file');
44
45
  fileInput.addEventListener('change', async (event) => {
45
46
  try {
46
- const result = await nskd.loadFromFile(event.target.files[0]);
47
+ const result = await noskid.loadFromFile(event.target.files[0]);
48
+ console.log('Verification result:', result);
49
+
47
50
  if (result.valid) {
48
- console.log('Certificate is valid!');
49
- console.log(nskd.getFormattedDetails());
50
- } else {
51
- console.log('Certificate is invalid:', result.message);
51
+ console.log(noskid.getFormattedDetails());
52
52
  }
53
53
  } catch (error) {
54
54
  console.error('Error:', error.message);
55
55
  }
56
56
  });
57
+ ```
57
58
 
58
- // Verify a certificate with a key
59
- const verificationKey = 'a1b2c3d4e5f6...'; // 64-character hex string
60
- nskd.verifyWithKey(verificationKey)
61
- .then(result => {
62
- if (result.valid) {
63
- console.log('Certificate is valid!');
64
- } else {
65
- console.log('Certificate is invalid:', result.message);
66
- }
67
- })
68
- .catch(error => {
69
- console.error('Error:', error.message);
70
- });
59
+ ## Constructor Options
60
+
61
+ ```js
62
+ const noskid = new NskdLbr({
63
+ // Core options
64
+ apiUrl: 'https://check.noskid.today/', // Verification API endpoint
65
+ debug: false, // Enable debug logging
66
+ timeout: 10000, // Request timeout (ms)
67
+ strictCheck: true, // Validate local vs API data
68
+ useLegacyAPI: false, // Use legacy API format
69
+
70
+ // Login feature options
71
+ loginEndpoint: '', // Login API endpoint
72
+ onLoginSuccess: null, // Success callback function
73
+ onLoginFail: null, // Failure callback function
74
+
75
+ // Logging
76
+ onLog: null // Custom logging function
77
+ });
71
78
  ```
72
79
 
73
- ## API Reference
80
+ ### Option Details
81
+
82
+ | Option | Type | Default | Description |
83
+ |--------|------|---------|-------------|
84
+ | `apiUrl` | `string` | `'https://check.noskid.today/'` | NoSkid verification API endpoint |
85
+ | `debug` | `boolean` | `false` | Enable console debug messages |
86
+ | `timeout` | `number` | `10000` | API request timeout in milliseconds |
87
+ | `strictCheck` | `boolean` | `true` | Compare local certificate data with API response |
88
+ | `useLegacyAPI` | `boolean` | `false` | Use legacy API format (affects username/nickname field) |
89
+ | `loginEndpoint` | `string` | `''` | Login API endpoint (required for login feature) |
90
+ | `onLoginSuccess` | `function` | `null` | `(result, certData) => {}` - Called on successful login |
91
+ | `onLoginFail` | `function` | `null` | `(error, certData) => {}` - Called on failed login |
92
+ | `onLog` | `function` | `null` | `(message, level) => {}` - Custom logging function |
93
+
94
+ ## Methods
95
+
96
+ ### Certificate Verification
97
+
98
+ #### `loadFromFile(file)`
99
+
100
+ Load and verify a certificate from a PNG file.'
74
101
 
75
- ### Constructor
102
+ **Parameters:**
103
+ - `file` (`File`) - PNG certificate file from file input
76
104
 
77
- ```javascript
78
- new NskdLbr(options)
105
+ **Returns:** `Promise<VerificationResult>`
106
+
107
+ **Example:**
108
+ ```js
109
+ const result = await noskid.loadFromFile(file);
110
+ // Returns: { valid: true, message: "Certificate verified successfully", data: {...}, cached: false }
79
111
  ```
80
112
 
81
- **Options:**
113
+ #### `verifyWithKey(key)`
82
114
 
83
- | Option | Type | Default | Description |
84
- | - | - | - | - |
85
- | `apiUrl` | string | `'https://check.noskid.today/'` | The API endpoint for certificate verification |
86
- | `debug` | boolean | `false` | Enable debug logging |
87
- | `timeout` | number | `10000` | Request timeout in milliseconds |
88
- | `strictCheck` | boolean | `true` | Validate local data against API response |
89
- | `useLegacyAPI` | boolean | `false` | Whether to use the legacy API format (nickname field or not) |
90
- | `onLog` | function | `null` | Custom logging function |
115
+ Verify a certificate using a verification key directly.
116
+
117
+ **Parameters:**
118
+ - `key` (`string`) - 64-character hexadecimal verification key
119
+
120
+ **Returns:** `Promise<VerificationResult>`
121
+
122
+ **Example:**
123
+ ```js
124
+ const result = await noskid.verifyWithKey('a1b2c3d4e5f6789...');
125
+ // Returns: { valid: true, message: "Certificate verified successfully", data: {...}, cached: false }
126
+ ```
127
+
128
+ ### Data Access
129
+
130
+ #### `getCertificateData()`
131
+
132
+ Get the current certificate data after successful verification.
133
+
134
+ **Returns:** `CertificateData | null`
135
+
136
+ **Example:**
137
+ ```js
138
+ const certData = noskid.getCertificateData();
139
+ // Returns: { certificate_number: "12345", username: "john_doe", percentage: 95, ... }
140
+ ```
141
+
142
+ #### `isValidCertificate()`
143
+
144
+ Check if the currently loaded certificate is valid.
145
+
146
+ **Returns:** `boolean`
147
+
148
+ #### `getFormattedDetails()`
149
+
150
+ Get a formatted string with certificate details.
151
+
152
+ **Returns:** `string`
153
+
154
+ **Example:**
155
+ ```js
156
+ const details = noskid.getFormattedDetails();
157
+ console.log(details);
158
+ // Output:
159
+ // Certificate Details:
160
+ // - Certificate #: 12345
161
+ // - Username: john_doe
162
+ // - Percentage: 95%
163
+ // - Creation Date: 2024-01-15 14:30:25
164
+ // - Country: United States (US)
165
+ ```
166
+
167
+ ### Utility Methods
168
+
169
+ #### `reset()`
170
+
171
+ Reset all certificate data and close any open login modals.
172
+
173
+ **Returns:** `void`
174
+
175
+ #### `nskdLbrLog(message, level)`
176
+
177
+ Log messages with different levels (when debug is enabled).
178
+
179
+ **Parameters:**
180
+ - `message` (`string`) - Message to log
181
+ - `level` (`string`) - Log level: `'info'`, `'error'`, `'warning'`, `'success'`
182
+
183
+ **Returns:** `void`
184
+
185
+ ## Login with NoSkid
186
+
187
+ The library provides a complete login system with a responsive modal interface.
188
+
189
+ If you want a clean login button, please use this one:
190
+ ![button](https://raw.githubusercontent.com/douxxtech/noskid.today/refs/heads/main/misc/nskd-lbr/src/login.svg)
191
+
192
+ ### `showLoginModal()`
193
+
194
+ Display a login modal for certificate-based authentication.
195
+
196
+ **Requirements:**
197
+ - Browser environment only
198
+ - `loginEndpoint` must be configured
199
+ - Valid login API endpoint that accepts POST requests
200
+
201
+ **Returns:** `Promise<LoginResult>`
202
+
203
+ **Example:**
204
+ ```js
205
+ const noskid = new NskdLbr({
206
+ loginEndpoint: 'https://your-api.com/login',
207
+ onLoginSuccess: (result, certData) => {
208
+ console.log('Welcome', certData.localUsername);
209
+ // Redirect user, update UI, etc.
210
+ },
211
+ onLoginFail: (error, certData) => {
212
+ console.error('Login failed:', error.message);
213
+ // Show error message, etc.
214
+ }
215
+ });
216
+
217
+ // Show login modal
218
+ try {
219
+ const loginResult = await noskid.showLoginModal();
220
+ console.log('Login successful:', loginResult);
221
+ } catch (error) {
222
+ console.log('Login cancelled:', error.message);
223
+ }
224
+ ```
225
+
226
+ ### Login API Format
227
+
228
+ Your login endpoint should accept POST requests with this format:
229
+
230
+ **Request:**
231
+ ```json
232
+ {
233
+ "certificate": {
234
+ "key": "a1b2c3d4e5f6789...",
235
+ "username": "john_doe",
236
+ "certificate_number": "12345",
237
+ "percentage": 95,
238
+ "country": "United States",
239
+ "countryCode": "US",
240
+ "creationDate": "2024-01-15 14:30:25"
241
+ },
242
+ "password": "user_password"
243
+ }
244
+ ```
245
+
246
+ **Response:**
247
+ ```json
248
+ {
249
+ "success": true,
250
+ "message": "Login successful",
251
+ "data": {
252
+ "token": "jwt_token_here",
253
+ "user": {...}
254
+ }
255
+ }
256
+ ```
91
257
 
92
- ### Methods
258
+ ## Response Objects
93
259
 
94
- | Method | Description | Returns |
95
- | - | - | - |
96
- | `loadFromFile(file)` | Load and verify a certificate from a PNG file | `Promise<Object>` Verification result |
97
- | `verifyWithKey(key)` | Verify a certificate using a verification key | `Promise<Object>` Verification result |
98
- | `getCertificateData()` | Get the current certificate data | `Object|null` Certificate data or null |
99
- | `isValidCertificate()` | Check if the certificate is valid | `boolean` |
100
- | `getFormattedDetails()` | Get formatted certificate details | `string` |
101
- | `reset()` | Reset the certificate data | `void` |
260
+ ### VerificationResult
102
261
 
103
- ### Logging
262
+ ```js
263
+ interface VerificationResult {
264
+ valid: boolean; // Whether certificate is valid
265
+ message: string; // Status message
266
+ data?: CertificateData; // Certificate data (if valid)
267
+ cached?: boolean; // Whether result was cached
268
+ strictCheck?: boolean; // Whether strict checking was used
269
+ }
270
+ ```
104
271
 
105
- The library provides a logging method that can be used to track the verification process:
272
+ ### CertificateData
106
273
 
107
274
  ```js
108
- nskd.nskdLbrLog(message, level);
275
+ interface CertificateData {
276
+ certificate_number: string; // Certificate number
277
+ username: string; // Username from API
278
+ nickname?: string; // Nickname (if not using legacy API)
279
+ percentage: number; // NoSkid percentage
280
+ country: string; // Country name
281
+ countryCode: string; // ISO country code
282
+ creationDate: string; // Certificate creation date
283
+ key: string; // Verification key
284
+ localUsername?: string; // Username from local certificate
285
+ localCreationDate?: string; // Creation date from local certificate
286
+ }
109
287
  ```
110
288
 
111
- **Levels:**
289
+ ### LoginResult
112
290
 
113
- - `info` (default)
114
- - `error`
115
- - `warning`
116
- - `success`
291
+ ```js
292
+ interface LoginResult {
293
+ success: boolean; // Whether login was successful
294
+ data: CertificateData; // Certificate data
295
+ response: any; // API response from login endpoint
296
+ }
297
+ ```
117
298
 
118
299
  ## Examples
119
300
 
120
- ### Custom Logging
301
+ ### Basic Certificate Verification
121
302
 
122
303
  ```js
123
- const nskd = new NskdLbr({
124
- onnskdLbrLog: (message, level) => {
125
- // Custom logging implementation
126
- console.log(`[Custom Log] [${level.toUpperCase()}] ${message}`);
304
+ const noskid = new NskdLbr({ debug: true });
305
+
306
+ // From file
307
+ document.getElementById('file-input').addEventListener('change', async (e) => {
308
+ try {
309
+ const result = await noskid.loadFromFile(e.target.files[0]);
310
+
311
+ if (result.valid) {
312
+ const certData = noskid.getCertificateData();
313
+ console.log(`Certificate #${certData.certificate_number} is valid!`);
314
+ console.log(`User: ${certData.username} (${certData.percentage}%)`);
315
+ } else {
316
+ console.log('Invalid certificate:', result.message);
317
+ }
318
+ } catch (error) {
319
+ console.error('Verification failed:', error.message);
127
320
  }
128
321
  });
322
+
323
+ // From verification key
324
+ const key = 'a1b2c3d4e5f6789abcdef...'; // 64-char hex string
325
+ try {
326
+ const result = await noskid.verifyWithKey(key);
327
+ console.log('Verification result:', result);
328
+ } catch (error) {
329
+ console.error('Error:', error.message);
330
+ }
129
331
  ```
130
332
 
131
- ### Disabling Strict Check
333
+ ### Complete Login Implementation
132
334
 
133
335
  ```js
134
- const nskd = new NskdLbr({
135
- strictCheck: false
336
+ const noskid = new NskdLbr({
337
+ debug: true,
338
+ loginEndpoint: 'https://api.yoursite.com/auth/noskid',
339
+ onLoginSuccess: (result, certData) => {
340
+ // Store authentication token
341
+ localStorage.setItem('auth_token', result.response.token);
342
+
343
+ // Update UI
344
+ document.getElementById('login-btn').style.display = 'none';
345
+ document.getElementById('user-info').textContent =
346
+ `Welcome, ${certData.localUsername}!`;
347
+
348
+ // Redirect or update application state
349
+ window.location.href = '/dashboard';
350
+ },
351
+ onLoginFail: (error, certData) => {
352
+ // Show error message
353
+ alert(`Login failed: ${error.message}`);
354
+
355
+ // Log for debugging
356
+ console.error('Login error:', error);
357
+ }
358
+ });
359
+
360
+ // Add login button event
361
+ document.getElementById('noskid-login-btn').addEventListener('click', async () => {
362
+ try {
363
+ await noskid.showLoginModal();
364
+ } catch (error) {
365
+ if (error.message !== 'Login cancelled') {
366
+ console.error('Login error:', error);
367
+ }
368
+ }
136
369
  });
137
370
  ```
138
371
 
139
- ## Configuration
372
+ ### Custom Configuration
373
+
374
+ ```js
375
+ const noskid = new NskdLbr({
376
+ apiUrl: 'https://custom-api.example.com/verify',
377
+ timeout: 15000,
378
+ strictCheck: false,
379
+ useLegacyAPI: true,
380
+ onLog: (message, level) => {
381
+ // Send logs to analytics service
382
+ analytics.track('noskid_log', { message, level });
383
+
384
+ // Custom console formatting
385
+ const timestamp = new Date().toISOString();
386
+ console.log(`[${timestamp}] [${level.toUpperCase()}] ${message}`);
387
+ }
388
+ });
389
+ ```
140
390
 
141
- The library can be configured with various options to suit your needs. The most important options are:
391
+ ### Handling Different Error Cases
142
392
 
143
- - `apiUrl`: The endpoint for the NoSkid verification API.
144
- - `debug`: Enable or disable debug logging.
145
- - `timeout`: Set the request timeout in milliseconds.
146
- - `strictCheck`: Enable or disable strict validation of local data against API response.
393
+ ```js
394
+ try {
395
+ const result = await noskid.loadFromFile(file);
396
+
397
+ if (result.valid) {
398
+ console.log('✅ Certificate is valid');
399
+ } else {
400
+ // Handle different failure reasons
401
+ if (result.strictCheck && result.message.includes('mismatch')) {
402
+ console.log('⚠️ Certificate data mismatch - try disabling strict check');
403
+ } else {
404
+ console.log('❌ Certificate verification failed:', result.message);
405
+ }
406
+ }
407
+ } catch (error) {
408
+ // Handle different error types
409
+ if (error.message.includes('timeout')) {
410
+ console.log('🕐 Request timed out - server may be slow');
411
+ } else if (error.message.includes('PNG')) {
412
+ console.log('📄 Invalid file format - please upload a PNG certificate');
413
+ } else if (error.message.includes('verification key')) {
414
+ console.log('🔑 Invalid verification key format');
415
+ } else {
416
+ console.log('💥 Unexpected error:', error.message);
417
+ }
418
+ }
419
+ ```
147
420
 
148
421
  ## Error Handling
149
422
 
150
- The library throws errors in case of issues during the verification process. It is recommended to wrap the library calls in try-catch blocks to handle these errors gracefully.
423
+ The library provides detailed error messages for different failure scenarios:
151
424
 
152
- ```javascript
425
+ ### Common Errors
426
+
427
+ | Error Type | Cause | Solution |
428
+ |------------|-------|----------|
429
+ | `"No file provided"` | File input is empty | Check file selection |
430
+ | `"File must be a PNG image"` | Wrong file format | Upload a PNG certificate |
431
+ | `"No valid verification key found"` | Certificate missing key | Check certificate validity |
432
+ | `"Request timeout"` | Network/server issues | Check connection, increase timeout |
433
+ | `"Data mismatch"` | Local vs API data differs | Disable `strictCheck` or verify certificate |
434
+ | `"Login endpoint is not configured"` | Missing login endpoint | Set `loginEndpoint` option |
435
+ | `"Login modal is only available in browser"` | Node.js environment | Use in browser only |
436
+
437
+ ### Best Practices
438
+
439
+ ```js
440
+ // Always wrap in try-catch
153
441
  try {
154
- const result = await nskd.loadFromFile(file);
155
- // Handle the result
442
+ const result = await noskid.loadFromFile(file);
443
+ // Handle result
156
444
  } catch (error) {
157
- console.error('Verification failed:', error.message);
445
+ // Handle error appropriately
446
+ console.error('Certificate verification failed:', error.message);
158
447
  }
448
+
449
+ // Check if certificate is loaded before accessing data
450
+ if (noskid.isValidCertificate()) {
451
+ const data = noskid.getCertificateData();
452
+ // Use certificate data
453
+ } else {
454
+ console.log('No valid certificate loaded');
455
+ }
456
+
457
+ // Reset state when needed
458
+ noskid.reset(); // Clears all data and closes modals
159
459
  ```
160
460
 
461
+ ## Browser Support
462
+
463
+ - **Modern Browsers**: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
464
+ - **Features Used**: Fetch API, Promises, File API, TextDecoder
465
+ - **Polyfills**: May require polyfills for older browsers
466
+
467
+ ### Required Browser APIs
468
+
469
+ - `fetch()` - for API requests
470
+ - `FileReader` - for reading certificate files
471
+ - `TextDecoder` - for PNG text extraction
472
+ - `AbortController` - for request timeouts
473
+
161
474
  ## Contributing
162
475
 
163
- Contributions are welcome! Please open an issue or submit a pull request on the GitHub repository.
476
+ Contributions are welcome! Please follow these guidelines:
477
+
478
+ 1. Fork the repository
479
+ 2. Create a feature branch
480
+ 3. Add tests for new functionality
481
+ 4. Ensure all tests pass
482
+ 5. Submit a pull request
164
483
 
165
484
  ## License
166
485
 
167
- This library is licensed under the NSDv1.0 License. See the LICENSE file for more information.
486
+ This library is licensed under the NSDv1.0 License. See the [LICENSE](LICENSE) file for details.
487
+
488
+ ---
489
+
490
+ **Need Help?**
491
+ - 🐛 Issues: [GitHub Issues](https://github.com/douxxtech/noskid.today/issues)
492
+
493
+ <a align="center" href="https://github.com/douxxtech" target="_blank">
494
+ <img src="https://madeby.douxx.tech"></img>
495
+ </a>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nskd-lbr",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "A JavaScript library for working with NoSkid certificates.",
5
5
  "main": "src/nskd-lbr.js",
6
6
  "scripts": {
package/src/login.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 60"><defs><linearGradient id="buttonGradient" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fcfaf5;stop-opacity:1"/><stop offset="100%" style="stop-color:#f0ede0;stop-opacity:1"/></linearGradient><pattern id="texturePattern" width="4" height="4" patternUnits="userSpaceOnUse"><rect width="4" height="4" fill="#f9f7f0"/><circle cx="2" cy="2" r="0.3" fill="#e8e5d8" opacity="0.3"/></pattern></defs><rect x="5" y="5" width="310" height="50" rx="8" ry="8" fill="url(#buttonGradient)" stroke="#8b4513" stroke-width="2"/><rect x="5" y="5" width="310" height="50" rx="8" ry="8" fill="url(#texturePattern)" opacity="0.4"/><rect x="8" y="8" width="304" height="44" rx="6" ry="6" fill="none" stroke="#8b4513" stroke-width="1" opacity="0.6"/><circle cx="25" cy="30" r="3" fill="#8b4513" opacity="0.7"/><circle cx="295" cy="30" r="3" fill="#8b4513" opacity="0.7"/><line x1="35" y1="30" x2="45" y2="30" stroke="#8b4513" stroke-width="1.5" opacity="0.5"/><line x1="275" y1="30" x2="285" y2="30" stroke="#8b4513" stroke-width="1.5" opacity="0.5"/><text x="160" y="35" fill="#8b4513" font-size="16" font-family="'Times New Roman', serif" font-weight="bold" text-anchor="middle">Login with NoSkid</text></svg>