@starklabs/backend-core 1.0.0 → 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 +477 -0
- package/dist/cjs/index.cjs +2 -1
- package/dist/cjs/utils/libsodium.cjs +13 -1
- package/dist/js/index.js +2 -1
- package/dist/js/utils/libsodium.js +13 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# @starklabs/backend-core
|
|
2
|
+
|
|
3
|
+
A comprehensive backend authentication library featuring MongoDB integration, JWT-based authentication, encryption/decryption using libsodium, and utilities for error handling and logging. Supports both ES modules and CommonJS.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **MongoDB Integration**: Seamless MongoDB connection management with Mongoose
|
|
8
|
+
- **JWT Authentication**: Sign and verify JWT tokens with configurable expiry
|
|
9
|
+
- **Encryption/Decryption**: Secure data encryption using libsodium (libsodium-wrappers-sumo)
|
|
10
|
+
- **Error Handling**: Custom AppError class for consistent error management
|
|
11
|
+
- **Structured Logging**: AppLog utility for emoji-tagged console logging
|
|
12
|
+
- **Async Handler**: Express middleware wrapper for async route handlers
|
|
13
|
+
- **Dual Module Support**: Works with both ES modules and CommonJS
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @starklabs/backend-core
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Environment Variables
|
|
22
|
+
|
|
23
|
+
The following environment variables are required:
|
|
24
|
+
|
|
25
|
+
```env
|
|
26
|
+
MONGO_URI=mongodb://localhost:27017
|
|
27
|
+
DB_NAME=your_database_name
|
|
28
|
+
MASTER_KEY=your_base64_encoded_32_byte_key
|
|
29
|
+
JWT_SECRET=your_jwt_secret_string
|
|
30
|
+
JWT_EXPIRY=1d
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Generating MASTER_KEY and JWT_SECRET
|
|
34
|
+
|
|
35
|
+
Generate both keys using the crypto utilities:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
import { crypto } from '@starklabs/backend-core';
|
|
39
|
+
|
|
40
|
+
// Generate 32-byte master key for encryption
|
|
41
|
+
const masterKey = await crypto.generateMasterKey();
|
|
42
|
+
console.log(masterKey); // Use this in .env as MASTER_KEY
|
|
43
|
+
|
|
44
|
+
// Generate 64-byte JWT secret for token signing
|
|
45
|
+
const jwtSecret = await crypto.generateJWTSecret();
|
|
46
|
+
console.log(jwtSecret); // Use this in .env as JWT_SECRET
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Store the generated values in your `.env` file:
|
|
50
|
+
|
|
51
|
+
```env
|
|
52
|
+
MASTER_KEY=eZkZDoy2s+DvGe44QGa7AdU41nKhglEaIjFsxfQCKao=
|
|
53
|
+
JWT_SECRET=your_generated_jwt_secret_base64_string
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
### ES Modules
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
import starkAuth, { crypto, AppError, AppLog, asyncHandler } from '@starklabs/backend-core';
|
|
62
|
+
|
|
63
|
+
// Initialize
|
|
64
|
+
const auth = await starkAuth.create({
|
|
65
|
+
MONGO_URI: process.env.MONGO_URI,
|
|
66
|
+
DB_NAME: process.env.DB_NAME,
|
|
67
|
+
MASTER_KEY: process.env.MASTER_KEY,
|
|
68
|
+
JWT_SECRET: process.env.JWT_SECRET,
|
|
69
|
+
JWT_EXPIRY: process.env.JWT_EXPIRY || '1d'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Sign JWT
|
|
73
|
+
const token = auth.signJWT({ userId: '123', email: 'user@example.com' });
|
|
74
|
+
|
|
75
|
+
// Verify JWT
|
|
76
|
+
const payload = auth.verifyJWT(token);
|
|
77
|
+
console.log(payload); // { userId: '123', email: 'user@example.com', iat: ..., exp: ... }
|
|
78
|
+
|
|
79
|
+
// Encrypt data
|
|
80
|
+
const encrypted = await auth.encrypt('sensitive data');
|
|
81
|
+
// Returns: { str, nonce, publicKey, securedPrivateKey }
|
|
82
|
+
|
|
83
|
+
// Decrypt data
|
|
84
|
+
const decrypted = await auth.decrypt(
|
|
85
|
+
encrypted.str,
|
|
86
|
+
encrypted.nonce,
|
|
87
|
+
encrypted.publicKey,
|
|
88
|
+
encrypted.securedPrivateKey
|
|
89
|
+
);
|
|
90
|
+
console.log(decrypted); // 'sensitive data'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### CommonJS
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
const starkAuth = require('@starklabs/backend-core');
|
|
97
|
+
|
|
98
|
+
// Initialize
|
|
99
|
+
const auth = await starkAuth.create({
|
|
100
|
+
MONGO_URI: process.env.MONGO_URI,
|
|
101
|
+
DB_NAME: process.env.DB_NAME,
|
|
102
|
+
MASTER_KEY: process.env.MASTER_KEY,
|
|
103
|
+
JWT_SECRET: process.env.JWT_SECRET,
|
|
104
|
+
JWT_EXPIRY: process.env.JWT_EXPIRY || '1d'
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Same API as ES modules
|
|
108
|
+
const token = auth.signJWT({ userId: '123' });
|
|
109
|
+
const payload = auth.verifyJWT(token);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## API Documentation
|
|
113
|
+
|
|
114
|
+
### StarkAuth Class
|
|
115
|
+
|
|
116
|
+
#### `static async create(config)`
|
|
117
|
+
|
|
118
|
+
Initializes database connection and returns a new StarkAuth instance.
|
|
119
|
+
|
|
120
|
+
**Parameters:**
|
|
121
|
+
- `config.MONGO_URI` (string): MongoDB connection URI
|
|
122
|
+
- `config.DB_NAME` (string): Database name
|
|
123
|
+
- `config.MASTER_KEY` (string): Base64-encoded 32-byte encryption key
|
|
124
|
+
- `config.JWT_SECRET` (string): Secret for JWT signing
|
|
125
|
+
- `config.JWT_EXPIRY` (string): JWT expiry time (e.g., "1d", "24h", "7d")
|
|
126
|
+
|
|
127
|
+
**Returns:** `Promise<StarkAuth>`
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
const auth = await starkAuth.create({
|
|
131
|
+
MONGO_URI: 'mongodb://localhost:27017',
|
|
132
|
+
DB_NAME: 'myapp',
|
|
133
|
+
MASTER_KEY: 'eZkZDoy2s+DvGe44QGa7AdU41nKhglEaIjFsxfQCKao=',
|
|
134
|
+
JWT_SECRET: 'your-secret-key',
|
|
135
|
+
JWT_EXPIRY: '7d'
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### `async encrypt(str)`
|
|
140
|
+
|
|
141
|
+
Encrypts a string using the master key.
|
|
142
|
+
|
|
143
|
+
**Parameters:**
|
|
144
|
+
- `str` (string): String to encrypt
|
|
145
|
+
|
|
146
|
+
**Returns:** `Promise<{ str, nonce, publicKey, securedPrivateKey }>`
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
const encrypted = await auth.encrypt('credit card number');
|
|
150
|
+
// Store all fields: str, nonce, publicKey, securedPrivateKey
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### `async decrypt(str, nonce, publicKey, securedPrivateKey)`
|
|
154
|
+
|
|
155
|
+
Decrypts an encrypted string.
|
|
156
|
+
|
|
157
|
+
**Parameters:**
|
|
158
|
+
- `str` (string): Encrypted data (base64)
|
|
159
|
+
- `nonce` (string): Nonce (base64)
|
|
160
|
+
- `publicKey` (string): Public key (base64)
|
|
161
|
+
- `securedPrivateKey` (string): Secured private key (base64)
|
|
162
|
+
|
|
163
|
+
**Returns:** `Promise<string>`
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
const original = await auth.decrypt(
|
|
167
|
+
encrypted.str,
|
|
168
|
+
encrypted.nonce,
|
|
169
|
+
encrypted.publicKey,
|
|
170
|
+
encrypted.securedPrivateKey
|
|
171
|
+
);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### `signJWT(payload)`
|
|
175
|
+
|
|
176
|
+
Signs a JWT token.
|
|
177
|
+
|
|
178
|
+
**Parameters:**
|
|
179
|
+
- `payload` (object): Data to encode in token
|
|
180
|
+
|
|
181
|
+
**Returns:** `string` (JWT token)
|
|
182
|
+
|
|
183
|
+
**Supported Expiry Values:**
|
|
184
|
+
- `"2m"`, `"10m"`, `"1h"`, `"6h"`, `"12h"`, `"1d"`, `"3d"`, `"7d"`, `"14d"`, `"30d"`
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
const token = auth.signJWT({
|
|
188
|
+
userId: '507f1f77bcf86cd799439011',
|
|
189
|
+
role: 'admin',
|
|
190
|
+
email: 'user@example.com'
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
#### `verifyJWT(token)`
|
|
195
|
+
|
|
196
|
+
Verifies and decodes a JWT token.
|
|
197
|
+
|
|
198
|
+
**Parameters:**
|
|
199
|
+
- `token` (string): JWT token to verify
|
|
200
|
+
|
|
201
|
+
**Returns:** `object` (decoded payload)
|
|
202
|
+
|
|
203
|
+
**Throws:** `AppError` if token is invalid or expired
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
try {
|
|
207
|
+
const payload = auth.verifyJWT(token);
|
|
208
|
+
console.log(payload.userId);
|
|
209
|
+
} catch (error) {
|
|
210
|
+
console.error('Invalid token:', error.message);
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Crypto Utilities
|
|
215
|
+
|
|
216
|
+
#### `crypto.generateMasterKey()`
|
|
217
|
+
|
|
218
|
+
Generates a secure 32-byte master key encoded in base64.
|
|
219
|
+
|
|
220
|
+
**Returns:** `Promise<string>`
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
const key = await crypto.generateMasterKey();
|
|
224
|
+
console.log(key); // "eZkZDoy2s+DvGe44QGa7AdU41nKhglEaIjFsxfQCKao="
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### `crypto.generateJWTSecret()`
|
|
228
|
+
|
|
229
|
+
Generates a secure 64-byte JWT secret encoded in base64.
|
|
230
|
+
|
|
231
|
+
**Returns:** `Promise<string>`
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
const secret = await crypto.generateJWTSecret();
|
|
235
|
+
console.log(secret); // "long_base64_encoded_string_suitable_for_jwt_signing"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### `crypto.hash(password)`
|
|
239
|
+
|
|
240
|
+
Hashes a password using argon2i algorithm.
|
|
241
|
+
|
|
242
|
+
**Parameters:**
|
|
243
|
+
- `password` (string): Password to hash
|
|
244
|
+
|
|
245
|
+
**Returns:** `Promise<string>` (salt + hash in base64)
|
|
246
|
+
|
|
247
|
+
```javascript
|
|
248
|
+
const hashedPassword = await crypto.hash('myPassword123');
|
|
249
|
+
// Store hashedPassword in database
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
#### `crypto.verifyHash(password, storedHash)`
|
|
253
|
+
|
|
254
|
+
Verifies a password against a stored hash.
|
|
255
|
+
|
|
256
|
+
**Parameters:**
|
|
257
|
+
- `password` (string): Password to verify
|
|
258
|
+
- `storedHash` (string): Hash from database
|
|
259
|
+
|
|
260
|
+
**Returns:** `Promise<boolean>`
|
|
261
|
+
|
|
262
|
+
```javascript
|
|
263
|
+
const isValid = await crypto.verifyHash('myPassword123', storedHash);
|
|
264
|
+
if (isValid) {
|
|
265
|
+
console.log('Password correct');
|
|
266
|
+
} else {
|
|
267
|
+
console.log('Password incorrect');
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Utility Exports
|
|
272
|
+
|
|
273
|
+
#### `AppError`
|
|
274
|
+
|
|
275
|
+
Custom error class for application errors.
|
|
276
|
+
|
|
277
|
+
```javascript
|
|
278
|
+
import { AppError } from '@starklabs/backend-core';
|
|
279
|
+
|
|
280
|
+
throw new AppError('User not found', 404);
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Constructor:** `new AppError(message, statusCode)`
|
|
284
|
+
|
|
285
|
+
#### `AppLog`
|
|
286
|
+
|
|
287
|
+
Structured logging utility with emoji tags.
|
|
288
|
+
|
|
289
|
+
```javascript
|
|
290
|
+
import { AppLog } from '@starklabs/backend-core';
|
|
291
|
+
|
|
292
|
+
AppLog('check', 'auth.js', 'User authenticated successfully');
|
|
293
|
+
// Output: ✅ [auth.js] User authenticated successfully
|
|
294
|
+
|
|
295
|
+
AppLog('X', 'auth.js', 'Authentication failed');
|
|
296
|
+
// Output: ❌ [auth.js] Authentication failed
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Parameters:** `AppLog(emoji, file, message)`
|
|
300
|
+
- `emoji` (string): `'check'` or `'X'`
|
|
301
|
+
- `file` (string): File name for context
|
|
302
|
+
- `message` (string): Log message
|
|
303
|
+
|
|
304
|
+
#### `asyncHandler`
|
|
305
|
+
|
|
306
|
+
Express middleware wrapper for handling async errors.
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
import { asyncHandler } from '@starklabs/backend-core';
|
|
310
|
+
import express from 'express';
|
|
311
|
+
|
|
312
|
+
const app = express();
|
|
313
|
+
|
|
314
|
+
app.post('/login', asyncHandler(async (req, res, next) => {
|
|
315
|
+
// Any thrown errors will be passed to next(error)
|
|
316
|
+
const user = await findUser(req.body.email);
|
|
317
|
+
res.json({ user });
|
|
318
|
+
}));
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Complete Example
|
|
322
|
+
|
|
323
|
+
### Express Server with Authentication
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
import express from 'express';
|
|
327
|
+
import starkAuth, { asyncHandler, AppLog, AppError } from '@starklabs/backend-core';
|
|
328
|
+
|
|
329
|
+
const app = express();
|
|
330
|
+
app.use(express.json());
|
|
331
|
+
|
|
332
|
+
let auth;
|
|
333
|
+
|
|
334
|
+
// Initialize auth middleware
|
|
335
|
+
app.use(async (req, res, next) => {
|
|
336
|
+
if (!auth) {
|
|
337
|
+
auth = await starkAuth.create({
|
|
338
|
+
MONGO_URI: process.env.MONGO_URI,
|
|
339
|
+
DB_NAME: process.env.DB_NAME,
|
|
340
|
+
MASTER_KEY: process.env.MASTER_KEY,
|
|
341
|
+
JWT_SECRET: process.env.JWT_SECRET,
|
|
342
|
+
JWT_EXPIRY: '7d'
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
req.auth = auth;
|
|
346
|
+
next();
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Login endpoint
|
|
350
|
+
app.post('/login', asyncHandler(async (req, res) => {
|
|
351
|
+
const { email, password } = req.body;
|
|
352
|
+
|
|
353
|
+
if (!email || !password) {
|
|
354
|
+
throw new AppError('Email and password required', 400);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Verify credentials (pseudo code)
|
|
358
|
+
const user = { id: '123', email };
|
|
359
|
+
|
|
360
|
+
const token = req.auth.signJWT({
|
|
361
|
+
userId: user.id,
|
|
362
|
+
email: user.email
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
AppLog('check', 'login', `User ${email} logged in`);
|
|
366
|
+
res.json({ token });
|
|
367
|
+
}));
|
|
368
|
+
|
|
369
|
+
// Protected endpoint with JWT verification
|
|
370
|
+
app.get('/profile', asyncHandler(async (req, res) => {
|
|
371
|
+
const token = req.headers.authorization?.split(' ')[1];
|
|
372
|
+
|
|
373
|
+
if (!token) {
|
|
374
|
+
throw new AppError('Token required', 401);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const payload = req.auth.verifyJWT(token);
|
|
378
|
+
res.json({ userId: payload.userId, email: payload.email });
|
|
379
|
+
}));
|
|
380
|
+
|
|
381
|
+
// Error handler
|
|
382
|
+
app.use((err, req, res, next) => {
|
|
383
|
+
const statusCode = err.statusCode || 500;
|
|
384
|
+
const message = err.message || 'Internal Server Error';
|
|
385
|
+
AppLog('X', 'server', message);
|
|
386
|
+
res.status(statusCode).json({ error: message });
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
app.listen(3000, () => {
|
|
390
|
+
AppLog('check', 'server', 'Server running on port 3000');
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Error Handling
|
|
395
|
+
|
|
396
|
+
All methods throw `AppError` on failure:
|
|
397
|
+
|
|
398
|
+
```javascript
|
|
399
|
+
import { AppError } from '@starklabs/backend-core';
|
|
400
|
+
|
|
401
|
+
try {
|
|
402
|
+
const payload = auth.verifyJWT(invalidToken);
|
|
403
|
+
} catch (error) {
|
|
404
|
+
if (error instanceof AppError) {
|
|
405
|
+
console.log(error.message); // "Invalid or expired token"
|
|
406
|
+
console.log(error.statusCode); // 401
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Testing
|
|
412
|
+
|
|
413
|
+
Run the test suite:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
npm test
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Tests verify:
|
|
420
|
+
- Instance creation and method existence
|
|
421
|
+
- JWT signing/verification
|
|
422
|
+
- Encryption/decryption
|
|
423
|
+
- Cross-module compatibility (ES ↔ CJS)
|
|
424
|
+
- Error handling
|
|
425
|
+
|
|
426
|
+
## Supported Environments
|
|
427
|
+
|
|
428
|
+
- **Node.js**: v14+
|
|
429
|
+
- **Module Systems**: ES Modules (`.mjs`, `"type": "module"`) and CommonJS (`.cjs`, `.js` with `"type": "commonjs"`)
|
|
430
|
+
- **Databases**: MongoDB 4.0+
|
|
431
|
+
|
|
432
|
+
## Dependencies
|
|
433
|
+
|
|
434
|
+
- `mongoose`: ^9.6.1 - MongoDB ODM
|
|
435
|
+
- `jsonwebtoken`: ^9.0.3 - JWT signing/verification
|
|
436
|
+
- `libsodium-wrappers-sumo`: ^0.8.4 - Encryption/hashing
|
|
437
|
+
- `dotenv`: ^17.4.2 - Environment variable management
|
|
438
|
+
- `express`: ^5.2.1 - Web framework (optional)
|
|
439
|
+
- `cors`: ^2.8.6 - CORS middleware (optional)
|
|
440
|
+
- `helmet`: ^8.1.0 - Security headers (optional)
|
|
441
|
+
|
|
442
|
+
## Security Considerations
|
|
443
|
+
|
|
444
|
+
1. **MASTER_KEY**: Generate a strong key using `crypto.generateMasterKey()` and store securely in `.env`
|
|
445
|
+
2. **JWT_SECRET**: Generate using `crypto.generateJWTSecret()` - this must be kept confidential and should never be shared or committed to version control
|
|
446
|
+
3. **Database**: Ensure MongoDB is protected with authentication and firewall rules
|
|
447
|
+
4. **HTTPS**: Always use HTTPS in production
|
|
448
|
+
5. **Token Storage**: Store JWT tokens securely (httpOnly cookies recommended, not localStorage)
|
|
449
|
+
6. **Key Rotation**: Consider rotating MASTER_KEY and JWT_SECRET periodically for enhanced security
|
|
450
|
+
|
|
451
|
+
## Common Issues
|
|
452
|
+
|
|
453
|
+
### "Invalid expiry key"
|
|
454
|
+
Ensure `JWT_EXPIRY` is one of the supported values: `"2m"`, `"10m"`, `"1h"`, `"6h"`, `"12h"`, `"1d"`, `"3d"`, `"7d"`, `"14d"`, `"30d"`
|
|
455
|
+
|
|
456
|
+
### "Error while connecting!"
|
|
457
|
+
Check that:
|
|
458
|
+
- MongoDB is running and accessible
|
|
459
|
+
- `MONGO_URI` is correct
|
|
460
|
+
- Network/firewall allows connection
|
|
461
|
+
|
|
462
|
+
### "Invalid or expired token"
|
|
463
|
+
- Token may have expired (check `JWT_EXPIRY`)
|
|
464
|
+
- `JWT_SECRET` may have changed
|
|
465
|
+
- Token may be malformed or tampered
|
|
466
|
+
|
|
467
|
+
## License
|
|
468
|
+
|
|
469
|
+
ISC
|
|
470
|
+
|
|
471
|
+
## Author
|
|
472
|
+
|
|
473
|
+
Musa (@starklabs)
|
|
474
|
+
|
|
475
|
+
## Contributing
|
|
476
|
+
|
|
477
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const connectDB = require("./db.cjs");
|
|
2
|
-
const { seal, unSeal, generateMasterKey, hash, verifyHash } = require("./utils/libsodium.cjs");
|
|
2
|
+
const { seal, unSeal, generateMasterKey, generateJWTSecret, hash, verifyHash } = require("./utils/libsodium.cjs");
|
|
3
3
|
const { signJWT, verifyJWT } = require("./utils/jwt.cjs");
|
|
4
4
|
|
|
5
5
|
const privateKeys = new WeakMap();
|
|
@@ -43,6 +43,7 @@ module.exports = StarkAuth;
|
|
|
43
43
|
|
|
44
44
|
const crypto = {
|
|
45
45
|
generateMasterKey,
|
|
46
|
+
generateJWTSecret,
|
|
46
47
|
hash,
|
|
47
48
|
verifyHash,
|
|
48
49
|
};
|
|
@@ -52,11 +52,22 @@ const generateMasterKey = async () => {
|
|
|
52
52
|
sodium.base64_variants.ORIGINAL
|
|
53
53
|
);
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
console.log(base64Key);
|
|
57
57
|
return base64Key
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
+
// generate JWT secret
|
|
61
|
+
const generateJWTSecret = async () => {
|
|
62
|
+
await sodium.ready;
|
|
63
|
+
|
|
64
|
+
const secret = sodium.randombytes_buf(64);
|
|
65
|
+
|
|
66
|
+
const base64Secret = sodium.to_base64(secret, sodium.base64_variants.ORIGINAL);
|
|
67
|
+
console.log(base64Secret);
|
|
68
|
+
return base64Secret;
|
|
69
|
+
};
|
|
70
|
+
|
|
60
71
|
// seal
|
|
61
72
|
const seal = async (string, masterKey) => {
|
|
62
73
|
try {
|
|
@@ -128,6 +139,7 @@ module.exports = {
|
|
|
128
139
|
hash,
|
|
129
140
|
verifyHash,
|
|
130
141
|
generateMasterKey,
|
|
142
|
+
generateJWTSecret,
|
|
131
143
|
seal,
|
|
132
144
|
unSeal,
|
|
133
145
|
};
|
package/dist/js/index.js
CHANGED
|
@@ -47,10 +47,11 @@ class StarkAuth {
|
|
|
47
47
|
export default StarkAuth;
|
|
48
48
|
|
|
49
49
|
// crypto - exports hashing utilities
|
|
50
|
-
import { generateMasterKey, hash, verifyHash } from "./utils/libsodium.js";
|
|
50
|
+
import { generateMasterKey, generateJWTSecret, hash, verifyHash } from "./utils/libsodium.js";
|
|
51
51
|
|
|
52
52
|
export const crypto = {
|
|
53
53
|
generateMasterKey,
|
|
54
|
+
generateJWTSecret,
|
|
54
55
|
hash,
|
|
55
56
|
verifyHash,
|
|
56
57
|
};
|
|
@@ -55,6 +55,19 @@ export const generateMasterKey = async () => {
|
|
|
55
55
|
return base64Key;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
// generate JWT secret
|
|
59
|
+
export const generateJWTSecret = async () => {
|
|
60
|
+
await sodium.ready;
|
|
61
|
+
|
|
62
|
+
// Generate a secure 64-byte random key for JWT
|
|
63
|
+
const secret = sodium.randombytes_buf(64);
|
|
64
|
+
|
|
65
|
+
// Convert to base64 for .env storage
|
|
66
|
+
const base64Secret = sodium.to_base64(secret, sodium.base64_variants.ORIGINAL);
|
|
67
|
+
console.log(base64Secret);
|
|
68
|
+
return base64Secret;
|
|
69
|
+
};
|
|
70
|
+
|
|
58
71
|
// seal
|
|
59
72
|
export const seal = async (string, masterKey) => {
|
|
60
73
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starklabs/backend-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A comprehensive backend authentication library featuring MongoDB integration, JWT-based authentication, encryption/decryption using libsodium, and utilities for error handling and logging. Supports both ES modules and CommonJS. Requires MONGO_URI, DB_NAME, MASTER_KEY, and JWT_SECRET environment variables.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"auth-mongo",
|