@rnaga/wp-node 1.2.3 → 1.2.6
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/common/password.d.ts.map +1 -1
- package/common/password.js +78 -8
- package/crud/error.d.ts +1 -2
- package/crud/error.d.ts.map +1 -1
- package/crud/error.js +3 -10
- package/package.json +4 -3
- package/validators/transactions/term.d.ts +2 -2
package/common/password.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/common/password.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/common/password.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,GAAI,WAAW,MAAM,WAG7C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,WAAW,MAAM,EAAE,YAAY,MAAM,YAGlE,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,SAAQ,MAAW,EACnB,eAAc,OAAc,EAC5B,oBAAmB,OAAe,KACjC,MAmBF,CAAC"}
|
package/common/password.js
CHANGED
|
@@ -32,9 +32,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.generatePassword = exports.checkPassword = exports.hashPassword = void 0;
|
|
37
40
|
const crypto = __importStar(require("crypto"));
|
|
41
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
38
42
|
const hashPassword = (plainText) => {
|
|
39
43
|
const passwordHash = new PasswordHash(8, true);
|
|
40
44
|
return passwordHash.hashPassword(plainText);
|
|
@@ -207,18 +211,84 @@ class PasswordHash {
|
|
|
207
211
|
}
|
|
208
212
|
return "*";
|
|
209
213
|
}
|
|
214
|
+
// https://github.com/WordPress/wordpress-develop/blob/063a74f93f0a89d1d92fac1f25c49a379ab3476b/src/wp-includes/pluggable.php#L2740
|
|
210
215
|
checkPassword(password, storedHash) {
|
|
216
|
+
// Passwords longer than 4096 characters are not supported
|
|
211
217
|
if (password.length > 4096) {
|
|
212
218
|
return false;
|
|
213
219
|
}
|
|
214
|
-
|
|
215
|
-
if (
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
220
|
+
// Check the hash using md5 regardless of the current hashing mechanism (legacy support)
|
|
221
|
+
if (storedHash.length <= 32) {
|
|
222
|
+
const md5Hash = crypto.createHash("md5").update(password).digest("hex");
|
|
223
|
+
return this.hashEquals(storedHash, md5Hash);
|
|
224
|
+
}
|
|
225
|
+
// Check the password using the current WordPress prefixed hash ($wp$ prefix)
|
|
226
|
+
if (storedHash.startsWith("$wp$")) {
|
|
227
|
+
try {
|
|
228
|
+
// WordPress 6.8+ uses SHA384 HMAC preprocessing before bcrypt
|
|
229
|
+
const passwordToVerify = crypto
|
|
230
|
+
.createHmac("sha384", "wp-sha384")
|
|
231
|
+
.update(password)
|
|
232
|
+
.digest("base64");
|
|
233
|
+
const bcryptHash = storedHash.substring(3); // Remove "$wp" prefix
|
|
234
|
+
return this.verifyPassword(passwordToVerify, bcryptHash);
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
console.error("Error verifying WordPress prefixed hash:", err);
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Check the password using phpass ($P$ prefix)
|
|
242
|
+
if (storedHash.startsWith("$P$")) {
|
|
243
|
+
let hash = this.cryptPrivate(password, storedHash);
|
|
244
|
+
if (hash[0] === "*") {
|
|
245
|
+
hash = crypto
|
|
246
|
+
.createHash("md5")
|
|
247
|
+
.update(password, "binary")
|
|
248
|
+
.digest("binary");
|
|
249
|
+
hash = this.cryptPrivate(password, storedHash);
|
|
250
|
+
}
|
|
251
|
+
return hash === storedHash;
|
|
252
|
+
}
|
|
253
|
+
// Check the password using compat support for any non-prefixed hash (bcrypt, Argon2, etc.)
|
|
254
|
+
try {
|
|
255
|
+
return this.verifyPassword(password, storedHash);
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
console.error("Error verifying non-prefixed hash:", err);
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Secure hash comparison to prevent timing attacks
|
|
264
|
+
*/
|
|
265
|
+
hashEquals(hash1, hash2) {
|
|
266
|
+
if (hash1.length !== hash2.length) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
let result = 0;
|
|
270
|
+
for (let i = 0; i < hash1.length; i++) {
|
|
271
|
+
result |= hash1.charCodeAt(i) ^ hash2.charCodeAt(i);
|
|
272
|
+
}
|
|
273
|
+
return result === 0;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Verify password using modern hashing algorithms (bcrypt, Argon2, etc.)
|
|
277
|
+
*/
|
|
278
|
+
verifyPassword(password, hash) {
|
|
279
|
+
try {
|
|
280
|
+
// Try bcrypt first (most common)
|
|
281
|
+
if (hash.match(/^\$2[axyb]\$/)) {
|
|
282
|
+
return bcryptjs_1.default.compareSync(password, hash);
|
|
283
|
+
}
|
|
284
|
+
// For other algorithms, we would need additional libraries
|
|
285
|
+
// For now, we'll just try bcrypt and return false for unsupported formats
|
|
286
|
+
console.warn(`Unsupported hash format: ${hash.substring(0, 10)}...`);
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
console.error("Error in password verification:", err);
|
|
291
|
+
return false;
|
|
221
292
|
}
|
|
222
|
-
return hash === storedHash;
|
|
223
293
|
}
|
|
224
294
|
}
|
package/crud/error.d.ts
CHANGED
|
@@ -13,8 +13,7 @@ export declare class StatusCodeMapper {
|
|
|
13
13
|
}
|
|
14
14
|
declare class CustomError extends Error {
|
|
15
15
|
statusCode: StatusCode;
|
|
16
|
-
|
|
17
|
-
constructor(message: string, statusMessage: StatusMessage, isOperational?: boolean, stack?: string);
|
|
16
|
+
constructor(message: string, statusMessage: StatusMessage);
|
|
18
17
|
}
|
|
19
18
|
export declare class CrudError extends CustomError {
|
|
20
19
|
constructor(statusMessage: StatusMessage | undefined, detail: string);
|
package/crud/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/crud/error.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE/C,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,SAAS,cAAc;IACvB,qBAAqB,0BAA0B;CAChD;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAKb;IAEX,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAMU;WAE3B,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,UAAU;WAI3C,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa;CAKhE;AAED,cAAM,WAAY,SAAQ,KAAK;IACtB,UAAU,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/crud/error.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE/C,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,SAAS,cAAc;IACvB,qBAAqB,0BAA0B;CAChD;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAKb;IAEX,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAMU;WAE3B,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,UAAU;WAI3C,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa;CAKhE;AAED,cAAM,WAAY,SAAQ,KAAK;IACtB,UAAU,EAAE,UAAU,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa;CAK1D;AAED,qBAAa,SAAU,SAAQ,WAAW;gBAEtC,aAAa,EAAE,aAAa,YAAsC,EAClE,MAAM,EAAE,MAAM;CAKjB"}
|
package/crud/error.js
CHANGED
|
@@ -29,22 +29,15 @@ class StatusCodeMapper {
|
|
|
29
29
|
exports.StatusCodeMapper = StatusCodeMapper;
|
|
30
30
|
class CustomError extends Error {
|
|
31
31
|
statusCode;
|
|
32
|
-
|
|
33
|
-
constructor(message, statusMessage, isOperational = true, stack = "") {
|
|
32
|
+
constructor(message, statusMessage) {
|
|
34
33
|
super(message);
|
|
35
34
|
this.statusCode = StatusCodeMapper.getCode(statusMessage);
|
|
36
|
-
this.
|
|
37
|
-
if (stack) {
|
|
38
|
-
this.stack = stack;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
Error.captureStackTrace(this, this.constructor);
|
|
42
|
-
}
|
|
35
|
+
Error.captureStackTrace(this, this.constructor);
|
|
43
36
|
}
|
|
44
37
|
}
|
|
45
38
|
class CrudError extends CustomError {
|
|
46
39
|
constructor(statusMessage = StatusMessage.INTERNAL_SERVER_ERROR, detail) {
|
|
47
|
-
super(`Error: ${detail}`, statusMessage
|
|
40
|
+
super(`Error: ${detail}`, statusMessage);
|
|
48
41
|
Object.setPrototypeOf(this, CrudError.prototype);
|
|
49
42
|
}
|
|
50
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rnaga/wp-node",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "rm -rf ./dist && tsc --project tsconfig.build.json && npm run copyfiles && cp package.json ./dist/",
|
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
"@types/node": "^22",
|
|
24
24
|
"copyfiles": "^2.4.1",
|
|
25
25
|
"ts-node": "^10.9.1",
|
|
26
|
-
"typescript": "^5.
|
|
26
|
+
"typescript": "^5.9",
|
|
27
27
|
"wordpress-hash-node": "^1.0.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"bcryptjs": "^
|
|
30
|
+
"@types/bcryptjs": "^2.4.6",
|
|
31
|
+
"bcryptjs": "^3.0.2",
|
|
31
32
|
"deep-object-diff": "^1.1.9",
|
|
32
33
|
"knex": "^3.1.0",
|
|
33
34
|
"moment-timezone": "^0.6.0",
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
export declare const termUpdate: import("zod").ZodObject<{
|
|
2
|
-
parent: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
3
2
|
taxonomy: import("zod").ZodDefault<import("zod").ZodString>;
|
|
4
3
|
name: import("zod").ZodString;
|
|
5
4
|
term_id: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
6
5
|
term_taxonomy_id: import("zod").ZodNumber;
|
|
7
6
|
description: import("zod").ZodDefault<import("zod").ZodString>;
|
|
7
|
+
parent: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
8
8
|
slug: import("zod").ZodPipe<import("zod").ZodString, import("zod").ZodTransform<string, string>>;
|
|
9
9
|
term_group: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
10
10
|
}, import("zod/v4/core").$strip>;
|
|
11
11
|
export declare const termInsert: import("zod").ZodObject<{
|
|
12
|
-
parent: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
13
12
|
taxonomy: import("zod").ZodDefault<import("zod").ZodString>;
|
|
14
13
|
name: import("zod").ZodString;
|
|
15
14
|
description: import("zod").ZodDefault<import("zod").ZodString>;
|
|
15
|
+
parent: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
16
16
|
slug: import("zod").ZodPipe<import("zod").ZodString, import("zod").ZodTransform<string, string>>;
|
|
17
17
|
term_group: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
18
18
|
}, import("zod/v4/core").$strip>;
|