@webbycrown/webbycommerce 1.1.2 → 1.2.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 +11 -2
- package/dist/_chunks/{Settings-D6uf1nI1.js → Settings-DZXAkI24.js} +131 -1
- package/dist/_chunks/{Settings-VM6V_KJt.mjs → Settings-yLx-YvVy.mjs} +131 -1
- package/dist/_chunks/{en-DIeqB4AB.js → en-CiQ97iC8.js} +15 -0
- package/dist/_chunks/{en-7gtFcumM.mjs → en-DE15m4xZ.mjs} +15 -0
- package/dist/_chunks/{index-BHqcM1qU.mjs → index-CXGrFKp6.mjs} +3 -3
- package/dist/_chunks/{index-RtBCA1lD.js → index-DgocXUgC.js} +3 -3
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +3246 -37
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -157,6 +157,38 @@ var require_routes = __commonJS({
|
|
|
157
157
|
auth: false
|
|
158
158
|
}
|
|
159
159
|
},
|
|
160
|
+
{
|
|
161
|
+
method: "GET",
|
|
162
|
+
path: "/auth/method",
|
|
163
|
+
handler: "auth.getAuthMethod",
|
|
164
|
+
config: {
|
|
165
|
+
auth: false,
|
|
166
|
+
policies: []
|
|
167
|
+
},
|
|
168
|
+
info: {
|
|
169
|
+
type: "content-api",
|
|
170
|
+
pluginName: PLUGIN_ID,
|
|
171
|
+
description: "Get current authentication method (default or otp)",
|
|
172
|
+
summary: "Get auth method",
|
|
173
|
+
tags: ["Authentication"]
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
method: "POST",
|
|
178
|
+
path: "/auth/unified",
|
|
179
|
+
handler: "auth.unifiedAuth",
|
|
180
|
+
config: {
|
|
181
|
+
auth: false,
|
|
182
|
+
policies: []
|
|
183
|
+
},
|
|
184
|
+
info: {
|
|
185
|
+
type: "content-api",
|
|
186
|
+
pluginName: PLUGIN_ID,
|
|
187
|
+
description: "Unified authentication endpoint supporting both OTP and default (email/password) methods",
|
|
188
|
+
summary: "Unified auth",
|
|
189
|
+
tags: ["Authentication"]
|
|
190
|
+
}
|
|
191
|
+
},
|
|
160
192
|
{
|
|
161
193
|
method: "GET",
|
|
162
194
|
path: "/auth/profile",
|
|
@@ -1242,7 +1274,8 @@ var require_register = __commonJS({
|
|
|
1242
1274
|
uid: shippingZoneUid,
|
|
1243
1275
|
modelType: "component",
|
|
1244
1276
|
modelName: "shipping-zone-location",
|
|
1245
|
-
globalId: "ComponentPluginWebbycommerceShippingZoneLocation"
|
|
1277
|
+
globalId: "ComponentPluginWebbycommerceShippingZoneLocation",
|
|
1278
|
+
category: shippingZoneSchema.category || "WebbyCommerce Shared"
|
|
1246
1279
|
});
|
|
1247
1280
|
strapi2.log.info(`[webbycommerce] Component registered: ${shippingZoneUid}`);
|
|
1248
1281
|
} else {
|
|
@@ -1257,7 +1290,8 @@ var require_register = __commonJS({
|
|
|
1257
1290
|
uid: contentBlockUid,
|
|
1258
1291
|
modelType: "component",
|
|
1259
1292
|
modelName: "content-block",
|
|
1260
|
-
globalId: "ComponentPluginWebbycommerceContentBlock"
|
|
1293
|
+
globalId: "ComponentPluginWebbycommerceContentBlock",
|
|
1294
|
+
category: contentBlockSchema.category || "WebbyCommerce Shared"
|
|
1261
1295
|
});
|
|
1262
1296
|
strapi2.log.info(`[webbycommerce] Component registered: ${contentBlockUid}`);
|
|
1263
1297
|
} else {
|
|
@@ -3157,6 +3191,8 @@ var require_content_types = __commonJS({
|
|
|
3157
3191
|
var require_bootstrap = __commonJS({
|
|
3158
3192
|
"server/src/bootstrap.js"(exports2, module2) {
|
|
3159
3193
|
"use strict";
|
|
3194
|
+
var fs = require("fs");
|
|
3195
|
+
var path = require("path");
|
|
3160
3196
|
var { registerEcommerceActions, ensureEcommercePermission } = require_check_ecommerce_permission();
|
|
3161
3197
|
var { extendUserSchemaWithOtpFields } = require_extend_user_schema();
|
|
3162
3198
|
module2.exports = async ({ strapi: strapi2 }) => {
|
|
@@ -3212,8 +3248,8 @@ var require_bootstrap = __commonJS({
|
|
|
3212
3248
|
return "webbycommerce";
|
|
3213
3249
|
}
|
|
3214
3250
|
};
|
|
3215
|
-
const isAdminRoute = (
|
|
3216
|
-
if (!
|
|
3251
|
+
const isAdminRoute = (path2) => {
|
|
3252
|
+
if (!path2) return false;
|
|
3217
3253
|
const adminRoutePatterns = [
|
|
3218
3254
|
"/admin/",
|
|
3219
3255
|
"/content-type-builder/",
|
|
@@ -3224,8 +3260,288 @@ var require_bootstrap = __commonJS({
|
|
|
3224
3260
|
"/documentation/",
|
|
3225
3261
|
"/graphql"
|
|
3226
3262
|
];
|
|
3227
|
-
return adminRoutePatterns.some((pattern) =>
|
|
3263
|
+
return adminRoutePatterns.some((pattern) => path2.startsWith(pattern));
|
|
3228
3264
|
};
|
|
3265
|
+
strapi2.server.use(async (ctx, next) => {
|
|
3266
|
+
if (ctx.path === "/content-type-builder/update-schema" && ctx.method === "POST") {
|
|
3267
|
+
try {
|
|
3268
|
+
let body = ctx.request.body;
|
|
3269
|
+
let bodyWasParsed = false;
|
|
3270
|
+
if (!body || typeof body === "object" && Object.keys(body).length === 0) {
|
|
3271
|
+
try {
|
|
3272
|
+
const contentType = ctx.request.header["content-type"] || "";
|
|
3273
|
+
if (contentType.includes("application/json") && ctx.req && typeof ctx.req[Symbol.asyncIterator] === "function") {
|
|
3274
|
+
const chunks = [];
|
|
3275
|
+
for await (const chunk of ctx.req) {
|
|
3276
|
+
chunks.push(chunk);
|
|
3277
|
+
}
|
|
3278
|
+
const rawBody = Buffer.concat(chunks).toString("utf8");
|
|
3279
|
+
if (rawBody && rawBody.trim()) {
|
|
3280
|
+
body = JSON.parse(rawBody);
|
|
3281
|
+
ctx.request.body = body;
|
|
3282
|
+
bodyWasParsed = true;
|
|
3283
|
+
const { Readable } = require("stream");
|
|
3284
|
+
ctx.req = Readable.from([Buffer.from(rawBody)]);
|
|
3285
|
+
strapi2.log.info("[webbycommerce] EARLY: Manually parsed request body");
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
} catch (parseError) {
|
|
3289
|
+
strapi2.log.warn("[webbycommerce] EARLY: Could not parse body:", parseError.message);
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
body = body || {};
|
|
3293
|
+
const data = body.data || body;
|
|
3294
|
+
const contentTypes3 = data.contentTypes || [];
|
|
3295
|
+
const components = data.components || [];
|
|
3296
|
+
strapi2.log.info("[webbycommerce] ===== EARLY: Processing content-type-builder update-schema request =====");
|
|
3297
|
+
strapi2.log.info("[webbycommerce] EARLY: Body type:", typeof body);
|
|
3298
|
+
strapi2.log.info("[webbycommerce] EARLY: Body keys:", Object.keys(body));
|
|
3299
|
+
strapi2.log.info("[webbycommerce] EARLY: Content types found:", contentTypes3.length);
|
|
3300
|
+
strapi2.log.info("[webbycommerce] EARLY: Components found:", components.length);
|
|
3301
|
+
let appDir;
|
|
3302
|
+
if (strapi2.dirs && strapi2.dirs.app && strapi2.dirs.app.root) {
|
|
3303
|
+
appDir = strapi2.dirs.app.root;
|
|
3304
|
+
} else if (strapi2.dirs && strapi2.dirs.root) {
|
|
3305
|
+
appDir = strapi2.dirs.root;
|
|
3306
|
+
} else {
|
|
3307
|
+
appDir = path.resolve(__dirname, "../..");
|
|
3308
|
+
}
|
|
3309
|
+
if (!strapi2.dirs) {
|
|
3310
|
+
strapi2.dirs = {};
|
|
3311
|
+
}
|
|
3312
|
+
if (!strapi2.dirs.app) {
|
|
3313
|
+
strapi2.dirs.app = {};
|
|
3314
|
+
}
|
|
3315
|
+
if (!strapi2.dirs.app.root) {
|
|
3316
|
+
strapi2.dirs.app.root = appDir;
|
|
3317
|
+
}
|
|
3318
|
+
for (const contentType of contentTypes3) {
|
|
3319
|
+
if (contentType.uid && contentType.uid.startsWith("api::")) {
|
|
3320
|
+
const uidParts = contentType.uid.split("::");
|
|
3321
|
+
if (uidParts.length === 2) {
|
|
3322
|
+
const apiAndType = uidParts[1].split(".");
|
|
3323
|
+
if (apiAndType.length >= 2) {
|
|
3324
|
+
const apiName = apiAndType[0];
|
|
3325
|
+
const contentTypeName = apiAndType[1];
|
|
3326
|
+
const apiDir = path.join(appDir, "src", "api", apiName);
|
|
3327
|
+
const contentTypeDir = path.join(apiDir, "content-types", contentTypeName);
|
|
3328
|
+
const schemaPath = path.join(contentTypeDir, "schema.json");
|
|
3329
|
+
fs.mkdirSync(contentTypeDir, { recursive: true });
|
|
3330
|
+
let existingSchema = {};
|
|
3331
|
+
if (fs.existsSync(schemaPath)) {
|
|
3332
|
+
try {
|
|
3333
|
+
existingSchema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
|
|
3334
|
+
} catch (e) {
|
|
3335
|
+
existingSchema = {};
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
const attributes = { ...existingSchema.attributes || {} };
|
|
3339
|
+
if (contentType.attributes && Array.isArray(contentType.attributes)) {
|
|
3340
|
+
for (const attr of contentType.attributes) {
|
|
3341
|
+
if (attr.name && attr.properties) {
|
|
3342
|
+
const attributeDef = { ...attr.properties };
|
|
3343
|
+
if (attributeDef.type === "component") {
|
|
3344
|
+
if (attributeDef.component) {
|
|
3345
|
+
strapi2.log.info(`[webbycommerce] EARLY: Processing component attribute: ${attr.name} -> ${attributeDef.component}`);
|
|
3346
|
+
}
|
|
3347
|
+
if (!attributeDef.repeatable) {
|
|
3348
|
+
attributeDef.repeatable = false;
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
if (attributeDef.type === "dynamiczone") {
|
|
3352
|
+
if (Array.isArray(attributeDef.components)) {
|
|
3353
|
+
strapi2.log.info(`[webbycommerce] EARLY: Processing dynamiczone: ${attr.name} with ${attributeDef.components.length} components`);
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
if (attributeDef.type === "relation") {
|
|
3357
|
+
if (attributeDef.target) {
|
|
3358
|
+
strapi2.log.info(`[webbycommerce] EARLY: Processing relation: ${attr.name} -> ${attributeDef.target}`);
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
attributes[attr.name] = attributeDef;
|
|
3362
|
+
const action = attr.action || "update";
|
|
3363
|
+
strapi2.log.info(`[webbycommerce] EARLY: ${action === "create" ? "Added" : "Updated"} attribute: ${attr.name} (type: ${attributeDef.type || "unknown"})`);
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
const schema = {
|
|
3368
|
+
kind: contentType.kind || existingSchema.kind || "collectionType",
|
|
3369
|
+
collectionName: contentType.collectionName || existingSchema.collectionName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
3370
|
+
info: {
|
|
3371
|
+
singularName: contentType.singularName || existingSchema.info?.singularName || contentTypeName,
|
|
3372
|
+
pluralName: contentType.pluralName || existingSchema.info?.pluralName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
3373
|
+
displayName: contentType.displayName || contentType.modelName || existingSchema.info?.displayName || contentTypeName,
|
|
3374
|
+
description: contentType.description || existingSchema.info?.description || ""
|
|
3375
|
+
},
|
|
3376
|
+
options: {
|
|
3377
|
+
draftAndPublish: contentType.draftAndPublish !== void 0 ? contentType.draftAndPublish : existingSchema.options?.draftAndPublish !== void 0 ? existingSchema.options.draftAndPublish : false
|
|
3378
|
+
},
|
|
3379
|
+
pluginOptions: contentType.pluginOptions || existingSchema.pluginOptions || {
|
|
3380
|
+
"content-manager": {
|
|
3381
|
+
visible: true
|
|
3382
|
+
},
|
|
3383
|
+
"content-api": {
|
|
3384
|
+
visible: true
|
|
3385
|
+
}
|
|
3386
|
+
},
|
|
3387
|
+
attributes
|
|
3388
|
+
};
|
|
3389
|
+
const schemaJson = JSON.stringify(schema, null, 2);
|
|
3390
|
+
fs.writeFileSync(schemaPath, schemaJson, "utf8");
|
|
3391
|
+
if (fs.existsSync(schemaPath)) {
|
|
3392
|
+
try {
|
|
3393
|
+
const verifySchema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
|
|
3394
|
+
const fileStats = fs.statSync(schemaPath);
|
|
3395
|
+
strapi2.log.info(`[webbycommerce] ========================================`);
|
|
3396
|
+
strapi2.log.info(`[webbycommerce] \u2713 COLLECTION SCHEMA CREATED/UPDATED`);
|
|
3397
|
+
strapi2.log.info(`[webbycommerce] ========================================`);
|
|
3398
|
+
strapi2.log.info(`[webbycommerce] \u2713 File: ${schemaPath}`);
|
|
3399
|
+
strapi2.log.info(`[webbycommerce] \u2713 File size: ${fileStats.size} bytes`);
|
|
3400
|
+
strapi2.log.info(`[webbycommerce] \u2713 Schema is valid JSON`);
|
|
3401
|
+
strapi2.log.info(`[webbycommerce] \u2713 Schema kind: ${verifySchema.kind}`);
|
|
3402
|
+
strapi2.log.info(`[webbycommerce] \u2713 Collection name: ${verifySchema.collectionName}`);
|
|
3403
|
+
strapi2.log.info(`[webbycommerce] \u2713 Display name: ${verifySchema.info?.displayName || "N/A"}`);
|
|
3404
|
+
strapi2.log.info(`[webbycommerce] \u2713 Total attributes: ${Object.keys(verifySchema.attributes || {}).length}`);
|
|
3405
|
+
const attrNames = Object.keys(verifySchema.attributes || {});
|
|
3406
|
+
if (attrNames.length > 0) {
|
|
3407
|
+
strapi2.log.info(`[webbycommerce] \u2713 Attributes list:`);
|
|
3408
|
+
attrNames.forEach((attrName) => {
|
|
3409
|
+
const attr = verifySchema.attributes[attrName];
|
|
3410
|
+
const attrType = attr.type || "unknown";
|
|
3411
|
+
const attrInfo = attrType === "component" ? `component: ${attr.component}` : attrType === "dynamiczone" ? `dynamiczone: ${(attr.components || []).join(", ")}` : attrType === "relation" ? `relation: ${attr.target}` : attrType;
|
|
3412
|
+
strapi2.log.info(`[webbycommerce] - ${attrName}: ${attrInfo}`);
|
|
3413
|
+
});
|
|
3414
|
+
} else {
|
|
3415
|
+
strapi2.log.warn(`[webbycommerce] \u26A0 No attributes found - this is a new empty collection`);
|
|
3416
|
+
}
|
|
3417
|
+
strapi2.log.info(`[webbycommerce] \u2713 File will trigger auto-restart`);
|
|
3418
|
+
strapi2.log.info(`[webbycommerce] \u2713 After restart, collection will be registered with all fields/components`);
|
|
3419
|
+
strapi2.log.info(`[webbycommerce] ========================================`);
|
|
3420
|
+
fs.chmodSync(schemaPath, 420);
|
|
3421
|
+
const now = /* @__PURE__ */ new Date();
|
|
3422
|
+
fs.utimesSync(schemaPath, now, now);
|
|
3423
|
+
ctx.state.schemaFileCreated = true;
|
|
3424
|
+
ctx.state.schemaPath = schemaPath;
|
|
3425
|
+
ctx.state.contentTypeUid = contentType.uid;
|
|
3426
|
+
} catch (verifyError) {
|
|
3427
|
+
strapi2.log.error(`[webbycommerce] \u2717 Schema file verification failed: ${verifyError.message}`);
|
|
3428
|
+
strapi2.log.error(`[webbycommerce] \u2717 Stack: ${verifyError.stack}`);
|
|
3429
|
+
}
|
|
3430
|
+
} else {
|
|
3431
|
+
strapi2.log.error(`[webbycommerce] \u2717 Schema file was not created: ${schemaPath}`);
|
|
3432
|
+
}
|
|
3433
|
+
const controllersDir = path.join(apiDir, "controllers", contentTypeName);
|
|
3434
|
+
const servicesDir = path.join(apiDir, "services", contentTypeName);
|
|
3435
|
+
const routesDir = path.join(apiDir, "routes", contentTypeName);
|
|
3436
|
+
[controllersDir, servicesDir, routesDir].forEach((dir) => {
|
|
3437
|
+
if (!fs.existsSync(dir)) {
|
|
3438
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
3439
|
+
strapi2.log.info(`[webbycommerce] EARLY: \u2713 Created directory: ${dir}`);
|
|
3440
|
+
}
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
if (ctx.state.schemaFileCreated && contentTypes3.length > 0) {
|
|
3447
|
+
strapi2.log.info(`[webbycommerce] EARLY: \u2713 Schema file(s) created successfully`);
|
|
3448
|
+
strapi2.log.info(`[webbycommerce] EARLY: \u2713 File watcher will detect change and trigger auto-restart`);
|
|
3449
|
+
strapi2.log.info(`[webbycommerce] EARLY: \u2713 After restart, collection will be automatically registered with all fields/components`);
|
|
3450
|
+
ctx.status = 200;
|
|
3451
|
+
ctx.body = {
|
|
3452
|
+
data: {
|
|
3453
|
+
contentTypes: contentTypes3.map((ct) => {
|
|
3454
|
+
const uidParts = ct.uid.split("::");
|
|
3455
|
+
const apiAndType = uidParts.length === 2 ? uidParts[1].split(".") : [];
|
|
3456
|
+
return {
|
|
3457
|
+
uid: ct.uid,
|
|
3458
|
+
apiID: ct.uid,
|
|
3459
|
+
schema: {
|
|
3460
|
+
kind: ct.kind || "collectionType",
|
|
3461
|
+
collectionName: ct.collectionName || (ct.kind === "singleType" ? apiAndType[1] : `${apiAndType[1]}s`),
|
|
3462
|
+
info: {
|
|
3463
|
+
singularName: ct.singularName || apiAndType[1],
|
|
3464
|
+
pluralName: ct.pluralName || (ct.kind === "singleType" ? apiAndType[1] : `${apiAndType[1]}s`),
|
|
3465
|
+
displayName: ct.displayName || ct.modelName || apiAndType[1],
|
|
3466
|
+
description: ct.description || ""
|
|
3467
|
+
},
|
|
3468
|
+
options: {
|
|
3469
|
+
draftAndPublish: ct.draftAndPublish !== void 0 ? ct.draftAndPublish : false
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
};
|
|
3473
|
+
}),
|
|
3474
|
+
components: (components || []).map((comp) => ({
|
|
3475
|
+
uid: comp.uid,
|
|
3476
|
+
category: comp.uid ? comp.uid.split(".")[0] : "",
|
|
3477
|
+
apiID: comp.uid
|
|
3478
|
+
}))
|
|
3479
|
+
}
|
|
3480
|
+
};
|
|
3481
|
+
strapi2.log.info(`[webbycommerce] EARLY: \u2713 Success response sent - request handled`);
|
|
3482
|
+
return;
|
|
3483
|
+
}
|
|
3484
|
+
} catch (error) {
|
|
3485
|
+
strapi2.log.error("[webbycommerce] EARLY: Error in content-type-builder fix:", error.message);
|
|
3486
|
+
strapi2.log.error("[webbycommerce] EARLY: Stack:", error.stack);
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
return next();
|
|
3490
|
+
});
|
|
3491
|
+
strapi2.server.use(async (ctx, next) => {
|
|
3492
|
+
if (ctx.path.includes("/content-manager/collection-types/") && (ctx.method === "POST" || ctx.method === "PUT") && ctx.request.body) {
|
|
3493
|
+
try {
|
|
3494
|
+
const match = ctx.path.match(/collection-types\/([^\/\?]+)/);
|
|
3495
|
+
const contentTypeUid = match?.[1];
|
|
3496
|
+
if (contentTypeUid && contentTypeUid.startsWith("api::")) {
|
|
3497
|
+
const contentType = strapi2.contentTypes[contentTypeUid];
|
|
3498
|
+
if (contentType && contentType.attributes) {
|
|
3499
|
+
const body = ctx.request.body;
|
|
3500
|
+
let modified = false;
|
|
3501
|
+
const sanitizeJsonValue = (value, fieldName) => {
|
|
3502
|
+
if (value === "" || value === '""') {
|
|
3503
|
+
return null;
|
|
3504
|
+
}
|
|
3505
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
3506
|
+
return null;
|
|
3507
|
+
}
|
|
3508
|
+
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
|
|
3509
|
+
try {
|
|
3510
|
+
return JSON.parse(value);
|
|
3511
|
+
} catch (e) {
|
|
3512
|
+
strapi2.log.warn(`[webbycommerce] Failed to parse JSON string for field "${fieldName}", using null`);
|
|
3513
|
+
return null;
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3516
|
+
return value;
|
|
3517
|
+
};
|
|
3518
|
+
for (const [fieldName, fieldValue] of Object.entries(body)) {
|
|
3519
|
+
if (fieldName === "id" || fieldName === "documentId" || fieldName.startsWith("_") || fieldName === "createdAt" || fieldName === "updatedAt" || fieldName === "publishedAt" || fieldName === "createdBy" || fieldName === "updatedBy") {
|
|
3520
|
+
continue;
|
|
3521
|
+
}
|
|
3522
|
+
const attribute = contentType.attributes[fieldName];
|
|
3523
|
+
if (attribute && attribute.type === "json") {
|
|
3524
|
+
const sanitizedValue = sanitizeJsonValue(fieldValue, fieldName);
|
|
3525
|
+
if (sanitizedValue !== fieldValue) {
|
|
3526
|
+
body[fieldName] = sanitizedValue;
|
|
3527
|
+
modified = true;
|
|
3528
|
+
strapi2.log.info(`[webbycommerce] Sanitized JSON field "${fieldName}": "${fieldValue}" -> ${sanitizedValue === null ? "null" : "parsed JSON"}`);
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
if (modified) {
|
|
3533
|
+
strapi2.log.info(`[webbycommerce] \u2713 Sanitized JSON fields in content-manager request for ${contentTypeUid}`);
|
|
3534
|
+
}
|
|
3535
|
+
} else {
|
|
3536
|
+
strapi2.log.debug(`[webbycommerce] Content type ${contentTypeUid} not found or has no attributes`);
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
} catch (error) {
|
|
3540
|
+
strapi2.log.warn(`[webbycommerce] Error sanitizing JSON fields:`, error.message);
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
return next();
|
|
3544
|
+
});
|
|
3229
3545
|
strapi2.server.use(async (ctx, next) => {
|
|
3230
3546
|
if (isAdminRoute(ctx.path)) {
|
|
3231
3547
|
return next();
|
|
@@ -3302,10 +3618,12 @@ var require_bootstrap = __commonJS({
|
|
|
3302
3618
|
const method = value.loginRegisterMethod || "default";
|
|
3303
3619
|
if (method === "otp") {
|
|
3304
3620
|
ctx.badRequest(
|
|
3305
|
-
"Authentication method is set to OTP. Please use the OTP login/register endpoints."
|
|
3621
|
+
"Authentication method is set to OTP. Please use the OTP login/register endpoints or the unified /auth/unified endpoint."
|
|
3306
3622
|
);
|
|
3307
3623
|
return;
|
|
3308
3624
|
}
|
|
3625
|
+
if (method === "both") {
|
|
3626
|
+
}
|
|
3309
3627
|
if (ctx.path === "/api/auth/local/register") {
|
|
3310
3628
|
return next();
|
|
3311
3629
|
}
|
|
@@ -3342,6 +3660,18 @@ var require_bootstrap = __commonJS({
|
|
|
3342
3660
|
"/webbycommerce/auth/verify-otp",
|
|
3343
3661
|
`/${routePrefix}/auth/verify-otp`
|
|
3344
3662
|
]);
|
|
3663
|
+
const methodPaths = /* @__PURE__ */ new Set([
|
|
3664
|
+
"/api/webbycommerce/auth/method",
|
|
3665
|
+
`/api/${routePrefix}/auth/method`,
|
|
3666
|
+
"/webbycommerce/auth/method",
|
|
3667
|
+
`/${routePrefix}/auth/method`
|
|
3668
|
+
]);
|
|
3669
|
+
const unifiedAuthPaths = /* @__PURE__ */ new Set([
|
|
3670
|
+
"/api/webbycommerce/auth/unified",
|
|
3671
|
+
`/api/${routePrefix}/auth/unified`,
|
|
3672
|
+
"/webbycommerce/auth/unified",
|
|
3673
|
+
`/${routePrefix}/auth/unified`
|
|
3674
|
+
]);
|
|
3345
3675
|
const profilePaths = /* @__PURE__ */ new Set([
|
|
3346
3676
|
"/api/webbycommerce/auth/profile",
|
|
3347
3677
|
`/api/${routePrefix}/auth/profile`,
|
|
@@ -3374,6 +3704,50 @@ var require_bootstrap = __commonJS({
|
|
|
3374
3704
|
return;
|
|
3375
3705
|
}
|
|
3376
3706
|
}
|
|
3707
|
+
if (ctx.method === "GET" && methodPaths.has(ctx.path)) {
|
|
3708
|
+
ctx.state.route = {
|
|
3709
|
+
info: {
|
|
3710
|
+
type: "content-api",
|
|
3711
|
+
pluginName: "webbycommerce"
|
|
3712
|
+
}
|
|
3713
|
+
};
|
|
3714
|
+
const authController = strapi2.plugin("webbycommerce").controller("auth");
|
|
3715
|
+
if (authController && typeof authController.getAuthMethod === "function") {
|
|
3716
|
+
await authController.getAuthMethod(ctx);
|
|
3717
|
+
return;
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
if (ctx.method === "POST" && unifiedAuthPaths.has(ctx.path)) {
|
|
3721
|
+
ctx.state.route = {
|
|
3722
|
+
info: {
|
|
3723
|
+
type: "content-api",
|
|
3724
|
+
pluginName: "webbycommerce"
|
|
3725
|
+
}
|
|
3726
|
+
};
|
|
3727
|
+
if (!ctx.request.body || typeof ctx.request.body === "object" && Object.keys(ctx.request.body || {}).length === 0) {
|
|
3728
|
+
try {
|
|
3729
|
+
const contentType = ctx.request.header["content-type"] || "";
|
|
3730
|
+
if (contentType.includes("application/json")) {
|
|
3731
|
+
const chunks = [];
|
|
3732
|
+
for await (const chunk of ctx.req) {
|
|
3733
|
+
chunks.push(chunk);
|
|
3734
|
+
}
|
|
3735
|
+
const rawBody = Buffer.concat(chunks).toString("utf8");
|
|
3736
|
+
if (rawBody && rawBody.trim()) {
|
|
3737
|
+
ctx.request.body = JSON.parse(rawBody);
|
|
3738
|
+
strapi2.log.debug(`[webbycommerce] Parsed request body for unified auth:`, ctx.request.body);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
} catch (error) {
|
|
3742
|
+
strapi2.log.error(`[webbycommerce] Failed to parse request body for unified auth:`, error.message);
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
const authController = strapi2.plugin("webbycommerce").controller("auth");
|
|
3746
|
+
if (authController && typeof authController.unifiedAuth === "function") {
|
|
3747
|
+
await authController.unifiedAuth(ctx);
|
|
3748
|
+
return;
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3377
3751
|
if ((ctx.method === "GET" || ctx.method === "PUT") && profilePaths.has(ctx.path)) {
|
|
3378
3752
|
ctx.state.route = {
|
|
3379
3753
|
info: {
|
|
@@ -4894,6 +5268,420 @@ var require_bootstrap = __commonJS({
|
|
|
4894
5268
|
}
|
|
4895
5269
|
return next();
|
|
4896
5270
|
});
|
|
5271
|
+
strapi2.server.use(async (ctx, next) => {
|
|
5272
|
+
if (ctx.path === "/content-type-builder/update-schema" && ctx.method === "POST") {
|
|
5273
|
+
try {
|
|
5274
|
+
let body = ctx.request.body;
|
|
5275
|
+
if (!body || typeof body === "object" && Object.keys(body).length === 0) {
|
|
5276
|
+
try {
|
|
5277
|
+
const contentType = ctx.request.header["content-type"] || "";
|
|
5278
|
+
if (contentType.includes("application/json")) {
|
|
5279
|
+
const chunks = [];
|
|
5280
|
+
const originalReq = ctx.req;
|
|
5281
|
+
for await (const chunk of originalReq) {
|
|
5282
|
+
chunks.push(chunk);
|
|
5283
|
+
}
|
|
5284
|
+
const rawBody = Buffer.concat(chunks).toString("utf8");
|
|
5285
|
+
if (rawBody && rawBody.trim()) {
|
|
5286
|
+
body = JSON.parse(rawBody);
|
|
5287
|
+
ctx.request.body = body;
|
|
5288
|
+
ctx.req = require("stream").Readable.from([Buffer.from(rawBody)]);
|
|
5289
|
+
}
|
|
5290
|
+
}
|
|
5291
|
+
} catch (parseError) {
|
|
5292
|
+
strapi2.log.warn("[webbycommerce] Could not parse request body:", parseError.message);
|
|
5293
|
+
}
|
|
5294
|
+
}
|
|
5295
|
+
body = body || {};
|
|
5296
|
+
const data = body.data || body;
|
|
5297
|
+
const contentTypes3 = data.contentTypes || [];
|
|
5298
|
+
const components = data.components || [];
|
|
5299
|
+
strapi2.log.info("[webbycommerce] ===== Processing content-type-builder update-schema request =====");
|
|
5300
|
+
strapi2.log.info("[webbycommerce] Request body keys:", Object.keys(body));
|
|
5301
|
+
strapi2.log.info("[webbycommerce] Data keys:", Object.keys(data));
|
|
5302
|
+
strapi2.log.info("[webbycommerce] Content types to process:", contentTypes3.length);
|
|
5303
|
+
strapi2.log.info("[webbycommerce] Components to process:", components.length);
|
|
5304
|
+
if (contentTypes3.length === 0 && components.length === 0) {
|
|
5305
|
+
strapi2.log.warn("[webbycommerce] No content types or components found in request body");
|
|
5306
|
+
strapi2.log.warn("[webbycommerce] Body type:", typeof body);
|
|
5307
|
+
strapi2.log.warn("[webbycommerce] Body stringified (first 500 chars):", JSON.stringify(body, null, 2).substring(0, 500));
|
|
5308
|
+
}
|
|
5309
|
+
let appDir;
|
|
5310
|
+
if (strapi2.dirs && strapi2.dirs.app && strapi2.dirs.app.root) {
|
|
5311
|
+
appDir = strapi2.dirs.app.root;
|
|
5312
|
+
strapi2.log.info("[webbycommerce] Using strapi.dirs.app.root:", appDir);
|
|
5313
|
+
} else if (strapi2.dirs && strapi2.dirs.root) {
|
|
5314
|
+
appDir = strapi2.dirs.root;
|
|
5315
|
+
strapi2.log.info("[webbycommerce] Using strapi.dirs.root:", appDir);
|
|
5316
|
+
} else {
|
|
5317
|
+
appDir = path.resolve(__dirname, "../..");
|
|
5318
|
+
strapi2.log.info("[webbycommerce] Using fallback appDir (from __dirname):", appDir);
|
|
5319
|
+
strapi2.log.info("[webbycommerce] __dirname is:", __dirname);
|
|
5320
|
+
}
|
|
5321
|
+
if (!strapi2.dirs) {
|
|
5322
|
+
strapi2.dirs = {};
|
|
5323
|
+
}
|
|
5324
|
+
if (!strapi2.dirs.app) {
|
|
5325
|
+
strapi2.dirs.app = {};
|
|
5326
|
+
}
|
|
5327
|
+
if (!strapi2.dirs.app.root) {
|
|
5328
|
+
strapi2.dirs.app.root = appDir;
|
|
5329
|
+
strapi2.log.info("[webbycommerce] Set strapi.dirs.app.root to:", appDir);
|
|
5330
|
+
}
|
|
5331
|
+
for (const component of components) {
|
|
5332
|
+
if (component.uid && component.uid.includes(".")) {
|
|
5333
|
+
const uidParts = component.uid.split(".");
|
|
5334
|
+
if (uidParts.length >= 2) {
|
|
5335
|
+
const category = uidParts[0];
|
|
5336
|
+
const componentName = uidParts[1];
|
|
5337
|
+
const componentsDir = path.join(appDir, "src", "components", category);
|
|
5338
|
+
const componentDir = path.join(componentsDir, componentName);
|
|
5339
|
+
if (!fs.existsSync(componentsDir)) {
|
|
5340
|
+
fs.mkdirSync(componentsDir, { recursive: true });
|
|
5341
|
+
strapi2.log.info(`[webbycommerce] Created component category directory: ${componentsDir}`);
|
|
5342
|
+
}
|
|
5343
|
+
if (!fs.existsSync(componentDir)) {
|
|
5344
|
+
fs.mkdirSync(componentDir, { recursive: true });
|
|
5345
|
+
strapi2.log.info(`[webbycommerce] Created component directory: ${componentDir}`);
|
|
5346
|
+
}
|
|
5347
|
+
const componentSchemaPath = path.join(componentDir, "schema.json");
|
|
5348
|
+
let componentSchema = {};
|
|
5349
|
+
if (fs.existsSync(componentSchemaPath)) {
|
|
5350
|
+
try {
|
|
5351
|
+
componentSchema = JSON.parse(fs.readFileSync(componentSchemaPath, "utf8"));
|
|
5352
|
+
} catch (error) {
|
|
5353
|
+
strapi2.log.warn(`[webbycommerce] Could not parse existing component schema: ${error.message}`);
|
|
5354
|
+
}
|
|
5355
|
+
}
|
|
5356
|
+
if (!componentSchema.info) {
|
|
5357
|
+
componentSchema.info = {};
|
|
5358
|
+
}
|
|
5359
|
+
if (!componentSchema.info.displayName) {
|
|
5360
|
+
componentSchema.info.displayName = component.displayName || component.modelName || componentName || "New Component";
|
|
5361
|
+
}
|
|
5362
|
+
if (!componentSchema.info.description) {
|
|
5363
|
+
componentSchema.info.description = component.description || "";
|
|
5364
|
+
}
|
|
5365
|
+
if (!componentSchema.category || componentSchema.category === "undefined" || componentSchema.category === "Undefined") {
|
|
5366
|
+
componentSchema.category = component.category || "WebbyCommerce Shared";
|
|
5367
|
+
}
|
|
5368
|
+
if (!componentSchema.collectionName) {
|
|
5369
|
+
componentSchema.collectionName = "components_" + component.uid.replace(/\./g, "_");
|
|
5370
|
+
}
|
|
5371
|
+
if (!componentSchema.options) {
|
|
5372
|
+
componentSchema.options = {};
|
|
5373
|
+
}
|
|
5374
|
+
if (!componentSchema.attributes) {
|
|
5375
|
+
componentSchema.attributes = {};
|
|
5376
|
+
}
|
|
5377
|
+
fs.writeFileSync(componentSchemaPath, JSON.stringify(componentSchema, null, 2));
|
|
5378
|
+
strapi2.log.info(`[webbycommerce] ${fs.existsSync(componentSchemaPath) ? "Updated" : "Created"} component schema file: ${componentSchemaPath}`);
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
}
|
|
5382
|
+
for (const contentType of contentTypes3) {
|
|
5383
|
+
if (contentType.uid && contentType.uid.startsWith("api::")) {
|
|
5384
|
+
const uidParts = contentType.uid.split("::");
|
|
5385
|
+
if (uidParts.length === 2) {
|
|
5386
|
+
const apiAndType = uidParts[1].split(".");
|
|
5387
|
+
if (apiAndType.length >= 2) {
|
|
5388
|
+
const apiName = apiAndType[0];
|
|
5389
|
+
const contentTypeName = apiAndType[1];
|
|
5390
|
+
const apiDir = path.join(appDir, "src", "api", apiName);
|
|
5391
|
+
const contentTypeDir = path.join(apiDir, "content-types", contentTypeName);
|
|
5392
|
+
strapi2.log.info(`[webbycommerce] Processing content type: ${contentType.uid}`);
|
|
5393
|
+
strapi2.log.info(`[webbycommerce] API Name: ${apiName}, Content Type Name: ${contentTypeName}`);
|
|
5394
|
+
strapi2.log.info(`[webbycommerce] App Directory: ${appDir}`);
|
|
5395
|
+
strapi2.log.info(`[webbycommerce] API Directory: ${apiDir}`);
|
|
5396
|
+
strapi2.log.info(`[webbycommerce] Content Type Directory: ${contentTypeDir}`);
|
|
5397
|
+
if (!fs.existsSync(apiDir)) {
|
|
5398
|
+
fs.mkdirSync(apiDir, { recursive: true });
|
|
5399
|
+
strapi2.log.info(`[webbycommerce] \u2713 Created API directory: ${apiDir}`);
|
|
5400
|
+
} else {
|
|
5401
|
+
strapi2.log.info(`[webbycommerce] \u2713 API directory already exists: ${apiDir}`);
|
|
5402
|
+
}
|
|
5403
|
+
if (!fs.existsSync(contentTypeDir)) {
|
|
5404
|
+
fs.mkdirSync(contentTypeDir, { recursive: true });
|
|
5405
|
+
strapi2.log.info(`[webbycommerce] \u2713 Created content type directory: ${contentTypeDir}`);
|
|
5406
|
+
} else {
|
|
5407
|
+
strapi2.log.info(`[webbycommerce] \u2713 Content type directory already exists: ${contentTypeDir}`);
|
|
5408
|
+
}
|
|
5409
|
+
const schemaPath = path.join(contentTypeDir, "schema.json");
|
|
5410
|
+
strapi2.log.info(`[webbycommerce] Schema path: ${schemaPath}`);
|
|
5411
|
+
let schemaNeedsUpdate = false;
|
|
5412
|
+
let currentSchema = {};
|
|
5413
|
+
if (fs.existsSync(schemaPath)) {
|
|
5414
|
+
try {
|
|
5415
|
+
currentSchema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
|
|
5416
|
+
if (!currentSchema || typeof currentSchema !== "object") {
|
|
5417
|
+
throw new Error("Invalid schema file");
|
|
5418
|
+
}
|
|
5419
|
+
strapi2.log.info(`[webbycommerce] \u2713 Schema file already exists and is valid`);
|
|
5420
|
+
const now = /* @__PURE__ */ new Date();
|
|
5421
|
+
fs.utimesSync(schemaPath, now, now);
|
|
5422
|
+
} catch (parseError) {
|
|
5423
|
+
strapi2.log.warn(`[webbycommerce] \u26A0 Schema file exists but is invalid, will be overwritten`);
|
|
5424
|
+
schemaNeedsUpdate = true;
|
|
5425
|
+
}
|
|
5426
|
+
} else {
|
|
5427
|
+
schemaNeedsUpdate = true;
|
|
5428
|
+
}
|
|
5429
|
+
if (schemaNeedsUpdate) {
|
|
5430
|
+
const minimalSchema = {
|
|
5431
|
+
kind: contentType.kind || "collectionType",
|
|
5432
|
+
collectionName: contentType.collectionName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
5433
|
+
info: {
|
|
5434
|
+
singularName: contentType.singularName || contentTypeName,
|
|
5435
|
+
pluralName: contentType.pluralName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
5436
|
+
displayName: contentType.displayName || contentType.modelName || contentTypeName,
|
|
5437
|
+
description: contentType.description || ""
|
|
5438
|
+
},
|
|
5439
|
+
options: {
|
|
5440
|
+
draftAndPublish: contentType.draftAndPublish !== void 0 ? contentType.draftAndPublish : false
|
|
5441
|
+
},
|
|
5442
|
+
attributes: {}
|
|
5443
|
+
};
|
|
5444
|
+
fs.writeFileSync(schemaPath, JSON.stringify(minimalSchema, null, 2));
|
|
5445
|
+
strapi2.log.info(`[webbycommerce] \u2713 Created/Updated schema file: ${schemaPath}`);
|
|
5446
|
+
strapi2.log.info(`[webbycommerce] \u2713 File watcher will detect change and trigger auto-restart`);
|
|
5447
|
+
}
|
|
5448
|
+
const controllersDir = path.join(apiDir, "controllers", contentTypeName);
|
|
5449
|
+
const servicesDir = path.join(apiDir, "services", contentTypeName);
|
|
5450
|
+
const routesDir = path.join(apiDir, "routes", contentTypeName);
|
|
5451
|
+
[controllersDir, servicesDir, routesDir].forEach((dir) => {
|
|
5452
|
+
if (!fs.existsSync(dir)) {
|
|
5453
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
5454
|
+
strapi2.log.info(`[webbycommerce] \u2713 Created directory: ${dir}`);
|
|
5455
|
+
}
|
|
5456
|
+
});
|
|
5457
|
+
if (!fs.existsSync(schemaPath)) {
|
|
5458
|
+
strapi2.log.error(`[webbycommerce] \u2717 CRITICAL: Schema path does not exist after creation attempt: ${schemaPath}`);
|
|
5459
|
+
} else {
|
|
5460
|
+
strapi2.log.info(`[webbycommerce] \u2713 Final verification: Schema path exists: ${schemaPath}`);
|
|
5461
|
+
}
|
|
5462
|
+
} else {
|
|
5463
|
+
strapi2.log.warn(`[webbycommerce] \u26A0 Could not parse UID parts for: ${contentType.uid}`);
|
|
5464
|
+
}
|
|
5465
|
+
} else {
|
|
5466
|
+
strapi2.log.warn(`[webbycommerce] \u26A0 Invalid UID format: ${contentType.uid}`);
|
|
5467
|
+
}
|
|
5468
|
+
} else {
|
|
5469
|
+
strapi2.log.warn(`[webbycommerce] \u26A0 Content type does not have UID or is not an API content type`);
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
strapi2.log.info("[webbycommerce] ===== Finished processing content-type-builder request =====");
|
|
5473
|
+
} catch (error) {
|
|
5474
|
+
strapi2.log.error("[webbycommerce] \u2717 Error ensuring API directory structure:", error.message);
|
|
5475
|
+
strapi2.log.error("[webbycommerce] Error stack:", error.stack);
|
|
5476
|
+
}
|
|
5477
|
+
}
|
|
5478
|
+
return next();
|
|
5479
|
+
});
|
|
5480
|
+
strapi2.server.use(async (ctx, next) => {
|
|
5481
|
+
try {
|
|
5482
|
+
await next();
|
|
5483
|
+
} catch (error) {
|
|
5484
|
+
if (ctx.path === "/content-type-builder/update-schema" && error.message && error.message.includes("path") && error.message.includes("undefined")) {
|
|
5485
|
+
strapi2.log.error("[webbycommerce] Caught path undefined error, attempting to fix...");
|
|
5486
|
+
try {
|
|
5487
|
+
const body = ctx.request.body || {};
|
|
5488
|
+
const data = body.data || body;
|
|
5489
|
+
const contentTypes3 = data.contentTypes || [];
|
|
5490
|
+
let appDir;
|
|
5491
|
+
if (strapi2.dirs && strapi2.dirs.app && strapi2.dirs.app.root) {
|
|
5492
|
+
appDir = strapi2.dirs.app.root;
|
|
5493
|
+
} else if (strapi2.dirs && strapi2.dirs.root) {
|
|
5494
|
+
appDir = strapi2.dirs.root;
|
|
5495
|
+
} else {
|
|
5496
|
+
appDir = path.resolve(__dirname, "../..");
|
|
5497
|
+
}
|
|
5498
|
+
for (const contentType of contentTypes3) {
|
|
5499
|
+
if (contentType.uid && contentType.uid.startsWith("api::")) {
|
|
5500
|
+
const uidParts = contentType.uid.split("::");
|
|
5501
|
+
if (uidParts.length === 2) {
|
|
5502
|
+
const apiAndType = uidParts[1].split(".");
|
|
5503
|
+
if (apiAndType.length >= 2) {
|
|
5504
|
+
const apiName = apiAndType[0];
|
|
5505
|
+
const contentTypeName = apiAndType[1];
|
|
5506
|
+
const apiDir = path.join(appDir, "src", "api", apiName);
|
|
5507
|
+
const contentTypeDir = path.join(apiDir, "content-types", contentTypeName);
|
|
5508
|
+
const schemaPath = path.join(contentTypeDir, "schema.json");
|
|
5509
|
+
if (!fs.existsSync(contentTypeDir)) {
|
|
5510
|
+
fs.mkdirSync(contentTypeDir, { recursive: true });
|
|
5511
|
+
strapi2.log.info(`[webbycommerce] Created content type directory: ${contentTypeDir}`);
|
|
5512
|
+
}
|
|
5513
|
+
if (!fs.existsSync(schemaPath)) {
|
|
5514
|
+
const minimalSchema = {
|
|
5515
|
+
kind: contentType.kind || "collectionType",
|
|
5516
|
+
collectionName: contentType.collectionName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
5517
|
+
info: {
|
|
5518
|
+
singularName: contentType.singularName || contentTypeName,
|
|
5519
|
+
pluralName: contentType.pluralName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
5520
|
+
displayName: contentType.displayName || contentType.modelName || contentTypeName,
|
|
5521
|
+
description: contentType.description || ""
|
|
5522
|
+
},
|
|
5523
|
+
options: {
|
|
5524
|
+
draftAndPublish: contentType.draftAndPublish !== void 0 ? contentType.draftAndPublish : false
|
|
5525
|
+
},
|
|
5526
|
+
attributes: {}
|
|
5527
|
+
};
|
|
5528
|
+
fs.writeFileSync(schemaPath, JSON.stringify(minimalSchema, null, 2));
|
|
5529
|
+
strapi2.log.info(`[webbycommerce] Created schema file: ${schemaPath}`);
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5532
|
+
}
|
|
5533
|
+
}
|
|
5534
|
+
}
|
|
5535
|
+
strapi2.log.info("[webbycommerce] Retrying content-type-builder request after fixing directories...");
|
|
5536
|
+
} catch (fixError) {
|
|
5537
|
+
strapi2.log.error("[webbycommerce] Failed to fix path error:", fixError.message);
|
|
5538
|
+
}
|
|
5539
|
+
}
|
|
5540
|
+
throw error;
|
|
5541
|
+
}
|
|
5542
|
+
});
|
|
5543
|
+
try {
|
|
5544
|
+
const contentTypeBuilderPlugin = strapi2.plugin("content-type-builder");
|
|
5545
|
+
if (contentTypeBuilderPlugin) {
|
|
5546
|
+
const ctbController = contentTypeBuilderPlugin.controller("content-types");
|
|
5547
|
+
if (ctbController && typeof ctbController.updateSchema === "function") {
|
|
5548
|
+
const originalUpdateSchema = ctbController.updateSchema;
|
|
5549
|
+
ctbController.updateSchema = async function(ctx) {
|
|
5550
|
+
try {
|
|
5551
|
+
return await originalUpdateSchema.call(this, ctx);
|
|
5552
|
+
} catch (error) {
|
|
5553
|
+
if (error.message && error.message.includes("path") && error.message.includes("undefined")) {
|
|
5554
|
+
strapi2.log.error("[webbycommerce] CONTROLLER: Caught path undefined error in updateSchema");
|
|
5555
|
+
const body = ctx.request.body || {};
|
|
5556
|
+
const data = body.data || body;
|
|
5557
|
+
const contentTypes3 = data.contentTypes || [];
|
|
5558
|
+
let appDir = strapi2.dirs?.app?.root || path.resolve(__dirname, "../..");
|
|
5559
|
+
for (const contentType of contentTypes3) {
|
|
5560
|
+
if (contentType.uid && contentType.uid.startsWith("api::")) {
|
|
5561
|
+
const uidParts = contentType.uid.split("::");
|
|
5562
|
+
if (uidParts.length === 2) {
|
|
5563
|
+
const apiAndType = uidParts[1].split(".");
|
|
5564
|
+
if (apiAndType.length >= 2) {
|
|
5565
|
+
const apiName = apiAndType[0];
|
|
5566
|
+
const contentTypeName = apiAndType[1];
|
|
5567
|
+
const contentTypeDir = path.join(appDir, "src", "api", apiName, "content-types", contentTypeName);
|
|
5568
|
+
const schemaPath = path.join(contentTypeDir, "schema.json");
|
|
5569
|
+
fs.mkdirSync(contentTypeDir, { recursive: true });
|
|
5570
|
+
if (!fs.existsSync(schemaPath)) {
|
|
5571
|
+
const minimalSchema = {
|
|
5572
|
+
kind: contentType.kind || "collectionType",
|
|
5573
|
+
collectionName: contentType.collectionName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
5574
|
+
info: {
|
|
5575
|
+
singularName: contentType.singularName || contentTypeName,
|
|
5576
|
+
pluralName: contentType.pluralName || (contentType.kind === "singleType" ? contentTypeName : `${contentTypeName}s`),
|
|
5577
|
+
displayName: contentType.displayName || contentType.modelName || contentTypeName
|
|
5578
|
+
},
|
|
5579
|
+
options: {
|
|
5580
|
+
draftAndPublish: contentType.draftAndPublish !== void 0 ? contentType.draftAndPublish : false
|
|
5581
|
+
},
|
|
5582
|
+
attributes: {}
|
|
5583
|
+
};
|
|
5584
|
+
fs.writeFileSync(schemaPath, JSON.stringify(minimalSchema, null, 2));
|
|
5585
|
+
}
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5588
|
+
}
|
|
5589
|
+
}
|
|
5590
|
+
strapi2.log.info("[webbycommerce] CONTROLLER: Retrying updateSchema after fixing paths");
|
|
5591
|
+
return await originalUpdateSchema.call(this, ctx);
|
|
5592
|
+
}
|
|
5593
|
+
throw error;
|
|
5594
|
+
}
|
|
5595
|
+
};
|
|
5596
|
+
strapi2.log.info("[webbycommerce] Patched content-type-builder updateSchema controller");
|
|
5597
|
+
}
|
|
5598
|
+
const ctbService = contentTypeBuilderPlugin.service("builder");
|
|
5599
|
+
if (ctbService) {
|
|
5600
|
+
if (ctbService.writeContentTypeSchema && typeof ctbService.writeContentTypeSchema === "function") {
|
|
5601
|
+
const originalWriteContentTypeSchema = ctbService.writeContentTypeSchema;
|
|
5602
|
+
ctbService.writeContentTypeSchema = function(uid, schema) {
|
|
5603
|
+
try {
|
|
5604
|
+
return originalWriteContentTypeSchema.call(this, uid, schema);
|
|
5605
|
+
} catch (error) {
|
|
5606
|
+
if (error.message && error.message.includes("path") && error.message.includes("undefined")) {
|
|
5607
|
+
strapi2.log.error("[webbycommerce] SERVICE: Caught path undefined error in writeContentTypeSchema");
|
|
5608
|
+
if (uid && uid.startsWith("api::")) {
|
|
5609
|
+
const uidParts = uid.split("::");
|
|
5610
|
+
if (uidParts.length === 2) {
|
|
5611
|
+
const apiAndType = uidParts[1].split(".");
|
|
5612
|
+
if (apiAndType.length >= 2) {
|
|
5613
|
+
const apiName = apiAndType[0];
|
|
5614
|
+
const contentTypeName = apiAndType[1];
|
|
5615
|
+
const appDir = strapi2.dirs?.app?.root || path.resolve(__dirname, "../..");
|
|
5616
|
+
const contentTypeDir = path.join(appDir, "src", "api", apiName, "content-types", contentTypeName);
|
|
5617
|
+
const schemaPath = path.join(contentTypeDir, "schema.json");
|
|
5618
|
+
fs.mkdirSync(contentTypeDir, { recursive: true });
|
|
5619
|
+
if (!fs.existsSync(schemaPath)) {
|
|
5620
|
+
fs.writeFileSync(schemaPath, JSON.stringify(schema || {}, null, 2));
|
|
5621
|
+
}
|
|
5622
|
+
return originalWriteContentTypeSchema.call(this, uid, schema);
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
}
|
|
5627
|
+
throw error;
|
|
5628
|
+
}
|
|
5629
|
+
};
|
|
5630
|
+
strapi2.log.info("[webbycommerce] Patched content-type-builder writeContentTypeSchema service");
|
|
5631
|
+
}
|
|
5632
|
+
}
|
|
5633
|
+
}
|
|
5634
|
+
} catch (patchError) {
|
|
5635
|
+
strapi2.log.warn("[webbycommerce] Could not patch content-type-builder:", patchError.message);
|
|
5636
|
+
strapi2.log.warn("[webbycommerce] Patch error stack:", patchError.stack);
|
|
5637
|
+
}
|
|
5638
|
+
const originalWriteFileSync = fs.writeFileSync;
|
|
5639
|
+
fs.writeFileSync = function(filePath, data, options) {
|
|
5640
|
+
if (filePath === void 0 || filePath === null) {
|
|
5641
|
+
const error = new Error('The "path" argument must be of type string. Received undefined');
|
|
5642
|
+
strapi2.log.error("[webbycommerce] FS PATCH: Caught undefined path in writeFileSync");
|
|
5643
|
+
strapi2.log.error("[webbycommerce] FS PATCH: Stack trace:", new Error().stack);
|
|
5644
|
+
throw error;
|
|
5645
|
+
}
|
|
5646
|
+
if (typeof filePath === "string" && !path.isAbsolute(filePath)) {
|
|
5647
|
+
const appDir = strapi2.dirs?.app?.root || path.resolve(__dirname, "../..");
|
|
5648
|
+
const absolutePath = path.resolve(appDir, filePath);
|
|
5649
|
+
if (absolutePath.includes("content-types") && absolutePath.endsWith("schema.json")) {
|
|
5650
|
+
const dir = path.dirname(absolutePath);
|
|
5651
|
+
if (!fs.existsSync(dir)) {
|
|
5652
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
5653
|
+
strapi2.log.info(`[webbycommerce] FS PATCH: Created directory for relative path: ${dir}`);
|
|
5654
|
+
}
|
|
5655
|
+
filePath = absolutePath;
|
|
5656
|
+
}
|
|
5657
|
+
}
|
|
5658
|
+
return originalWriteFileSync.call(this, filePath, data, options);
|
|
5659
|
+
};
|
|
5660
|
+
const originalWriteFile = fs.writeFile;
|
|
5661
|
+
fs.writeFile = function(filePath, data, options, callback) {
|
|
5662
|
+
if (filePath === void 0 || filePath === null) {
|
|
5663
|
+
const error = new Error('The "path" argument must be of type string. Received undefined');
|
|
5664
|
+
strapi2.log.error("[webbycommerce] FS PATCH: Caught undefined path in writeFile");
|
|
5665
|
+
if (callback && typeof callback === "function") {
|
|
5666
|
+
return callback(error);
|
|
5667
|
+
}
|
|
5668
|
+
throw error;
|
|
5669
|
+
}
|
|
5670
|
+
if (typeof filePath === "string" && !path.isAbsolute(filePath)) {
|
|
5671
|
+
const appDir = strapi2.dirs?.app?.root || path.resolve(__dirname, "../..");
|
|
5672
|
+
const absolutePath = path.resolve(appDir, filePath);
|
|
5673
|
+
if (absolutePath.includes("content-types") && absolutePath.endsWith("schema.json")) {
|
|
5674
|
+
const dir = path.dirname(absolutePath);
|
|
5675
|
+
if (!fs.existsSync(dir)) {
|
|
5676
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
5677
|
+
strapi2.log.info(`[webbycommerce] FS PATCH: Created directory for relative path: ${dir}`);
|
|
5678
|
+
}
|
|
5679
|
+
filePath = absolutePath;
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
return originalWriteFile.call(this, filePath, data, options, callback);
|
|
5683
|
+
};
|
|
5684
|
+
strapi2.log.info("[webbycommerce] Patched fs.writeFileSync and fs.writeFile to catch undefined paths");
|
|
4897
5685
|
let retryCount = 0;
|
|
4898
5686
|
const maxRetries = 3;
|
|
4899
5687
|
const retryDelay = 1e3;
|
|
@@ -4916,10 +5704,59 @@ var require_bootstrap = __commonJS({
|
|
|
4916
5704
|
}
|
|
4917
5705
|
};
|
|
4918
5706
|
await registerWithRetry();
|
|
5707
|
+
strapi2.db.lifecycles.subscribe({
|
|
5708
|
+
models: ["*"],
|
|
5709
|
+
// Listen to all models
|
|
5710
|
+
async afterCreate(event) {
|
|
5711
|
+
}
|
|
5712
|
+
});
|
|
5713
|
+
strapi2.server.use(async (ctx, next) => {
|
|
5714
|
+
if (ctx.path === "/content-type-builder/update-schema" && ctx.method === "POST") {
|
|
5715
|
+
await next();
|
|
5716
|
+
if (ctx.status === 200 || ctx.status === 201) {
|
|
5717
|
+
const body = ctx.request.body || {};
|
|
5718
|
+
const data = body.data || body;
|
|
5719
|
+
const contentTypes3 = data.contentTypes || [];
|
|
5720
|
+
for (const contentType of contentTypes3) {
|
|
5721
|
+
if (contentType.uid && contentType.uid.startsWith("api::")) {
|
|
5722
|
+
const uidParts = contentType.uid.split("::");
|
|
5723
|
+
if (uidParts.length === 2) {
|
|
5724
|
+
const apiAndType = uidParts[1].split(".");
|
|
5725
|
+
if (apiAndType.length >= 2) {
|
|
5726
|
+
const apiName = apiAndType[0];
|
|
5727
|
+
const contentTypeName = apiAndType[1];
|
|
5728
|
+
strapi2.log.info(`[webbycommerce] \u2713 New collection created: ${contentType.uid}`);
|
|
5729
|
+
strapi2.log.info(`[webbycommerce] \u2713 Collection will be auto-registered on next restart`);
|
|
5730
|
+
strapi2.log.info(`[webbycommerce] \u2713 Strapi will auto-restart in develop mode to register the new collection`);
|
|
5731
|
+
const appDir = strapi2.dirs?.app?.root || path.resolve(__dirname, "../..");
|
|
5732
|
+
const schemaPath = path.join(appDir, "src", "api", apiName, "content-types", contentTypeName, "schema.json");
|
|
5733
|
+
if (fs.existsSync(schemaPath)) {
|
|
5734
|
+
strapi2.log.info(`[webbycommerce] \u2713 Schema file confirmed: ${schemaPath}`);
|
|
5735
|
+
strapi2.log.info(`[webbycommerce] \u2713 Auto-restart should occur automatically in develop mode`);
|
|
5736
|
+
}
|
|
5737
|
+
}
|
|
5738
|
+
}
|
|
5739
|
+
}
|
|
5740
|
+
}
|
|
5741
|
+
}
|
|
5742
|
+
} else {
|
|
5743
|
+
await next();
|
|
5744
|
+
}
|
|
5745
|
+
});
|
|
5746
|
+
try {
|
|
5747
|
+
const allContentTypes = strapi2.contentTypes;
|
|
5748
|
+
const apiContentTypes = Object.keys(allContentTypes).filter((uid) => uid.startsWith("api::"));
|
|
5749
|
+
strapi2.log.info(`[webbycommerce] Currently registered API content types: ${apiContentTypes.length}`);
|
|
5750
|
+
if (apiContentTypes.length > 0) {
|
|
5751
|
+
strapi2.log.info(`[webbycommerce] Registered collections: ${apiContentTypes.join(", ")}`);
|
|
5752
|
+
}
|
|
5753
|
+
} catch (error) {
|
|
5754
|
+
}
|
|
4919
5755
|
strapi2.log.info("[webbycommerce] Plugin bootstrapped successfully");
|
|
4920
5756
|
strapi2.log.info(
|
|
4921
5757
|
"[webbycommerce] Health endpoint is available at: /webbycommerce/health and /api/webbycommerce/health"
|
|
4922
5758
|
);
|
|
5759
|
+
strapi2.log.info("[webbycommerce] Auto-restart enabled: Strapi will automatically restart when new collections are added");
|
|
4923
5760
|
strapi2.log.info("[webbycommerce] ========================================");
|
|
4924
5761
|
} catch (error) {
|
|
4925
5762
|
strapi2.log.error("[webbycommerce] Bootstrap error:", error);
|
|
@@ -4998,8 +5835,8 @@ var require_controller = __commonJS({
|
|
|
4998
5835
|
const currentValue = await store.get({ key: SETTINGS_KEY }) || {};
|
|
4999
5836
|
const allowedOrigins = body.allowedOrigins !== void 0 ? sanitizeOrigins(body.allowedOrigins) : sanitizeOrigins(currentValue.allowedOrigins);
|
|
5000
5837
|
let loginRegisterMethod = body.loginRegisterMethod !== void 0 ? body.loginRegisterMethod : currentValue.loginRegisterMethod || "default";
|
|
5001
|
-
if (loginRegisterMethod !== "default" && loginRegisterMethod !== "otp") {
|
|
5002
|
-
return ctx.badRequest('Invalid loginRegisterMethod. Must be "default" or "
|
|
5838
|
+
if (loginRegisterMethod !== "default" && loginRegisterMethod !== "otp" && loginRegisterMethod !== "both") {
|
|
5839
|
+
return ctx.badRequest('Invalid loginRegisterMethod. Must be "default", "otp", or "both".');
|
|
5003
5840
|
}
|
|
5004
5841
|
let routePrefix = body.routePrefix !== void 0 ? body.routePrefix : currentValue.routePrefix || "webbycommerce";
|
|
5005
5842
|
routePrefix = routePrefix.trim().replace(/^\/+|\/+$/g, "").replace(/\/+/g, "/").replace(/[^a-zA-Z0-9\/_-]/g, "") || "webbycommerce";
|
|
@@ -5037,32 +5874,1850 @@ var require_controller = __commonJS({
|
|
|
5037
5874
|
strapi.log.error(`[${PLUGIN_ID}] Seed demo failed:`, error);
|
|
5038
5875
|
ctx.badRequest("Failed to seed demo data", { error: error.message });
|
|
5039
5876
|
}
|
|
5040
|
-
},
|
|
5041
|
-
async generateDemo(ctx) {
|
|
5042
|
-
strapi.log.info(`[${PLUGIN_ID}] Demo data generation requested`);
|
|
5043
|
-
try {
|
|
5044
|
-
const path = require("path");
|
|
5045
|
-
const demoScriptPath = path.join(strapi.dirs.app.root, "scripts", "demo-ecommerce-visual.js");
|
|
5046
|
-
strapi.log.info(`[${PLUGIN_ID}] Loading demo script from: ${demoScriptPath}`);
|
|
5047
|
-
const { createVisualDemo } = require(demoScriptPath);
|
|
5048
|
-
if (typeof createVisualDemo !== "function") {
|
|
5049
|
-
throw new Error("createVisualDemo is not a function in the demo script");
|
|
5877
|
+
},
|
|
5878
|
+
async generateDemo(ctx) {
|
|
5879
|
+
strapi.log.info(`[${PLUGIN_ID}] Demo data generation requested`);
|
|
5880
|
+
try {
|
|
5881
|
+
const path = require("path");
|
|
5882
|
+
const demoScriptPath = path.join(strapi.dirs.app.root, "scripts", "demo-ecommerce-visual.js");
|
|
5883
|
+
strapi.log.info(`[${PLUGIN_ID}] Loading demo script from: ${demoScriptPath}`);
|
|
5884
|
+
const { createVisualDemo } = require(demoScriptPath);
|
|
5885
|
+
if (typeof createVisualDemo !== "function") {
|
|
5886
|
+
throw new Error("createVisualDemo is not a function in the demo script");
|
|
5887
|
+
}
|
|
5888
|
+
const result = await createVisualDemo();
|
|
5889
|
+
ctx.body = {
|
|
5890
|
+
success: true,
|
|
5891
|
+
message: "Demo data generated successfully",
|
|
5892
|
+
data: result
|
|
5893
|
+
};
|
|
5894
|
+
} catch (error) {
|
|
5895
|
+
strapi.log.error(`[${PLUGIN_ID}] Demo generation failed:`, error);
|
|
5896
|
+
ctx.badRequest("Failed to generate demo data", {
|
|
5897
|
+
error: error.message,
|
|
5898
|
+
details: error.stack
|
|
5899
|
+
});
|
|
5900
|
+
}
|
|
5901
|
+
}
|
|
5902
|
+
};
|
|
5903
|
+
}
|
|
5904
|
+
});
|
|
5905
|
+
|
|
5906
|
+
// node_modules/bcryptjs/dist/bcrypt.js
|
|
5907
|
+
var require_bcrypt = __commonJS({
|
|
5908
|
+
"node_modules/bcryptjs/dist/bcrypt.js"(exports2, module2) {
|
|
5909
|
+
(function(global, factory) {
|
|
5910
|
+
if (typeof define === "function" && define["amd"])
|
|
5911
|
+
define([], factory);
|
|
5912
|
+
else if (typeof require === "function" && typeof module2 === "object" && module2 && module2["exports"])
|
|
5913
|
+
module2["exports"] = factory();
|
|
5914
|
+
else
|
|
5915
|
+
(global["dcodeIO"] = global["dcodeIO"] || {})["bcrypt"] = factory();
|
|
5916
|
+
})(exports2, function() {
|
|
5917
|
+
"use strict";
|
|
5918
|
+
var bcrypt = {};
|
|
5919
|
+
var randomFallback = null;
|
|
5920
|
+
function random(len) {
|
|
5921
|
+
if (typeof module2 !== "undefined" && module2 && module2["exports"])
|
|
5922
|
+
try {
|
|
5923
|
+
return require("crypto")["randomBytes"](len);
|
|
5924
|
+
} catch (e) {
|
|
5925
|
+
}
|
|
5926
|
+
try {
|
|
5927
|
+
var a;
|
|
5928
|
+
(self["crypto"] || self["msCrypto"])["getRandomValues"](a = new Uint32Array(len));
|
|
5929
|
+
return Array.prototype.slice.call(a);
|
|
5930
|
+
} catch (e) {
|
|
5931
|
+
}
|
|
5932
|
+
if (!randomFallback)
|
|
5933
|
+
throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative");
|
|
5934
|
+
return randomFallback(len);
|
|
5935
|
+
}
|
|
5936
|
+
var randomAvailable = false;
|
|
5937
|
+
try {
|
|
5938
|
+
random(1);
|
|
5939
|
+
randomAvailable = true;
|
|
5940
|
+
} catch (e) {
|
|
5941
|
+
}
|
|
5942
|
+
randomFallback = null;
|
|
5943
|
+
bcrypt.setRandomFallback = function(random2) {
|
|
5944
|
+
randomFallback = random2;
|
|
5945
|
+
};
|
|
5946
|
+
bcrypt.genSaltSync = function(rounds, seed_length) {
|
|
5947
|
+
rounds = rounds || GENSALT_DEFAULT_LOG2_ROUNDS;
|
|
5948
|
+
if (typeof rounds !== "number")
|
|
5949
|
+
throw Error("Illegal arguments: " + typeof rounds + ", " + typeof seed_length);
|
|
5950
|
+
if (rounds < 4)
|
|
5951
|
+
rounds = 4;
|
|
5952
|
+
else if (rounds > 31)
|
|
5953
|
+
rounds = 31;
|
|
5954
|
+
var salt = [];
|
|
5955
|
+
salt.push("$2a$");
|
|
5956
|
+
if (rounds < 10)
|
|
5957
|
+
salt.push("0");
|
|
5958
|
+
salt.push(rounds.toString());
|
|
5959
|
+
salt.push("$");
|
|
5960
|
+
salt.push(base64_encode(random(BCRYPT_SALT_LEN), BCRYPT_SALT_LEN));
|
|
5961
|
+
return salt.join("");
|
|
5962
|
+
};
|
|
5963
|
+
bcrypt.genSalt = function(rounds, seed_length, callback) {
|
|
5964
|
+
if (typeof seed_length === "function")
|
|
5965
|
+
callback = seed_length, seed_length = void 0;
|
|
5966
|
+
if (typeof rounds === "function")
|
|
5967
|
+
callback = rounds, rounds = void 0;
|
|
5968
|
+
if (typeof rounds === "undefined")
|
|
5969
|
+
rounds = GENSALT_DEFAULT_LOG2_ROUNDS;
|
|
5970
|
+
else if (typeof rounds !== "number")
|
|
5971
|
+
throw Error("illegal arguments: " + typeof rounds);
|
|
5972
|
+
function _async(callback2) {
|
|
5973
|
+
nextTick(function() {
|
|
5974
|
+
try {
|
|
5975
|
+
callback2(null, bcrypt.genSaltSync(rounds));
|
|
5976
|
+
} catch (err) {
|
|
5977
|
+
callback2(err);
|
|
5978
|
+
}
|
|
5979
|
+
});
|
|
5980
|
+
}
|
|
5981
|
+
if (callback) {
|
|
5982
|
+
if (typeof callback !== "function")
|
|
5983
|
+
throw Error("Illegal callback: " + typeof callback);
|
|
5984
|
+
_async(callback);
|
|
5985
|
+
} else
|
|
5986
|
+
return new Promise(function(resolve, reject) {
|
|
5987
|
+
_async(function(err, res) {
|
|
5988
|
+
if (err) {
|
|
5989
|
+
reject(err);
|
|
5990
|
+
return;
|
|
5991
|
+
}
|
|
5992
|
+
resolve(res);
|
|
5993
|
+
});
|
|
5994
|
+
});
|
|
5995
|
+
};
|
|
5996
|
+
bcrypt.hashSync = function(s, salt) {
|
|
5997
|
+
if (typeof salt === "undefined")
|
|
5998
|
+
salt = GENSALT_DEFAULT_LOG2_ROUNDS;
|
|
5999
|
+
if (typeof salt === "number")
|
|
6000
|
+
salt = bcrypt.genSaltSync(salt);
|
|
6001
|
+
if (typeof s !== "string" || typeof salt !== "string")
|
|
6002
|
+
throw Error("Illegal arguments: " + typeof s + ", " + typeof salt);
|
|
6003
|
+
return _hash(s, salt);
|
|
6004
|
+
};
|
|
6005
|
+
bcrypt.hash = function(s, salt, callback, progressCallback) {
|
|
6006
|
+
function _async(callback2) {
|
|
6007
|
+
if (typeof s === "string" && typeof salt === "number")
|
|
6008
|
+
bcrypt.genSalt(salt, function(err, salt2) {
|
|
6009
|
+
_hash(s, salt2, callback2, progressCallback);
|
|
6010
|
+
});
|
|
6011
|
+
else if (typeof s === "string" && typeof salt === "string")
|
|
6012
|
+
_hash(s, salt, callback2, progressCallback);
|
|
6013
|
+
else
|
|
6014
|
+
nextTick(callback2.bind(this, Error("Illegal arguments: " + typeof s + ", " + typeof salt)));
|
|
6015
|
+
}
|
|
6016
|
+
if (callback) {
|
|
6017
|
+
if (typeof callback !== "function")
|
|
6018
|
+
throw Error("Illegal callback: " + typeof callback);
|
|
6019
|
+
_async(callback);
|
|
6020
|
+
} else
|
|
6021
|
+
return new Promise(function(resolve, reject) {
|
|
6022
|
+
_async(function(err, res) {
|
|
6023
|
+
if (err) {
|
|
6024
|
+
reject(err);
|
|
6025
|
+
return;
|
|
6026
|
+
}
|
|
6027
|
+
resolve(res);
|
|
6028
|
+
});
|
|
6029
|
+
});
|
|
6030
|
+
};
|
|
6031
|
+
function safeStringCompare(known, unknown) {
|
|
6032
|
+
var right = 0, wrong = 0;
|
|
6033
|
+
for (var i = 0, k = known.length; i < k; ++i) {
|
|
6034
|
+
if (known.charCodeAt(i) === unknown.charCodeAt(i))
|
|
6035
|
+
++right;
|
|
6036
|
+
else
|
|
6037
|
+
++wrong;
|
|
6038
|
+
}
|
|
6039
|
+
if (right < 0)
|
|
6040
|
+
return false;
|
|
6041
|
+
return wrong === 0;
|
|
6042
|
+
}
|
|
6043
|
+
bcrypt.compareSync = function(s, hash) {
|
|
6044
|
+
if (typeof s !== "string" || typeof hash !== "string")
|
|
6045
|
+
throw Error("Illegal arguments: " + typeof s + ", " + typeof hash);
|
|
6046
|
+
if (hash.length !== 60)
|
|
6047
|
+
return false;
|
|
6048
|
+
return safeStringCompare(bcrypt.hashSync(s, hash.substr(0, hash.length - 31)), hash);
|
|
6049
|
+
};
|
|
6050
|
+
bcrypt.compare = function(s, hash, callback, progressCallback) {
|
|
6051
|
+
function _async(callback2) {
|
|
6052
|
+
if (typeof s !== "string" || typeof hash !== "string") {
|
|
6053
|
+
nextTick(callback2.bind(this, Error("Illegal arguments: " + typeof s + ", " + typeof hash)));
|
|
6054
|
+
return;
|
|
6055
|
+
}
|
|
6056
|
+
if (hash.length !== 60) {
|
|
6057
|
+
nextTick(callback2.bind(this, null, false));
|
|
6058
|
+
return;
|
|
6059
|
+
}
|
|
6060
|
+
bcrypt.hash(s, hash.substr(0, 29), function(err, comp) {
|
|
6061
|
+
if (err)
|
|
6062
|
+
callback2(err);
|
|
6063
|
+
else
|
|
6064
|
+
callback2(null, safeStringCompare(comp, hash));
|
|
6065
|
+
}, progressCallback);
|
|
6066
|
+
}
|
|
6067
|
+
if (callback) {
|
|
6068
|
+
if (typeof callback !== "function")
|
|
6069
|
+
throw Error("Illegal callback: " + typeof callback);
|
|
6070
|
+
_async(callback);
|
|
6071
|
+
} else
|
|
6072
|
+
return new Promise(function(resolve, reject) {
|
|
6073
|
+
_async(function(err, res) {
|
|
6074
|
+
if (err) {
|
|
6075
|
+
reject(err);
|
|
6076
|
+
return;
|
|
6077
|
+
}
|
|
6078
|
+
resolve(res);
|
|
6079
|
+
});
|
|
6080
|
+
});
|
|
6081
|
+
};
|
|
6082
|
+
bcrypt.getRounds = function(hash) {
|
|
6083
|
+
if (typeof hash !== "string")
|
|
6084
|
+
throw Error("Illegal arguments: " + typeof hash);
|
|
6085
|
+
return parseInt(hash.split("$")[2], 10);
|
|
6086
|
+
};
|
|
6087
|
+
bcrypt.getSalt = function(hash) {
|
|
6088
|
+
if (typeof hash !== "string")
|
|
6089
|
+
throw Error("Illegal arguments: " + typeof hash);
|
|
6090
|
+
if (hash.length !== 60)
|
|
6091
|
+
throw Error("Illegal hash length: " + hash.length + " != 60");
|
|
6092
|
+
return hash.substring(0, 29);
|
|
6093
|
+
};
|
|
6094
|
+
var nextTick = typeof process !== "undefined" && process && typeof process.nextTick === "function" ? typeof setImmediate === "function" ? setImmediate : process.nextTick : setTimeout;
|
|
6095
|
+
function stringToBytes(str) {
|
|
6096
|
+
var out = [], i = 0;
|
|
6097
|
+
utfx.encodeUTF16toUTF8(function() {
|
|
6098
|
+
if (i >= str.length) return null;
|
|
6099
|
+
return str.charCodeAt(i++);
|
|
6100
|
+
}, function(b) {
|
|
6101
|
+
out.push(b);
|
|
6102
|
+
});
|
|
6103
|
+
return out;
|
|
6104
|
+
}
|
|
6105
|
+
var BASE64_CODE = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split("");
|
|
6106
|
+
var BASE64_INDEX = [
|
|
6107
|
+
-1,
|
|
6108
|
+
-1,
|
|
6109
|
+
-1,
|
|
6110
|
+
-1,
|
|
6111
|
+
-1,
|
|
6112
|
+
-1,
|
|
6113
|
+
-1,
|
|
6114
|
+
-1,
|
|
6115
|
+
-1,
|
|
6116
|
+
-1,
|
|
6117
|
+
-1,
|
|
6118
|
+
-1,
|
|
6119
|
+
-1,
|
|
6120
|
+
-1,
|
|
6121
|
+
-1,
|
|
6122
|
+
-1,
|
|
6123
|
+
-1,
|
|
6124
|
+
-1,
|
|
6125
|
+
-1,
|
|
6126
|
+
-1,
|
|
6127
|
+
-1,
|
|
6128
|
+
-1,
|
|
6129
|
+
-1,
|
|
6130
|
+
-1,
|
|
6131
|
+
-1,
|
|
6132
|
+
-1,
|
|
6133
|
+
-1,
|
|
6134
|
+
-1,
|
|
6135
|
+
-1,
|
|
6136
|
+
-1,
|
|
6137
|
+
-1,
|
|
6138
|
+
-1,
|
|
6139
|
+
-1,
|
|
6140
|
+
-1,
|
|
6141
|
+
-1,
|
|
6142
|
+
-1,
|
|
6143
|
+
-1,
|
|
6144
|
+
-1,
|
|
6145
|
+
-1,
|
|
6146
|
+
-1,
|
|
6147
|
+
-1,
|
|
6148
|
+
-1,
|
|
6149
|
+
-1,
|
|
6150
|
+
-1,
|
|
6151
|
+
-1,
|
|
6152
|
+
-1,
|
|
6153
|
+
0,
|
|
6154
|
+
1,
|
|
6155
|
+
54,
|
|
6156
|
+
55,
|
|
6157
|
+
56,
|
|
6158
|
+
57,
|
|
6159
|
+
58,
|
|
6160
|
+
59,
|
|
6161
|
+
60,
|
|
6162
|
+
61,
|
|
6163
|
+
62,
|
|
6164
|
+
63,
|
|
6165
|
+
-1,
|
|
6166
|
+
-1,
|
|
6167
|
+
-1,
|
|
6168
|
+
-1,
|
|
6169
|
+
-1,
|
|
6170
|
+
-1,
|
|
6171
|
+
-1,
|
|
6172
|
+
2,
|
|
6173
|
+
3,
|
|
6174
|
+
4,
|
|
6175
|
+
5,
|
|
6176
|
+
6,
|
|
6177
|
+
7,
|
|
6178
|
+
8,
|
|
6179
|
+
9,
|
|
6180
|
+
10,
|
|
6181
|
+
11,
|
|
6182
|
+
12,
|
|
6183
|
+
13,
|
|
6184
|
+
14,
|
|
6185
|
+
15,
|
|
6186
|
+
16,
|
|
6187
|
+
17,
|
|
6188
|
+
18,
|
|
6189
|
+
19,
|
|
6190
|
+
20,
|
|
6191
|
+
21,
|
|
6192
|
+
22,
|
|
6193
|
+
23,
|
|
6194
|
+
24,
|
|
6195
|
+
25,
|
|
6196
|
+
26,
|
|
6197
|
+
27,
|
|
6198
|
+
-1,
|
|
6199
|
+
-1,
|
|
6200
|
+
-1,
|
|
6201
|
+
-1,
|
|
6202
|
+
-1,
|
|
6203
|
+
-1,
|
|
6204
|
+
28,
|
|
6205
|
+
29,
|
|
6206
|
+
30,
|
|
6207
|
+
31,
|
|
6208
|
+
32,
|
|
6209
|
+
33,
|
|
6210
|
+
34,
|
|
6211
|
+
35,
|
|
6212
|
+
36,
|
|
6213
|
+
37,
|
|
6214
|
+
38,
|
|
6215
|
+
39,
|
|
6216
|
+
40,
|
|
6217
|
+
41,
|
|
6218
|
+
42,
|
|
6219
|
+
43,
|
|
6220
|
+
44,
|
|
6221
|
+
45,
|
|
6222
|
+
46,
|
|
6223
|
+
47,
|
|
6224
|
+
48,
|
|
6225
|
+
49,
|
|
6226
|
+
50,
|
|
6227
|
+
51,
|
|
6228
|
+
52,
|
|
6229
|
+
53,
|
|
6230
|
+
-1,
|
|
6231
|
+
-1,
|
|
6232
|
+
-1,
|
|
6233
|
+
-1,
|
|
6234
|
+
-1
|
|
6235
|
+
];
|
|
6236
|
+
var stringFromCharCode = String.fromCharCode;
|
|
6237
|
+
function base64_encode(b, len) {
|
|
6238
|
+
var off = 0, rs = [], c1, c2;
|
|
6239
|
+
if (len <= 0 || len > b.length)
|
|
6240
|
+
throw Error("Illegal len: " + len);
|
|
6241
|
+
while (off < len) {
|
|
6242
|
+
c1 = b[off++] & 255;
|
|
6243
|
+
rs.push(BASE64_CODE[c1 >> 2 & 63]);
|
|
6244
|
+
c1 = (c1 & 3) << 4;
|
|
6245
|
+
if (off >= len) {
|
|
6246
|
+
rs.push(BASE64_CODE[c1 & 63]);
|
|
6247
|
+
break;
|
|
6248
|
+
}
|
|
6249
|
+
c2 = b[off++] & 255;
|
|
6250
|
+
c1 |= c2 >> 4 & 15;
|
|
6251
|
+
rs.push(BASE64_CODE[c1 & 63]);
|
|
6252
|
+
c1 = (c2 & 15) << 2;
|
|
6253
|
+
if (off >= len) {
|
|
6254
|
+
rs.push(BASE64_CODE[c1 & 63]);
|
|
6255
|
+
break;
|
|
6256
|
+
}
|
|
6257
|
+
c2 = b[off++] & 255;
|
|
6258
|
+
c1 |= c2 >> 6 & 3;
|
|
6259
|
+
rs.push(BASE64_CODE[c1 & 63]);
|
|
6260
|
+
rs.push(BASE64_CODE[c2 & 63]);
|
|
6261
|
+
}
|
|
6262
|
+
return rs.join("");
|
|
6263
|
+
}
|
|
6264
|
+
function base64_decode(s, len) {
|
|
6265
|
+
var off = 0, slen = s.length, olen = 0, rs = [], c1, c2, c3, c4, o, code;
|
|
6266
|
+
if (len <= 0)
|
|
6267
|
+
throw Error("Illegal len: " + len);
|
|
6268
|
+
while (off < slen - 1 && olen < len) {
|
|
6269
|
+
code = s.charCodeAt(off++);
|
|
6270
|
+
c1 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
|
|
6271
|
+
code = s.charCodeAt(off++);
|
|
6272
|
+
c2 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
|
|
6273
|
+
if (c1 == -1 || c2 == -1)
|
|
6274
|
+
break;
|
|
6275
|
+
o = c1 << 2 >>> 0;
|
|
6276
|
+
o |= (c2 & 48) >> 4;
|
|
6277
|
+
rs.push(stringFromCharCode(o));
|
|
6278
|
+
if (++olen >= len || off >= slen)
|
|
6279
|
+
break;
|
|
6280
|
+
code = s.charCodeAt(off++);
|
|
6281
|
+
c3 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
|
|
6282
|
+
if (c3 == -1)
|
|
6283
|
+
break;
|
|
6284
|
+
o = (c2 & 15) << 4 >>> 0;
|
|
6285
|
+
o |= (c3 & 60) >> 2;
|
|
6286
|
+
rs.push(stringFromCharCode(o));
|
|
6287
|
+
if (++olen >= len || off >= slen)
|
|
6288
|
+
break;
|
|
6289
|
+
code = s.charCodeAt(off++);
|
|
6290
|
+
c4 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
|
|
6291
|
+
o = (c3 & 3) << 6 >>> 0;
|
|
6292
|
+
o |= c4;
|
|
6293
|
+
rs.push(stringFromCharCode(o));
|
|
6294
|
+
++olen;
|
|
6295
|
+
}
|
|
6296
|
+
var res = [];
|
|
6297
|
+
for (off = 0; off < olen; off++)
|
|
6298
|
+
res.push(rs[off].charCodeAt(0));
|
|
6299
|
+
return res;
|
|
6300
|
+
}
|
|
6301
|
+
var utfx = (function() {
|
|
6302
|
+
"use strict";
|
|
6303
|
+
var utfx2 = {};
|
|
6304
|
+
utfx2.MAX_CODEPOINT = 1114111;
|
|
6305
|
+
utfx2.encodeUTF8 = function(src, dst) {
|
|
6306
|
+
var cp = null;
|
|
6307
|
+
if (typeof src === "number")
|
|
6308
|
+
cp = src, src = function() {
|
|
6309
|
+
return null;
|
|
6310
|
+
};
|
|
6311
|
+
while (cp !== null || (cp = src()) !== null) {
|
|
6312
|
+
if (cp < 128)
|
|
6313
|
+
dst(cp & 127);
|
|
6314
|
+
else if (cp < 2048)
|
|
6315
|
+
dst(cp >> 6 & 31 | 192), dst(cp & 63 | 128);
|
|
6316
|
+
else if (cp < 65536)
|
|
6317
|
+
dst(cp >> 12 & 15 | 224), dst(cp >> 6 & 63 | 128), dst(cp & 63 | 128);
|
|
6318
|
+
else
|
|
6319
|
+
dst(cp >> 18 & 7 | 240), dst(cp >> 12 & 63 | 128), dst(cp >> 6 & 63 | 128), dst(cp & 63 | 128);
|
|
6320
|
+
cp = null;
|
|
6321
|
+
}
|
|
6322
|
+
};
|
|
6323
|
+
utfx2.decodeUTF8 = function(src, dst) {
|
|
6324
|
+
var a, b, c, d, fail = function(b2) {
|
|
6325
|
+
b2 = b2.slice(0, b2.indexOf(null));
|
|
6326
|
+
var err = Error(b2.toString());
|
|
6327
|
+
err.name = "TruncatedError";
|
|
6328
|
+
err["bytes"] = b2;
|
|
6329
|
+
throw err;
|
|
6330
|
+
};
|
|
6331
|
+
while ((a = src()) !== null) {
|
|
6332
|
+
if ((a & 128) === 0)
|
|
6333
|
+
dst(a);
|
|
6334
|
+
else if ((a & 224) === 192)
|
|
6335
|
+
(b = src()) === null && fail([a, b]), dst((a & 31) << 6 | b & 63);
|
|
6336
|
+
else if ((a & 240) === 224)
|
|
6337
|
+
((b = src()) === null || (c = src()) === null) && fail([a, b, c]), dst((a & 15) << 12 | (b & 63) << 6 | c & 63);
|
|
6338
|
+
else if ((a & 248) === 240)
|
|
6339
|
+
((b = src()) === null || (c = src()) === null || (d = src()) === null) && fail([a, b, c, d]), dst((a & 7) << 18 | (b & 63) << 12 | (c & 63) << 6 | d & 63);
|
|
6340
|
+
else throw RangeError("Illegal starting byte: " + a);
|
|
6341
|
+
}
|
|
6342
|
+
};
|
|
6343
|
+
utfx2.UTF16toUTF8 = function(src, dst) {
|
|
6344
|
+
var c1, c2 = null;
|
|
6345
|
+
while (true) {
|
|
6346
|
+
if ((c1 = c2 !== null ? c2 : src()) === null)
|
|
6347
|
+
break;
|
|
6348
|
+
if (c1 >= 55296 && c1 <= 57343) {
|
|
6349
|
+
if ((c2 = src()) !== null) {
|
|
6350
|
+
if (c2 >= 56320 && c2 <= 57343) {
|
|
6351
|
+
dst((c1 - 55296) * 1024 + c2 - 56320 + 65536);
|
|
6352
|
+
c2 = null;
|
|
6353
|
+
continue;
|
|
6354
|
+
}
|
|
6355
|
+
}
|
|
6356
|
+
}
|
|
6357
|
+
dst(c1);
|
|
6358
|
+
}
|
|
6359
|
+
if (c2 !== null) dst(c2);
|
|
6360
|
+
};
|
|
6361
|
+
utfx2.UTF8toUTF16 = function(src, dst) {
|
|
6362
|
+
var cp = null;
|
|
6363
|
+
if (typeof src === "number")
|
|
6364
|
+
cp = src, src = function() {
|
|
6365
|
+
return null;
|
|
6366
|
+
};
|
|
6367
|
+
while (cp !== null || (cp = src()) !== null) {
|
|
6368
|
+
if (cp <= 65535)
|
|
6369
|
+
dst(cp);
|
|
6370
|
+
else
|
|
6371
|
+
cp -= 65536, dst((cp >> 10) + 55296), dst(cp % 1024 + 56320);
|
|
6372
|
+
cp = null;
|
|
6373
|
+
}
|
|
6374
|
+
};
|
|
6375
|
+
utfx2.encodeUTF16toUTF8 = function(src, dst) {
|
|
6376
|
+
utfx2.UTF16toUTF8(src, function(cp) {
|
|
6377
|
+
utfx2.encodeUTF8(cp, dst);
|
|
6378
|
+
});
|
|
6379
|
+
};
|
|
6380
|
+
utfx2.decodeUTF8toUTF16 = function(src, dst) {
|
|
6381
|
+
utfx2.decodeUTF8(src, function(cp) {
|
|
6382
|
+
utfx2.UTF8toUTF16(cp, dst);
|
|
6383
|
+
});
|
|
6384
|
+
};
|
|
6385
|
+
utfx2.calculateCodePoint = function(cp) {
|
|
6386
|
+
return cp < 128 ? 1 : cp < 2048 ? 2 : cp < 65536 ? 3 : 4;
|
|
6387
|
+
};
|
|
6388
|
+
utfx2.calculateUTF8 = function(src) {
|
|
6389
|
+
var cp, l = 0;
|
|
6390
|
+
while ((cp = src()) !== null)
|
|
6391
|
+
l += utfx2.calculateCodePoint(cp);
|
|
6392
|
+
return l;
|
|
6393
|
+
};
|
|
6394
|
+
utfx2.calculateUTF16asUTF8 = function(src) {
|
|
6395
|
+
var n = 0, l = 0;
|
|
6396
|
+
utfx2.UTF16toUTF8(src, function(cp) {
|
|
6397
|
+
++n;
|
|
6398
|
+
l += utfx2.calculateCodePoint(cp);
|
|
6399
|
+
});
|
|
6400
|
+
return [n, l];
|
|
6401
|
+
};
|
|
6402
|
+
return utfx2;
|
|
6403
|
+
})();
|
|
6404
|
+
Date.now = Date.now || function() {
|
|
6405
|
+
return +/* @__PURE__ */ new Date();
|
|
6406
|
+
};
|
|
6407
|
+
var BCRYPT_SALT_LEN = 16;
|
|
6408
|
+
var GENSALT_DEFAULT_LOG2_ROUNDS = 10;
|
|
6409
|
+
var BLOWFISH_NUM_ROUNDS = 16;
|
|
6410
|
+
var MAX_EXECUTION_TIME = 100;
|
|
6411
|
+
var P_ORIG = [
|
|
6412
|
+
608135816,
|
|
6413
|
+
2242054355,
|
|
6414
|
+
320440878,
|
|
6415
|
+
57701188,
|
|
6416
|
+
2752067618,
|
|
6417
|
+
698298832,
|
|
6418
|
+
137296536,
|
|
6419
|
+
3964562569,
|
|
6420
|
+
1160258022,
|
|
6421
|
+
953160567,
|
|
6422
|
+
3193202383,
|
|
6423
|
+
887688300,
|
|
6424
|
+
3232508343,
|
|
6425
|
+
3380367581,
|
|
6426
|
+
1065670069,
|
|
6427
|
+
3041331479,
|
|
6428
|
+
2450970073,
|
|
6429
|
+
2306472731
|
|
6430
|
+
];
|
|
6431
|
+
var S_ORIG = [
|
|
6432
|
+
3509652390,
|
|
6433
|
+
2564797868,
|
|
6434
|
+
805139163,
|
|
6435
|
+
3491422135,
|
|
6436
|
+
3101798381,
|
|
6437
|
+
1780907670,
|
|
6438
|
+
3128725573,
|
|
6439
|
+
4046225305,
|
|
6440
|
+
614570311,
|
|
6441
|
+
3012652279,
|
|
6442
|
+
134345442,
|
|
6443
|
+
2240740374,
|
|
6444
|
+
1667834072,
|
|
6445
|
+
1901547113,
|
|
6446
|
+
2757295779,
|
|
6447
|
+
4103290238,
|
|
6448
|
+
227898511,
|
|
6449
|
+
1921955416,
|
|
6450
|
+
1904987480,
|
|
6451
|
+
2182433518,
|
|
6452
|
+
2069144605,
|
|
6453
|
+
3260701109,
|
|
6454
|
+
2620446009,
|
|
6455
|
+
720527379,
|
|
6456
|
+
3318853667,
|
|
6457
|
+
677414384,
|
|
6458
|
+
3393288472,
|
|
6459
|
+
3101374703,
|
|
6460
|
+
2390351024,
|
|
6461
|
+
1614419982,
|
|
6462
|
+
1822297739,
|
|
6463
|
+
2954791486,
|
|
6464
|
+
3608508353,
|
|
6465
|
+
3174124327,
|
|
6466
|
+
2024746970,
|
|
6467
|
+
1432378464,
|
|
6468
|
+
3864339955,
|
|
6469
|
+
2857741204,
|
|
6470
|
+
1464375394,
|
|
6471
|
+
1676153920,
|
|
6472
|
+
1439316330,
|
|
6473
|
+
715854006,
|
|
6474
|
+
3033291828,
|
|
6475
|
+
289532110,
|
|
6476
|
+
2706671279,
|
|
6477
|
+
2087905683,
|
|
6478
|
+
3018724369,
|
|
6479
|
+
1668267050,
|
|
6480
|
+
732546397,
|
|
6481
|
+
1947742710,
|
|
6482
|
+
3462151702,
|
|
6483
|
+
2609353502,
|
|
6484
|
+
2950085171,
|
|
6485
|
+
1814351708,
|
|
6486
|
+
2050118529,
|
|
6487
|
+
680887927,
|
|
6488
|
+
999245976,
|
|
6489
|
+
1800124847,
|
|
6490
|
+
3300911131,
|
|
6491
|
+
1713906067,
|
|
6492
|
+
1641548236,
|
|
6493
|
+
4213287313,
|
|
6494
|
+
1216130144,
|
|
6495
|
+
1575780402,
|
|
6496
|
+
4018429277,
|
|
6497
|
+
3917837745,
|
|
6498
|
+
3693486850,
|
|
6499
|
+
3949271944,
|
|
6500
|
+
596196993,
|
|
6501
|
+
3549867205,
|
|
6502
|
+
258830323,
|
|
6503
|
+
2213823033,
|
|
6504
|
+
772490370,
|
|
6505
|
+
2760122372,
|
|
6506
|
+
1774776394,
|
|
6507
|
+
2652871518,
|
|
6508
|
+
566650946,
|
|
6509
|
+
4142492826,
|
|
6510
|
+
1728879713,
|
|
6511
|
+
2882767088,
|
|
6512
|
+
1783734482,
|
|
6513
|
+
3629395816,
|
|
6514
|
+
2517608232,
|
|
6515
|
+
2874225571,
|
|
6516
|
+
1861159788,
|
|
6517
|
+
326777828,
|
|
6518
|
+
3124490320,
|
|
6519
|
+
2130389656,
|
|
6520
|
+
2716951837,
|
|
6521
|
+
967770486,
|
|
6522
|
+
1724537150,
|
|
6523
|
+
2185432712,
|
|
6524
|
+
2364442137,
|
|
6525
|
+
1164943284,
|
|
6526
|
+
2105845187,
|
|
6527
|
+
998989502,
|
|
6528
|
+
3765401048,
|
|
6529
|
+
2244026483,
|
|
6530
|
+
1075463327,
|
|
6531
|
+
1455516326,
|
|
6532
|
+
1322494562,
|
|
6533
|
+
910128902,
|
|
6534
|
+
469688178,
|
|
6535
|
+
1117454909,
|
|
6536
|
+
936433444,
|
|
6537
|
+
3490320968,
|
|
6538
|
+
3675253459,
|
|
6539
|
+
1240580251,
|
|
6540
|
+
122909385,
|
|
6541
|
+
2157517691,
|
|
6542
|
+
634681816,
|
|
6543
|
+
4142456567,
|
|
6544
|
+
3825094682,
|
|
6545
|
+
3061402683,
|
|
6546
|
+
2540495037,
|
|
6547
|
+
79693498,
|
|
6548
|
+
3249098678,
|
|
6549
|
+
1084186820,
|
|
6550
|
+
1583128258,
|
|
6551
|
+
426386531,
|
|
6552
|
+
1761308591,
|
|
6553
|
+
1047286709,
|
|
6554
|
+
322548459,
|
|
6555
|
+
995290223,
|
|
6556
|
+
1845252383,
|
|
6557
|
+
2603652396,
|
|
6558
|
+
3431023940,
|
|
6559
|
+
2942221577,
|
|
6560
|
+
3202600964,
|
|
6561
|
+
3727903485,
|
|
6562
|
+
1712269319,
|
|
6563
|
+
422464435,
|
|
6564
|
+
3234572375,
|
|
6565
|
+
1170764815,
|
|
6566
|
+
3523960633,
|
|
6567
|
+
3117677531,
|
|
6568
|
+
1434042557,
|
|
6569
|
+
442511882,
|
|
6570
|
+
3600875718,
|
|
6571
|
+
1076654713,
|
|
6572
|
+
1738483198,
|
|
6573
|
+
4213154764,
|
|
6574
|
+
2393238008,
|
|
6575
|
+
3677496056,
|
|
6576
|
+
1014306527,
|
|
6577
|
+
4251020053,
|
|
6578
|
+
793779912,
|
|
6579
|
+
2902807211,
|
|
6580
|
+
842905082,
|
|
6581
|
+
4246964064,
|
|
6582
|
+
1395751752,
|
|
6583
|
+
1040244610,
|
|
6584
|
+
2656851899,
|
|
6585
|
+
3396308128,
|
|
6586
|
+
445077038,
|
|
6587
|
+
3742853595,
|
|
6588
|
+
3577915638,
|
|
6589
|
+
679411651,
|
|
6590
|
+
2892444358,
|
|
6591
|
+
2354009459,
|
|
6592
|
+
1767581616,
|
|
6593
|
+
3150600392,
|
|
6594
|
+
3791627101,
|
|
6595
|
+
3102740896,
|
|
6596
|
+
284835224,
|
|
6597
|
+
4246832056,
|
|
6598
|
+
1258075500,
|
|
6599
|
+
768725851,
|
|
6600
|
+
2589189241,
|
|
6601
|
+
3069724005,
|
|
6602
|
+
3532540348,
|
|
6603
|
+
1274779536,
|
|
6604
|
+
3789419226,
|
|
6605
|
+
2764799539,
|
|
6606
|
+
1660621633,
|
|
6607
|
+
3471099624,
|
|
6608
|
+
4011903706,
|
|
6609
|
+
913787905,
|
|
6610
|
+
3497959166,
|
|
6611
|
+
737222580,
|
|
6612
|
+
2514213453,
|
|
6613
|
+
2928710040,
|
|
6614
|
+
3937242737,
|
|
6615
|
+
1804850592,
|
|
6616
|
+
3499020752,
|
|
6617
|
+
2949064160,
|
|
6618
|
+
2386320175,
|
|
6619
|
+
2390070455,
|
|
6620
|
+
2415321851,
|
|
6621
|
+
4061277028,
|
|
6622
|
+
2290661394,
|
|
6623
|
+
2416832540,
|
|
6624
|
+
1336762016,
|
|
6625
|
+
1754252060,
|
|
6626
|
+
3520065937,
|
|
6627
|
+
3014181293,
|
|
6628
|
+
791618072,
|
|
6629
|
+
3188594551,
|
|
6630
|
+
3933548030,
|
|
6631
|
+
2332172193,
|
|
6632
|
+
3852520463,
|
|
6633
|
+
3043980520,
|
|
6634
|
+
413987798,
|
|
6635
|
+
3465142937,
|
|
6636
|
+
3030929376,
|
|
6637
|
+
4245938359,
|
|
6638
|
+
2093235073,
|
|
6639
|
+
3534596313,
|
|
6640
|
+
375366246,
|
|
6641
|
+
2157278981,
|
|
6642
|
+
2479649556,
|
|
6643
|
+
555357303,
|
|
6644
|
+
3870105701,
|
|
6645
|
+
2008414854,
|
|
6646
|
+
3344188149,
|
|
6647
|
+
4221384143,
|
|
6648
|
+
3956125452,
|
|
6649
|
+
2067696032,
|
|
6650
|
+
3594591187,
|
|
6651
|
+
2921233993,
|
|
6652
|
+
2428461,
|
|
6653
|
+
544322398,
|
|
6654
|
+
577241275,
|
|
6655
|
+
1471733935,
|
|
6656
|
+
610547355,
|
|
6657
|
+
4027169054,
|
|
6658
|
+
1432588573,
|
|
6659
|
+
1507829418,
|
|
6660
|
+
2025931657,
|
|
6661
|
+
3646575487,
|
|
6662
|
+
545086370,
|
|
6663
|
+
48609733,
|
|
6664
|
+
2200306550,
|
|
6665
|
+
1653985193,
|
|
6666
|
+
298326376,
|
|
6667
|
+
1316178497,
|
|
6668
|
+
3007786442,
|
|
6669
|
+
2064951626,
|
|
6670
|
+
458293330,
|
|
6671
|
+
2589141269,
|
|
6672
|
+
3591329599,
|
|
6673
|
+
3164325604,
|
|
6674
|
+
727753846,
|
|
6675
|
+
2179363840,
|
|
6676
|
+
146436021,
|
|
6677
|
+
1461446943,
|
|
6678
|
+
4069977195,
|
|
6679
|
+
705550613,
|
|
6680
|
+
3059967265,
|
|
6681
|
+
3887724982,
|
|
6682
|
+
4281599278,
|
|
6683
|
+
3313849956,
|
|
6684
|
+
1404054877,
|
|
6685
|
+
2845806497,
|
|
6686
|
+
146425753,
|
|
6687
|
+
1854211946,
|
|
6688
|
+
1266315497,
|
|
6689
|
+
3048417604,
|
|
6690
|
+
3681880366,
|
|
6691
|
+
3289982499,
|
|
6692
|
+
290971e4,
|
|
6693
|
+
1235738493,
|
|
6694
|
+
2632868024,
|
|
6695
|
+
2414719590,
|
|
6696
|
+
3970600049,
|
|
6697
|
+
1771706367,
|
|
6698
|
+
1449415276,
|
|
6699
|
+
3266420449,
|
|
6700
|
+
422970021,
|
|
6701
|
+
1963543593,
|
|
6702
|
+
2690192192,
|
|
6703
|
+
3826793022,
|
|
6704
|
+
1062508698,
|
|
6705
|
+
1531092325,
|
|
6706
|
+
1804592342,
|
|
6707
|
+
2583117782,
|
|
6708
|
+
2714934279,
|
|
6709
|
+
4024971509,
|
|
6710
|
+
1294809318,
|
|
6711
|
+
4028980673,
|
|
6712
|
+
1289560198,
|
|
6713
|
+
2221992742,
|
|
6714
|
+
1669523910,
|
|
6715
|
+
35572830,
|
|
6716
|
+
157838143,
|
|
6717
|
+
1052438473,
|
|
6718
|
+
1016535060,
|
|
6719
|
+
1802137761,
|
|
6720
|
+
1753167236,
|
|
6721
|
+
1386275462,
|
|
6722
|
+
3080475397,
|
|
6723
|
+
2857371447,
|
|
6724
|
+
1040679964,
|
|
6725
|
+
2145300060,
|
|
6726
|
+
2390574316,
|
|
6727
|
+
1461121720,
|
|
6728
|
+
2956646967,
|
|
6729
|
+
4031777805,
|
|
6730
|
+
4028374788,
|
|
6731
|
+
33600511,
|
|
6732
|
+
2920084762,
|
|
6733
|
+
1018524850,
|
|
6734
|
+
629373528,
|
|
6735
|
+
3691585981,
|
|
6736
|
+
3515945977,
|
|
6737
|
+
2091462646,
|
|
6738
|
+
2486323059,
|
|
6739
|
+
586499841,
|
|
6740
|
+
988145025,
|
|
6741
|
+
935516892,
|
|
6742
|
+
3367335476,
|
|
6743
|
+
2599673255,
|
|
6744
|
+
2839830854,
|
|
6745
|
+
265290510,
|
|
6746
|
+
3972581182,
|
|
6747
|
+
2759138881,
|
|
6748
|
+
3795373465,
|
|
6749
|
+
1005194799,
|
|
6750
|
+
847297441,
|
|
6751
|
+
406762289,
|
|
6752
|
+
1314163512,
|
|
6753
|
+
1332590856,
|
|
6754
|
+
1866599683,
|
|
6755
|
+
4127851711,
|
|
6756
|
+
750260880,
|
|
6757
|
+
613907577,
|
|
6758
|
+
1450815602,
|
|
6759
|
+
3165620655,
|
|
6760
|
+
3734664991,
|
|
6761
|
+
3650291728,
|
|
6762
|
+
3012275730,
|
|
6763
|
+
3704569646,
|
|
6764
|
+
1427272223,
|
|
6765
|
+
778793252,
|
|
6766
|
+
1343938022,
|
|
6767
|
+
2676280711,
|
|
6768
|
+
2052605720,
|
|
6769
|
+
1946737175,
|
|
6770
|
+
3164576444,
|
|
6771
|
+
3914038668,
|
|
6772
|
+
3967478842,
|
|
6773
|
+
3682934266,
|
|
6774
|
+
1661551462,
|
|
6775
|
+
3294938066,
|
|
6776
|
+
4011595847,
|
|
6777
|
+
840292616,
|
|
6778
|
+
3712170807,
|
|
6779
|
+
616741398,
|
|
6780
|
+
312560963,
|
|
6781
|
+
711312465,
|
|
6782
|
+
1351876610,
|
|
6783
|
+
322626781,
|
|
6784
|
+
1910503582,
|
|
6785
|
+
271666773,
|
|
6786
|
+
2175563734,
|
|
6787
|
+
1594956187,
|
|
6788
|
+
70604529,
|
|
6789
|
+
3617834859,
|
|
6790
|
+
1007753275,
|
|
6791
|
+
1495573769,
|
|
6792
|
+
4069517037,
|
|
6793
|
+
2549218298,
|
|
6794
|
+
2663038764,
|
|
6795
|
+
504708206,
|
|
6796
|
+
2263041392,
|
|
6797
|
+
3941167025,
|
|
6798
|
+
2249088522,
|
|
6799
|
+
1514023603,
|
|
6800
|
+
1998579484,
|
|
6801
|
+
1312622330,
|
|
6802
|
+
694541497,
|
|
6803
|
+
2582060303,
|
|
6804
|
+
2151582166,
|
|
6805
|
+
1382467621,
|
|
6806
|
+
776784248,
|
|
6807
|
+
2618340202,
|
|
6808
|
+
3323268794,
|
|
6809
|
+
2497899128,
|
|
6810
|
+
2784771155,
|
|
6811
|
+
503983604,
|
|
6812
|
+
4076293799,
|
|
6813
|
+
907881277,
|
|
6814
|
+
423175695,
|
|
6815
|
+
432175456,
|
|
6816
|
+
1378068232,
|
|
6817
|
+
4145222326,
|
|
6818
|
+
3954048622,
|
|
6819
|
+
3938656102,
|
|
6820
|
+
3820766613,
|
|
6821
|
+
2793130115,
|
|
6822
|
+
2977904593,
|
|
6823
|
+
26017576,
|
|
6824
|
+
3274890735,
|
|
6825
|
+
3194772133,
|
|
6826
|
+
1700274565,
|
|
6827
|
+
1756076034,
|
|
6828
|
+
4006520079,
|
|
6829
|
+
3677328699,
|
|
6830
|
+
720338349,
|
|
6831
|
+
1533947780,
|
|
6832
|
+
354530856,
|
|
6833
|
+
688349552,
|
|
6834
|
+
3973924725,
|
|
6835
|
+
1637815568,
|
|
6836
|
+
332179504,
|
|
6837
|
+
3949051286,
|
|
6838
|
+
53804574,
|
|
6839
|
+
2852348879,
|
|
6840
|
+
3044236432,
|
|
6841
|
+
1282449977,
|
|
6842
|
+
3583942155,
|
|
6843
|
+
3416972820,
|
|
6844
|
+
4006381244,
|
|
6845
|
+
1617046695,
|
|
6846
|
+
2628476075,
|
|
6847
|
+
3002303598,
|
|
6848
|
+
1686838959,
|
|
6849
|
+
431878346,
|
|
6850
|
+
2686675385,
|
|
6851
|
+
1700445008,
|
|
6852
|
+
1080580658,
|
|
6853
|
+
1009431731,
|
|
6854
|
+
832498133,
|
|
6855
|
+
3223435511,
|
|
6856
|
+
2605976345,
|
|
6857
|
+
2271191193,
|
|
6858
|
+
2516031870,
|
|
6859
|
+
1648197032,
|
|
6860
|
+
4164389018,
|
|
6861
|
+
2548247927,
|
|
6862
|
+
300782431,
|
|
6863
|
+
375919233,
|
|
6864
|
+
238389289,
|
|
6865
|
+
3353747414,
|
|
6866
|
+
2531188641,
|
|
6867
|
+
2019080857,
|
|
6868
|
+
1475708069,
|
|
6869
|
+
455242339,
|
|
6870
|
+
2609103871,
|
|
6871
|
+
448939670,
|
|
6872
|
+
3451063019,
|
|
6873
|
+
1395535956,
|
|
6874
|
+
2413381860,
|
|
6875
|
+
1841049896,
|
|
6876
|
+
1491858159,
|
|
6877
|
+
885456874,
|
|
6878
|
+
4264095073,
|
|
6879
|
+
4001119347,
|
|
6880
|
+
1565136089,
|
|
6881
|
+
3898914787,
|
|
6882
|
+
1108368660,
|
|
6883
|
+
540939232,
|
|
6884
|
+
1173283510,
|
|
6885
|
+
2745871338,
|
|
6886
|
+
3681308437,
|
|
6887
|
+
4207628240,
|
|
6888
|
+
3343053890,
|
|
6889
|
+
4016749493,
|
|
6890
|
+
1699691293,
|
|
6891
|
+
1103962373,
|
|
6892
|
+
3625875870,
|
|
6893
|
+
2256883143,
|
|
6894
|
+
3830138730,
|
|
6895
|
+
1031889488,
|
|
6896
|
+
3479347698,
|
|
6897
|
+
1535977030,
|
|
6898
|
+
4236805024,
|
|
6899
|
+
3251091107,
|
|
6900
|
+
2132092099,
|
|
6901
|
+
1774941330,
|
|
6902
|
+
1199868427,
|
|
6903
|
+
1452454533,
|
|
6904
|
+
157007616,
|
|
6905
|
+
2904115357,
|
|
6906
|
+
342012276,
|
|
6907
|
+
595725824,
|
|
6908
|
+
1480756522,
|
|
6909
|
+
206960106,
|
|
6910
|
+
497939518,
|
|
6911
|
+
591360097,
|
|
6912
|
+
863170706,
|
|
6913
|
+
2375253569,
|
|
6914
|
+
3596610801,
|
|
6915
|
+
1814182875,
|
|
6916
|
+
2094937945,
|
|
6917
|
+
3421402208,
|
|
6918
|
+
1082520231,
|
|
6919
|
+
3463918190,
|
|
6920
|
+
2785509508,
|
|
6921
|
+
435703966,
|
|
6922
|
+
3908032597,
|
|
6923
|
+
1641649973,
|
|
6924
|
+
2842273706,
|
|
6925
|
+
3305899714,
|
|
6926
|
+
1510255612,
|
|
6927
|
+
2148256476,
|
|
6928
|
+
2655287854,
|
|
6929
|
+
3276092548,
|
|
6930
|
+
4258621189,
|
|
6931
|
+
236887753,
|
|
6932
|
+
3681803219,
|
|
6933
|
+
274041037,
|
|
6934
|
+
1734335097,
|
|
6935
|
+
3815195456,
|
|
6936
|
+
3317970021,
|
|
6937
|
+
1899903192,
|
|
6938
|
+
1026095262,
|
|
6939
|
+
4050517792,
|
|
6940
|
+
356393447,
|
|
6941
|
+
2410691914,
|
|
6942
|
+
3873677099,
|
|
6943
|
+
3682840055,
|
|
6944
|
+
3913112168,
|
|
6945
|
+
2491498743,
|
|
6946
|
+
4132185628,
|
|
6947
|
+
2489919796,
|
|
6948
|
+
1091903735,
|
|
6949
|
+
1979897079,
|
|
6950
|
+
3170134830,
|
|
6951
|
+
3567386728,
|
|
6952
|
+
3557303409,
|
|
6953
|
+
857797738,
|
|
6954
|
+
1136121015,
|
|
6955
|
+
1342202287,
|
|
6956
|
+
507115054,
|
|
6957
|
+
2535736646,
|
|
6958
|
+
337727348,
|
|
6959
|
+
3213592640,
|
|
6960
|
+
1301675037,
|
|
6961
|
+
2528481711,
|
|
6962
|
+
1895095763,
|
|
6963
|
+
1721773893,
|
|
6964
|
+
3216771564,
|
|
6965
|
+
62756741,
|
|
6966
|
+
2142006736,
|
|
6967
|
+
835421444,
|
|
6968
|
+
2531993523,
|
|
6969
|
+
1442658625,
|
|
6970
|
+
3659876326,
|
|
6971
|
+
2882144922,
|
|
6972
|
+
676362277,
|
|
6973
|
+
1392781812,
|
|
6974
|
+
170690266,
|
|
6975
|
+
3921047035,
|
|
6976
|
+
1759253602,
|
|
6977
|
+
3611846912,
|
|
6978
|
+
1745797284,
|
|
6979
|
+
664899054,
|
|
6980
|
+
1329594018,
|
|
6981
|
+
3901205900,
|
|
6982
|
+
3045908486,
|
|
6983
|
+
2062866102,
|
|
6984
|
+
2865634940,
|
|
6985
|
+
3543621612,
|
|
6986
|
+
3464012697,
|
|
6987
|
+
1080764994,
|
|
6988
|
+
553557557,
|
|
6989
|
+
3656615353,
|
|
6990
|
+
3996768171,
|
|
6991
|
+
991055499,
|
|
6992
|
+
499776247,
|
|
6993
|
+
1265440854,
|
|
6994
|
+
648242737,
|
|
6995
|
+
3940784050,
|
|
6996
|
+
980351604,
|
|
6997
|
+
3713745714,
|
|
6998
|
+
1749149687,
|
|
6999
|
+
3396870395,
|
|
7000
|
+
4211799374,
|
|
7001
|
+
3640570775,
|
|
7002
|
+
1161844396,
|
|
7003
|
+
3125318951,
|
|
7004
|
+
1431517754,
|
|
7005
|
+
545492359,
|
|
7006
|
+
4268468663,
|
|
7007
|
+
3499529547,
|
|
7008
|
+
1437099964,
|
|
7009
|
+
2702547544,
|
|
7010
|
+
3433638243,
|
|
7011
|
+
2581715763,
|
|
7012
|
+
2787789398,
|
|
7013
|
+
1060185593,
|
|
7014
|
+
1593081372,
|
|
7015
|
+
2418618748,
|
|
7016
|
+
4260947970,
|
|
7017
|
+
69676912,
|
|
7018
|
+
2159744348,
|
|
7019
|
+
86519011,
|
|
7020
|
+
2512459080,
|
|
7021
|
+
3838209314,
|
|
7022
|
+
1220612927,
|
|
7023
|
+
3339683548,
|
|
7024
|
+
133810670,
|
|
7025
|
+
1090789135,
|
|
7026
|
+
1078426020,
|
|
7027
|
+
1569222167,
|
|
7028
|
+
845107691,
|
|
7029
|
+
3583754449,
|
|
7030
|
+
4072456591,
|
|
7031
|
+
1091646820,
|
|
7032
|
+
628848692,
|
|
7033
|
+
1613405280,
|
|
7034
|
+
3757631651,
|
|
7035
|
+
526609435,
|
|
7036
|
+
236106946,
|
|
7037
|
+
48312990,
|
|
7038
|
+
2942717905,
|
|
7039
|
+
3402727701,
|
|
7040
|
+
1797494240,
|
|
7041
|
+
859738849,
|
|
7042
|
+
992217954,
|
|
7043
|
+
4005476642,
|
|
7044
|
+
2243076622,
|
|
7045
|
+
3870952857,
|
|
7046
|
+
3732016268,
|
|
7047
|
+
765654824,
|
|
7048
|
+
3490871365,
|
|
7049
|
+
2511836413,
|
|
7050
|
+
1685915746,
|
|
7051
|
+
3888969200,
|
|
7052
|
+
1414112111,
|
|
7053
|
+
2273134842,
|
|
7054
|
+
3281911079,
|
|
7055
|
+
4080962846,
|
|
7056
|
+
172450625,
|
|
7057
|
+
2569994100,
|
|
7058
|
+
980381355,
|
|
7059
|
+
4109958455,
|
|
7060
|
+
2819808352,
|
|
7061
|
+
2716589560,
|
|
7062
|
+
2568741196,
|
|
7063
|
+
3681446669,
|
|
7064
|
+
3329971472,
|
|
7065
|
+
1835478071,
|
|
7066
|
+
660984891,
|
|
7067
|
+
3704678404,
|
|
7068
|
+
4045999559,
|
|
7069
|
+
3422617507,
|
|
7070
|
+
3040415634,
|
|
7071
|
+
1762651403,
|
|
7072
|
+
1719377915,
|
|
7073
|
+
3470491036,
|
|
7074
|
+
2693910283,
|
|
7075
|
+
3642056355,
|
|
7076
|
+
3138596744,
|
|
7077
|
+
1364962596,
|
|
7078
|
+
2073328063,
|
|
7079
|
+
1983633131,
|
|
7080
|
+
926494387,
|
|
7081
|
+
3423689081,
|
|
7082
|
+
2150032023,
|
|
7083
|
+
4096667949,
|
|
7084
|
+
1749200295,
|
|
7085
|
+
3328846651,
|
|
7086
|
+
309677260,
|
|
7087
|
+
2016342300,
|
|
7088
|
+
1779581495,
|
|
7089
|
+
3079819751,
|
|
7090
|
+
111262694,
|
|
7091
|
+
1274766160,
|
|
7092
|
+
443224088,
|
|
7093
|
+
298511866,
|
|
7094
|
+
1025883608,
|
|
7095
|
+
3806446537,
|
|
7096
|
+
1145181785,
|
|
7097
|
+
168956806,
|
|
7098
|
+
3641502830,
|
|
7099
|
+
3584813610,
|
|
7100
|
+
1689216846,
|
|
7101
|
+
3666258015,
|
|
7102
|
+
3200248200,
|
|
7103
|
+
1692713982,
|
|
7104
|
+
2646376535,
|
|
7105
|
+
4042768518,
|
|
7106
|
+
1618508792,
|
|
7107
|
+
1610833997,
|
|
7108
|
+
3523052358,
|
|
7109
|
+
4130873264,
|
|
7110
|
+
2001055236,
|
|
7111
|
+
3610705100,
|
|
7112
|
+
2202168115,
|
|
7113
|
+
4028541809,
|
|
7114
|
+
2961195399,
|
|
7115
|
+
1006657119,
|
|
7116
|
+
2006996926,
|
|
7117
|
+
3186142756,
|
|
7118
|
+
1430667929,
|
|
7119
|
+
3210227297,
|
|
7120
|
+
1314452623,
|
|
7121
|
+
4074634658,
|
|
7122
|
+
4101304120,
|
|
7123
|
+
2273951170,
|
|
7124
|
+
1399257539,
|
|
7125
|
+
3367210612,
|
|
7126
|
+
3027628629,
|
|
7127
|
+
1190975929,
|
|
7128
|
+
2062231137,
|
|
7129
|
+
2333990788,
|
|
7130
|
+
2221543033,
|
|
7131
|
+
2438960610,
|
|
7132
|
+
1181637006,
|
|
7133
|
+
548689776,
|
|
7134
|
+
2362791313,
|
|
7135
|
+
3372408396,
|
|
7136
|
+
3104550113,
|
|
7137
|
+
3145860560,
|
|
7138
|
+
296247880,
|
|
7139
|
+
1970579870,
|
|
7140
|
+
3078560182,
|
|
7141
|
+
3769228297,
|
|
7142
|
+
1714227617,
|
|
7143
|
+
3291629107,
|
|
7144
|
+
3898220290,
|
|
7145
|
+
166772364,
|
|
7146
|
+
1251581989,
|
|
7147
|
+
493813264,
|
|
7148
|
+
448347421,
|
|
7149
|
+
195405023,
|
|
7150
|
+
2709975567,
|
|
7151
|
+
677966185,
|
|
7152
|
+
3703036547,
|
|
7153
|
+
1463355134,
|
|
7154
|
+
2715995803,
|
|
7155
|
+
1338867538,
|
|
7156
|
+
1343315457,
|
|
7157
|
+
2802222074,
|
|
7158
|
+
2684532164,
|
|
7159
|
+
233230375,
|
|
7160
|
+
2599980071,
|
|
7161
|
+
2000651841,
|
|
7162
|
+
3277868038,
|
|
7163
|
+
1638401717,
|
|
7164
|
+
4028070440,
|
|
7165
|
+
3237316320,
|
|
7166
|
+
6314154,
|
|
7167
|
+
819756386,
|
|
7168
|
+
300326615,
|
|
7169
|
+
590932579,
|
|
7170
|
+
1405279636,
|
|
7171
|
+
3267499572,
|
|
7172
|
+
3150704214,
|
|
7173
|
+
2428286686,
|
|
7174
|
+
3959192993,
|
|
7175
|
+
3461946742,
|
|
7176
|
+
1862657033,
|
|
7177
|
+
1266418056,
|
|
7178
|
+
963775037,
|
|
7179
|
+
2089974820,
|
|
7180
|
+
2263052895,
|
|
7181
|
+
1917689273,
|
|
7182
|
+
448879540,
|
|
7183
|
+
3550394620,
|
|
7184
|
+
3981727096,
|
|
7185
|
+
150775221,
|
|
7186
|
+
3627908307,
|
|
7187
|
+
1303187396,
|
|
7188
|
+
508620638,
|
|
7189
|
+
2975983352,
|
|
7190
|
+
2726630617,
|
|
7191
|
+
1817252668,
|
|
7192
|
+
1876281319,
|
|
7193
|
+
1457606340,
|
|
7194
|
+
908771278,
|
|
7195
|
+
3720792119,
|
|
7196
|
+
3617206836,
|
|
7197
|
+
2455994898,
|
|
7198
|
+
1729034894,
|
|
7199
|
+
1080033504,
|
|
7200
|
+
976866871,
|
|
7201
|
+
3556439503,
|
|
7202
|
+
2881648439,
|
|
7203
|
+
1522871579,
|
|
7204
|
+
1555064734,
|
|
7205
|
+
1336096578,
|
|
7206
|
+
3548522304,
|
|
7207
|
+
2579274686,
|
|
7208
|
+
3574697629,
|
|
7209
|
+
3205460757,
|
|
7210
|
+
3593280638,
|
|
7211
|
+
3338716283,
|
|
7212
|
+
3079412587,
|
|
7213
|
+
564236357,
|
|
7214
|
+
2993598910,
|
|
7215
|
+
1781952180,
|
|
7216
|
+
1464380207,
|
|
7217
|
+
3163844217,
|
|
7218
|
+
3332601554,
|
|
7219
|
+
1699332808,
|
|
7220
|
+
1393555694,
|
|
7221
|
+
1183702653,
|
|
7222
|
+
3581086237,
|
|
7223
|
+
1288719814,
|
|
7224
|
+
691649499,
|
|
7225
|
+
2847557200,
|
|
7226
|
+
2895455976,
|
|
7227
|
+
3193889540,
|
|
7228
|
+
2717570544,
|
|
7229
|
+
1781354906,
|
|
7230
|
+
1676643554,
|
|
7231
|
+
2592534050,
|
|
7232
|
+
3230253752,
|
|
7233
|
+
1126444790,
|
|
7234
|
+
2770207658,
|
|
7235
|
+
2633158820,
|
|
7236
|
+
2210423226,
|
|
7237
|
+
2615765581,
|
|
7238
|
+
2414155088,
|
|
7239
|
+
3127139286,
|
|
7240
|
+
673620729,
|
|
7241
|
+
2805611233,
|
|
7242
|
+
1269405062,
|
|
7243
|
+
4015350505,
|
|
7244
|
+
3341807571,
|
|
7245
|
+
4149409754,
|
|
7246
|
+
1057255273,
|
|
7247
|
+
2012875353,
|
|
7248
|
+
2162469141,
|
|
7249
|
+
2276492801,
|
|
7250
|
+
2601117357,
|
|
7251
|
+
993977747,
|
|
7252
|
+
3918593370,
|
|
7253
|
+
2654263191,
|
|
7254
|
+
753973209,
|
|
7255
|
+
36408145,
|
|
7256
|
+
2530585658,
|
|
7257
|
+
25011837,
|
|
7258
|
+
3520020182,
|
|
7259
|
+
2088578344,
|
|
7260
|
+
530523599,
|
|
7261
|
+
2918365339,
|
|
7262
|
+
1524020338,
|
|
7263
|
+
1518925132,
|
|
7264
|
+
3760827505,
|
|
7265
|
+
3759777254,
|
|
7266
|
+
1202760957,
|
|
7267
|
+
3985898139,
|
|
7268
|
+
3906192525,
|
|
7269
|
+
674977740,
|
|
7270
|
+
4174734889,
|
|
7271
|
+
2031300136,
|
|
7272
|
+
2019492241,
|
|
7273
|
+
3983892565,
|
|
7274
|
+
4153806404,
|
|
7275
|
+
3822280332,
|
|
7276
|
+
352677332,
|
|
7277
|
+
2297720250,
|
|
7278
|
+
60907813,
|
|
7279
|
+
90501309,
|
|
7280
|
+
3286998549,
|
|
7281
|
+
1016092578,
|
|
7282
|
+
2535922412,
|
|
7283
|
+
2839152426,
|
|
7284
|
+
457141659,
|
|
7285
|
+
509813237,
|
|
7286
|
+
4120667899,
|
|
7287
|
+
652014361,
|
|
7288
|
+
1966332200,
|
|
7289
|
+
2975202805,
|
|
7290
|
+
55981186,
|
|
7291
|
+
2327461051,
|
|
7292
|
+
676427537,
|
|
7293
|
+
3255491064,
|
|
7294
|
+
2882294119,
|
|
7295
|
+
3433927263,
|
|
7296
|
+
1307055953,
|
|
7297
|
+
942726286,
|
|
7298
|
+
933058658,
|
|
7299
|
+
2468411793,
|
|
7300
|
+
3933900994,
|
|
7301
|
+
4215176142,
|
|
7302
|
+
1361170020,
|
|
7303
|
+
2001714738,
|
|
7304
|
+
2830558078,
|
|
7305
|
+
3274259782,
|
|
7306
|
+
1222529897,
|
|
7307
|
+
1679025792,
|
|
7308
|
+
2729314320,
|
|
7309
|
+
3714953764,
|
|
7310
|
+
1770335741,
|
|
7311
|
+
151462246,
|
|
7312
|
+
3013232138,
|
|
7313
|
+
1682292957,
|
|
7314
|
+
1483529935,
|
|
7315
|
+
471910574,
|
|
7316
|
+
1539241949,
|
|
7317
|
+
458788160,
|
|
7318
|
+
3436315007,
|
|
7319
|
+
1807016891,
|
|
7320
|
+
3718408830,
|
|
7321
|
+
978976581,
|
|
7322
|
+
1043663428,
|
|
7323
|
+
3165965781,
|
|
7324
|
+
1927990952,
|
|
7325
|
+
4200891579,
|
|
7326
|
+
2372276910,
|
|
7327
|
+
3208408903,
|
|
7328
|
+
3533431907,
|
|
7329
|
+
1412390302,
|
|
7330
|
+
2931980059,
|
|
7331
|
+
4132332400,
|
|
7332
|
+
1947078029,
|
|
7333
|
+
3881505623,
|
|
7334
|
+
4168226417,
|
|
7335
|
+
2941484381,
|
|
7336
|
+
1077988104,
|
|
7337
|
+
1320477388,
|
|
7338
|
+
886195818,
|
|
7339
|
+
18198404,
|
|
7340
|
+
3786409e3,
|
|
7341
|
+
2509781533,
|
|
7342
|
+
112762804,
|
|
7343
|
+
3463356488,
|
|
7344
|
+
1866414978,
|
|
7345
|
+
891333506,
|
|
7346
|
+
18488651,
|
|
7347
|
+
661792760,
|
|
7348
|
+
1628790961,
|
|
7349
|
+
3885187036,
|
|
7350
|
+
3141171499,
|
|
7351
|
+
876946877,
|
|
7352
|
+
2693282273,
|
|
7353
|
+
1372485963,
|
|
7354
|
+
791857591,
|
|
7355
|
+
2686433993,
|
|
7356
|
+
3759982718,
|
|
7357
|
+
3167212022,
|
|
7358
|
+
3472953795,
|
|
7359
|
+
2716379847,
|
|
7360
|
+
445679433,
|
|
7361
|
+
3561995674,
|
|
7362
|
+
3504004811,
|
|
7363
|
+
3574258232,
|
|
7364
|
+
54117162,
|
|
7365
|
+
3331405415,
|
|
7366
|
+
2381918588,
|
|
7367
|
+
3769707343,
|
|
7368
|
+
4154350007,
|
|
7369
|
+
1140177722,
|
|
7370
|
+
4074052095,
|
|
7371
|
+
668550556,
|
|
7372
|
+
3214352940,
|
|
7373
|
+
367459370,
|
|
7374
|
+
261225585,
|
|
7375
|
+
2610173221,
|
|
7376
|
+
4209349473,
|
|
7377
|
+
3468074219,
|
|
7378
|
+
3265815641,
|
|
7379
|
+
314222801,
|
|
7380
|
+
3066103646,
|
|
7381
|
+
3808782860,
|
|
7382
|
+
282218597,
|
|
7383
|
+
3406013506,
|
|
7384
|
+
3773591054,
|
|
7385
|
+
379116347,
|
|
7386
|
+
1285071038,
|
|
7387
|
+
846784868,
|
|
7388
|
+
2669647154,
|
|
7389
|
+
3771962079,
|
|
7390
|
+
3550491691,
|
|
7391
|
+
2305946142,
|
|
7392
|
+
453669953,
|
|
7393
|
+
1268987020,
|
|
7394
|
+
3317592352,
|
|
7395
|
+
3279303384,
|
|
7396
|
+
3744833421,
|
|
7397
|
+
2610507566,
|
|
7398
|
+
3859509063,
|
|
7399
|
+
266596637,
|
|
7400
|
+
3847019092,
|
|
7401
|
+
517658769,
|
|
7402
|
+
3462560207,
|
|
7403
|
+
3443424879,
|
|
7404
|
+
370717030,
|
|
7405
|
+
4247526661,
|
|
7406
|
+
2224018117,
|
|
7407
|
+
4143653529,
|
|
7408
|
+
4112773975,
|
|
7409
|
+
2788324899,
|
|
7410
|
+
2477274417,
|
|
7411
|
+
1456262402,
|
|
7412
|
+
2901442914,
|
|
7413
|
+
1517677493,
|
|
7414
|
+
1846949527,
|
|
7415
|
+
2295493580,
|
|
7416
|
+
3734397586,
|
|
7417
|
+
2176403920,
|
|
7418
|
+
1280348187,
|
|
7419
|
+
1908823572,
|
|
7420
|
+
3871786941,
|
|
7421
|
+
846861322,
|
|
7422
|
+
1172426758,
|
|
7423
|
+
3287448474,
|
|
7424
|
+
3383383037,
|
|
7425
|
+
1655181056,
|
|
7426
|
+
3139813346,
|
|
7427
|
+
901632758,
|
|
7428
|
+
1897031941,
|
|
7429
|
+
2986607138,
|
|
7430
|
+
3066810236,
|
|
7431
|
+
3447102507,
|
|
7432
|
+
1393639104,
|
|
7433
|
+
373351379,
|
|
7434
|
+
950779232,
|
|
7435
|
+
625454576,
|
|
7436
|
+
3124240540,
|
|
7437
|
+
4148612726,
|
|
7438
|
+
2007998917,
|
|
7439
|
+
544563296,
|
|
7440
|
+
2244738638,
|
|
7441
|
+
2330496472,
|
|
7442
|
+
2058025392,
|
|
7443
|
+
1291430526,
|
|
7444
|
+
424198748,
|
|
7445
|
+
50039436,
|
|
7446
|
+
29584100,
|
|
7447
|
+
3605783033,
|
|
7448
|
+
2429876329,
|
|
7449
|
+
2791104160,
|
|
7450
|
+
1057563949,
|
|
7451
|
+
3255363231,
|
|
7452
|
+
3075367218,
|
|
7453
|
+
3463963227,
|
|
7454
|
+
1469046755,
|
|
7455
|
+
985887462
|
|
7456
|
+
];
|
|
7457
|
+
var C_ORIG = [
|
|
7458
|
+
1332899944,
|
|
7459
|
+
1700884034,
|
|
7460
|
+
1701343084,
|
|
7461
|
+
1684370003,
|
|
7462
|
+
1668446532,
|
|
7463
|
+
1869963892
|
|
7464
|
+
];
|
|
7465
|
+
function _encipher(lr, off, P, S) {
|
|
7466
|
+
var n, l = lr[off], r = lr[off + 1];
|
|
7467
|
+
l ^= P[0];
|
|
7468
|
+
n = S[l >>> 24];
|
|
7469
|
+
n += S[256 | l >> 16 & 255];
|
|
7470
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7471
|
+
n += S[768 | l & 255];
|
|
7472
|
+
r ^= n ^ P[1];
|
|
7473
|
+
n = S[r >>> 24];
|
|
7474
|
+
n += S[256 | r >> 16 & 255];
|
|
7475
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7476
|
+
n += S[768 | r & 255];
|
|
7477
|
+
l ^= n ^ P[2];
|
|
7478
|
+
n = S[l >>> 24];
|
|
7479
|
+
n += S[256 | l >> 16 & 255];
|
|
7480
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7481
|
+
n += S[768 | l & 255];
|
|
7482
|
+
r ^= n ^ P[3];
|
|
7483
|
+
n = S[r >>> 24];
|
|
7484
|
+
n += S[256 | r >> 16 & 255];
|
|
7485
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7486
|
+
n += S[768 | r & 255];
|
|
7487
|
+
l ^= n ^ P[4];
|
|
7488
|
+
n = S[l >>> 24];
|
|
7489
|
+
n += S[256 | l >> 16 & 255];
|
|
7490
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7491
|
+
n += S[768 | l & 255];
|
|
7492
|
+
r ^= n ^ P[5];
|
|
7493
|
+
n = S[r >>> 24];
|
|
7494
|
+
n += S[256 | r >> 16 & 255];
|
|
7495
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7496
|
+
n += S[768 | r & 255];
|
|
7497
|
+
l ^= n ^ P[6];
|
|
7498
|
+
n = S[l >>> 24];
|
|
7499
|
+
n += S[256 | l >> 16 & 255];
|
|
7500
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7501
|
+
n += S[768 | l & 255];
|
|
7502
|
+
r ^= n ^ P[7];
|
|
7503
|
+
n = S[r >>> 24];
|
|
7504
|
+
n += S[256 | r >> 16 & 255];
|
|
7505
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7506
|
+
n += S[768 | r & 255];
|
|
7507
|
+
l ^= n ^ P[8];
|
|
7508
|
+
n = S[l >>> 24];
|
|
7509
|
+
n += S[256 | l >> 16 & 255];
|
|
7510
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7511
|
+
n += S[768 | l & 255];
|
|
7512
|
+
r ^= n ^ P[9];
|
|
7513
|
+
n = S[r >>> 24];
|
|
7514
|
+
n += S[256 | r >> 16 & 255];
|
|
7515
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7516
|
+
n += S[768 | r & 255];
|
|
7517
|
+
l ^= n ^ P[10];
|
|
7518
|
+
n = S[l >>> 24];
|
|
7519
|
+
n += S[256 | l >> 16 & 255];
|
|
7520
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7521
|
+
n += S[768 | l & 255];
|
|
7522
|
+
r ^= n ^ P[11];
|
|
7523
|
+
n = S[r >>> 24];
|
|
7524
|
+
n += S[256 | r >> 16 & 255];
|
|
7525
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7526
|
+
n += S[768 | r & 255];
|
|
7527
|
+
l ^= n ^ P[12];
|
|
7528
|
+
n = S[l >>> 24];
|
|
7529
|
+
n += S[256 | l >> 16 & 255];
|
|
7530
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7531
|
+
n += S[768 | l & 255];
|
|
7532
|
+
r ^= n ^ P[13];
|
|
7533
|
+
n = S[r >>> 24];
|
|
7534
|
+
n += S[256 | r >> 16 & 255];
|
|
7535
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7536
|
+
n += S[768 | r & 255];
|
|
7537
|
+
l ^= n ^ P[14];
|
|
7538
|
+
n = S[l >>> 24];
|
|
7539
|
+
n += S[256 | l >> 16 & 255];
|
|
7540
|
+
n ^= S[512 | l >> 8 & 255];
|
|
7541
|
+
n += S[768 | l & 255];
|
|
7542
|
+
r ^= n ^ P[15];
|
|
7543
|
+
n = S[r >>> 24];
|
|
7544
|
+
n += S[256 | r >> 16 & 255];
|
|
7545
|
+
n ^= S[512 | r >> 8 & 255];
|
|
7546
|
+
n += S[768 | r & 255];
|
|
7547
|
+
l ^= n ^ P[16];
|
|
7548
|
+
lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
|
|
7549
|
+
lr[off + 1] = l;
|
|
7550
|
+
return lr;
|
|
7551
|
+
}
|
|
7552
|
+
function _streamtoword(data, offp) {
|
|
7553
|
+
for (var i = 0, word = 0; i < 4; ++i)
|
|
7554
|
+
word = word << 8 | data[offp] & 255, offp = (offp + 1) % data.length;
|
|
7555
|
+
return { key: word, offp };
|
|
7556
|
+
}
|
|
7557
|
+
function _key(key, P, S) {
|
|
7558
|
+
var offset = 0, lr = [0, 0], plen = P.length, slen = S.length, sw;
|
|
7559
|
+
for (var i = 0; i < plen; i++)
|
|
7560
|
+
sw = _streamtoword(key, offset), offset = sw.offp, P[i] = P[i] ^ sw.key;
|
|
7561
|
+
for (i = 0; i < plen; i += 2)
|
|
7562
|
+
lr = _encipher(lr, 0, P, S), P[i] = lr[0], P[i + 1] = lr[1];
|
|
7563
|
+
for (i = 0; i < slen; i += 2)
|
|
7564
|
+
lr = _encipher(lr, 0, P, S), S[i] = lr[0], S[i + 1] = lr[1];
|
|
7565
|
+
}
|
|
7566
|
+
function _ekskey(data, key, P, S) {
|
|
7567
|
+
var offp = 0, lr = [0, 0], plen = P.length, slen = S.length, sw;
|
|
7568
|
+
for (var i = 0; i < plen; i++)
|
|
7569
|
+
sw = _streamtoword(key, offp), offp = sw.offp, P[i] = P[i] ^ sw.key;
|
|
7570
|
+
offp = 0;
|
|
7571
|
+
for (i = 0; i < plen; i += 2)
|
|
7572
|
+
sw = _streamtoword(data, offp), offp = sw.offp, lr[0] ^= sw.key, sw = _streamtoword(data, offp), offp = sw.offp, lr[1] ^= sw.key, lr = _encipher(lr, 0, P, S), P[i] = lr[0], P[i + 1] = lr[1];
|
|
7573
|
+
for (i = 0; i < slen; i += 2)
|
|
7574
|
+
sw = _streamtoword(data, offp), offp = sw.offp, lr[0] ^= sw.key, sw = _streamtoword(data, offp), offp = sw.offp, lr[1] ^= sw.key, lr = _encipher(lr, 0, P, S), S[i] = lr[0], S[i + 1] = lr[1];
|
|
7575
|
+
}
|
|
7576
|
+
function _crypt(b, salt, rounds, callback, progressCallback) {
|
|
7577
|
+
var cdata = C_ORIG.slice(), clen = cdata.length, err;
|
|
7578
|
+
if (rounds < 4 || rounds > 31) {
|
|
7579
|
+
err = Error("Illegal number of rounds (4-31): " + rounds);
|
|
7580
|
+
if (callback) {
|
|
7581
|
+
nextTick(callback.bind(this, err));
|
|
7582
|
+
return;
|
|
7583
|
+
} else
|
|
7584
|
+
throw err;
|
|
7585
|
+
}
|
|
7586
|
+
if (salt.length !== BCRYPT_SALT_LEN) {
|
|
7587
|
+
err = Error("Illegal salt length: " + salt.length + " != " + BCRYPT_SALT_LEN);
|
|
7588
|
+
if (callback) {
|
|
7589
|
+
nextTick(callback.bind(this, err));
|
|
7590
|
+
return;
|
|
7591
|
+
} else
|
|
7592
|
+
throw err;
|
|
7593
|
+
}
|
|
7594
|
+
rounds = 1 << rounds >>> 0;
|
|
7595
|
+
var P, S, i = 0, j;
|
|
7596
|
+
if (Int32Array) {
|
|
7597
|
+
P = new Int32Array(P_ORIG);
|
|
7598
|
+
S = new Int32Array(S_ORIG);
|
|
7599
|
+
} else {
|
|
7600
|
+
P = P_ORIG.slice();
|
|
7601
|
+
S = S_ORIG.slice();
|
|
7602
|
+
}
|
|
7603
|
+
_ekskey(salt, b, P, S);
|
|
7604
|
+
function next() {
|
|
7605
|
+
if (progressCallback)
|
|
7606
|
+
progressCallback(i / rounds);
|
|
7607
|
+
if (i < rounds) {
|
|
7608
|
+
var start = Date.now();
|
|
7609
|
+
for (; i < rounds; ) {
|
|
7610
|
+
i = i + 1;
|
|
7611
|
+
_key(b, P, S);
|
|
7612
|
+
_key(salt, P, S);
|
|
7613
|
+
if (Date.now() - start > MAX_EXECUTION_TIME)
|
|
7614
|
+
break;
|
|
7615
|
+
}
|
|
7616
|
+
} else {
|
|
7617
|
+
for (i = 0; i < 64; i++)
|
|
7618
|
+
for (j = 0; j < clen >> 1; j++)
|
|
7619
|
+
_encipher(cdata, j << 1, P, S);
|
|
7620
|
+
var ret = [];
|
|
7621
|
+
for (i = 0; i < clen; i++)
|
|
7622
|
+
ret.push((cdata[i] >> 24 & 255) >>> 0), ret.push((cdata[i] >> 16 & 255) >>> 0), ret.push((cdata[i] >> 8 & 255) >>> 0), ret.push((cdata[i] & 255) >>> 0);
|
|
7623
|
+
if (callback) {
|
|
7624
|
+
callback(null, ret);
|
|
7625
|
+
return;
|
|
7626
|
+
} else
|
|
7627
|
+
return ret;
|
|
7628
|
+
}
|
|
7629
|
+
if (callback)
|
|
7630
|
+
nextTick(next);
|
|
7631
|
+
}
|
|
7632
|
+
if (typeof callback !== "undefined") {
|
|
7633
|
+
next();
|
|
7634
|
+
} else {
|
|
7635
|
+
var res;
|
|
7636
|
+
while (true)
|
|
7637
|
+
if (typeof (res = next()) !== "undefined")
|
|
7638
|
+
return res || [];
|
|
7639
|
+
}
|
|
7640
|
+
}
|
|
7641
|
+
function _hash(s, salt, callback, progressCallback) {
|
|
7642
|
+
var err;
|
|
7643
|
+
if (typeof s !== "string" || typeof salt !== "string") {
|
|
7644
|
+
err = Error("Invalid string / salt: Not a string");
|
|
7645
|
+
if (callback) {
|
|
7646
|
+
nextTick(callback.bind(this, err));
|
|
7647
|
+
return;
|
|
7648
|
+
} else
|
|
7649
|
+
throw err;
|
|
7650
|
+
}
|
|
7651
|
+
var minor, offset;
|
|
7652
|
+
if (salt.charAt(0) !== "$" || salt.charAt(1) !== "2") {
|
|
7653
|
+
err = Error("Invalid salt version: " + salt.substring(0, 2));
|
|
7654
|
+
if (callback) {
|
|
7655
|
+
nextTick(callback.bind(this, err));
|
|
7656
|
+
return;
|
|
7657
|
+
} else
|
|
7658
|
+
throw err;
|
|
7659
|
+
}
|
|
7660
|
+
if (salt.charAt(2) === "$")
|
|
7661
|
+
minor = String.fromCharCode(0), offset = 3;
|
|
7662
|
+
else {
|
|
7663
|
+
minor = salt.charAt(2);
|
|
7664
|
+
if (minor !== "a" && minor !== "b" && minor !== "y" || salt.charAt(3) !== "$") {
|
|
7665
|
+
err = Error("Invalid salt revision: " + salt.substring(2, 4));
|
|
7666
|
+
if (callback) {
|
|
7667
|
+
nextTick(callback.bind(this, err));
|
|
7668
|
+
return;
|
|
7669
|
+
} else
|
|
7670
|
+
throw err;
|
|
5050
7671
|
}
|
|
5051
|
-
|
|
5052
|
-
ctx.body = {
|
|
5053
|
-
success: true,
|
|
5054
|
-
message: "Demo data generated successfully",
|
|
5055
|
-
data: result
|
|
5056
|
-
};
|
|
5057
|
-
} catch (error) {
|
|
5058
|
-
strapi.log.error(`[${PLUGIN_ID}] Demo generation failed:`, error);
|
|
5059
|
-
ctx.badRequest("Failed to generate demo data", {
|
|
5060
|
-
error: error.message,
|
|
5061
|
-
details: error.stack
|
|
5062
|
-
});
|
|
7672
|
+
offset = 4;
|
|
5063
7673
|
}
|
|
5064
|
-
|
|
5065
|
-
|
|
7674
|
+
if (salt.charAt(offset + 2) > "$") {
|
|
7675
|
+
err = Error("Missing salt rounds");
|
|
7676
|
+
if (callback) {
|
|
7677
|
+
nextTick(callback.bind(this, err));
|
|
7678
|
+
return;
|
|
7679
|
+
} else
|
|
7680
|
+
throw err;
|
|
7681
|
+
}
|
|
7682
|
+
var r1 = parseInt(salt.substring(offset, offset + 1), 10) * 10, r2 = parseInt(salt.substring(offset + 1, offset + 2), 10), rounds = r1 + r2, real_salt = salt.substring(offset + 3, offset + 25);
|
|
7683
|
+
s += minor >= "a" ? "\0" : "";
|
|
7684
|
+
var passwordb = stringToBytes(s), saltb = base64_decode(real_salt, BCRYPT_SALT_LEN);
|
|
7685
|
+
function finish(bytes) {
|
|
7686
|
+
var res = [];
|
|
7687
|
+
res.push("$2");
|
|
7688
|
+
if (minor >= "a")
|
|
7689
|
+
res.push(minor);
|
|
7690
|
+
res.push("$");
|
|
7691
|
+
if (rounds < 10)
|
|
7692
|
+
res.push("0");
|
|
7693
|
+
res.push(rounds.toString());
|
|
7694
|
+
res.push("$");
|
|
7695
|
+
res.push(base64_encode(saltb, saltb.length));
|
|
7696
|
+
res.push(base64_encode(bytes, C_ORIG.length * 4 - 1));
|
|
7697
|
+
return res.join("");
|
|
7698
|
+
}
|
|
7699
|
+
if (typeof callback == "undefined")
|
|
7700
|
+
return finish(_crypt(passwordb, saltb, rounds));
|
|
7701
|
+
else {
|
|
7702
|
+
_crypt(passwordb, saltb, rounds, function(err2, bytes) {
|
|
7703
|
+
if (err2)
|
|
7704
|
+
callback(err2, null);
|
|
7705
|
+
else
|
|
7706
|
+
callback(null, finish(bytes));
|
|
7707
|
+
}, progressCallback);
|
|
7708
|
+
}
|
|
7709
|
+
}
|
|
7710
|
+
bcrypt.encodeBase64 = base64_encode;
|
|
7711
|
+
bcrypt.decodeBase64 = base64_decode;
|
|
7712
|
+
return bcrypt;
|
|
7713
|
+
});
|
|
7714
|
+
}
|
|
7715
|
+
});
|
|
7716
|
+
|
|
7717
|
+
// node_modules/bcryptjs/index.js
|
|
7718
|
+
var require_bcryptjs = __commonJS({
|
|
7719
|
+
"node_modules/bcryptjs/index.js"(exports2, module2) {
|
|
7720
|
+
module2.exports = require_bcrypt();
|
|
5066
7721
|
}
|
|
5067
7722
|
});
|
|
5068
7723
|
|
|
@@ -16855,6 +19510,7 @@ var require_auth = __commonJS({
|
|
|
16855
19510
|
"server/src/controllers/auth.js"(exports2, module2) {
|
|
16856
19511
|
"use strict";
|
|
16857
19512
|
var PLUGIN_ID = "webbycommerce";
|
|
19513
|
+
var bcrypt = require_bcryptjs();
|
|
16858
19514
|
var { sendEmail } = require_send_email();
|
|
16859
19515
|
var { ensureEcommercePermission } = require_check_ecommerce_permission();
|
|
16860
19516
|
var getStore = () => {
|
|
@@ -17245,6 +19901,547 @@ var require_auth = __commonJS({
|
|
|
17245
19901
|
ctx.internalServerError("Failed to verify OTP. Please try again.");
|
|
17246
19902
|
}
|
|
17247
19903
|
},
|
|
19904
|
+
/**
|
|
19905
|
+
* Get current authentication method
|
|
19906
|
+
* Returns which authentication method is currently enabled (default or otp)
|
|
19907
|
+
* This endpoint is public and can be used by frontend to determine which auth flow to use
|
|
19908
|
+
*/
|
|
19909
|
+
async getAuthMethod(ctx) {
|
|
19910
|
+
try {
|
|
19911
|
+
const method = await getLoginMethod();
|
|
19912
|
+
ctx.send({
|
|
19913
|
+
method,
|
|
19914
|
+
message: `Current authentication method: ${method}`
|
|
19915
|
+
});
|
|
19916
|
+
} catch (error) {
|
|
19917
|
+
strapi.log.error(`[${PLUGIN_ID}] Error in getAuthMethod:`, error);
|
|
19918
|
+
ctx.send({
|
|
19919
|
+
method: "default",
|
|
19920
|
+
message: "Current authentication method: default"
|
|
19921
|
+
});
|
|
19922
|
+
}
|
|
19923
|
+
},
|
|
19924
|
+
/**
|
|
19925
|
+
* Unified Login/Register endpoint
|
|
19926
|
+
* Supports both OTP and default (email/password) authentication methods
|
|
19927
|
+
* Automatically detects which method to use based on request body
|
|
19928
|
+
*
|
|
19929
|
+
* For OTP method:
|
|
19930
|
+
* - First call: Send email/mobile to receive OTP (step: 'request')
|
|
19931
|
+
* - Second call: Verify OTP to complete login (step: 'verify')
|
|
19932
|
+
*
|
|
19933
|
+
* For Default method:
|
|
19934
|
+
* - Single call: Send email/username and password to login
|
|
19935
|
+
* - Register: Send username, email, and password to register
|
|
19936
|
+
*/
|
|
19937
|
+
async unifiedAuth(ctx) {
|
|
19938
|
+
try {
|
|
19939
|
+
const hasPermission = await ensureEcommercePermission(ctx);
|
|
19940
|
+
if (!hasPermission) {
|
|
19941
|
+
return;
|
|
19942
|
+
}
|
|
19943
|
+
if (!ctx.request.body || typeof ctx.request.body !== "object") {
|
|
19944
|
+
return ctx.badRequest("Request body is required. Please provide authentication credentials.");
|
|
19945
|
+
}
|
|
19946
|
+
const {
|
|
19947
|
+
step,
|
|
19948
|
+
// 'request' or 'verify' for OTP, 'login' or 'register' for default
|
|
19949
|
+
authMethod,
|
|
19950
|
+
// 'otp' or 'default' (optional, auto-detected if not provided)
|
|
19951
|
+
// OTP fields
|
|
19952
|
+
email,
|
|
19953
|
+
mobile,
|
|
19954
|
+
type,
|
|
19955
|
+
// 'email' or 'mobile' for OTP
|
|
19956
|
+
otp,
|
|
19957
|
+
// OTP code for verification
|
|
19958
|
+
// Default fields
|
|
19959
|
+
identifier,
|
|
19960
|
+
// email or username for default login
|
|
19961
|
+
password,
|
|
19962
|
+
// password for default login
|
|
19963
|
+
username
|
|
19964
|
+
// username for default register
|
|
19965
|
+
} = ctx.request.body;
|
|
19966
|
+
strapi.log.debug(`[${PLUGIN_ID}] Unified auth request:`, {
|
|
19967
|
+
step,
|
|
19968
|
+
authMethod,
|
|
19969
|
+
hasEmail: !!email,
|
|
19970
|
+
hasMobile: !!mobile,
|
|
19971
|
+
hasType: !!type,
|
|
19972
|
+
hasOtp: !!otp,
|
|
19973
|
+
hasIdentifier: !!identifier,
|
|
19974
|
+
hasPassword: !!password,
|
|
19975
|
+
hasUsername: !!username
|
|
19976
|
+
});
|
|
19977
|
+
const configuredMethod = await getLoginMethod();
|
|
19978
|
+
let detectedMethod = authMethod;
|
|
19979
|
+
if (!detectedMethod) {
|
|
19980
|
+
if ((email || mobile) && type) {
|
|
19981
|
+
detectedMethod = "otp";
|
|
19982
|
+
} else if (identifier && password || username && email && password) {
|
|
19983
|
+
detectedMethod = "default";
|
|
19984
|
+
} else {
|
|
19985
|
+
detectedMethod = configuredMethod;
|
|
19986
|
+
}
|
|
19987
|
+
}
|
|
19988
|
+
if (configuredMethod !== "both") {
|
|
19989
|
+
if (detectedMethod === "otp" && configuredMethod !== "otp") {
|
|
19990
|
+
return ctx.badRequest("OTP authentication is not enabled. Please enable it in plugin settings or use the unified endpoint.");
|
|
19991
|
+
}
|
|
19992
|
+
if (detectedMethod === "default" && configuredMethod !== "default") {
|
|
19993
|
+
return ctx.badRequest("Default authentication is not enabled. Please enable it in plugin settings or use the unified endpoint.");
|
|
19994
|
+
}
|
|
19995
|
+
}
|
|
19996
|
+
if (detectedMethod === "otp") {
|
|
19997
|
+
if (step === "request" || !step && !otp) {
|
|
19998
|
+
let normalizedEmail = email?.toLowerCase();
|
|
19999
|
+
if (!type || type !== "email" && type !== "mobile") {
|
|
20000
|
+
return ctx.badRequest('Type must be "email" or "mobile" for OTP authentication.');
|
|
20001
|
+
}
|
|
20002
|
+
let identifier2 = type === "email" ? normalizedEmail : mobile;
|
|
20003
|
+
if (!identifier2) {
|
|
20004
|
+
return ctx.badRequest(
|
|
20005
|
+
`${type === "email" ? "Email" : "Mobile number"} is required.`
|
|
20006
|
+
);
|
|
20007
|
+
}
|
|
20008
|
+
let user = await strapi.db.query("plugin::users-permissions.user").findOne({
|
|
20009
|
+
where: type === "email" ? { email: normalizedEmail } : { phone_no: mobile }
|
|
20010
|
+
});
|
|
20011
|
+
let isNewUser = false;
|
|
20012
|
+
if (!user) {
|
|
20013
|
+
let generatedUsername = "";
|
|
20014
|
+
if (type === "email" && email) {
|
|
20015
|
+
let base = email.split("@")[0].replace(/[^a-zA-Z]/g, "").toLowerCase();
|
|
20016
|
+
if (!base) base = "user";
|
|
20017
|
+
base = base.substring(0, 4);
|
|
20018
|
+
const digitsNeeded = 8 - base.length;
|
|
20019
|
+
const min = Math.pow(10, digitsNeeded - 1);
|
|
20020
|
+
const max = Math.pow(10, digitsNeeded) - 1;
|
|
20021
|
+
let randomDigits = String(Math.floor(Math.random() * (max - min + 1)) + min);
|
|
20022
|
+
generatedUsername = (base + randomDigits).substring(0, 8);
|
|
20023
|
+
} else if (type === "mobile" && mobile) {
|
|
20024
|
+
const prefix = "webby";
|
|
20025
|
+
const randomDigits = String(Math.floor(100 + Math.random() * 900));
|
|
20026
|
+
generatedUsername = prefix + randomDigits;
|
|
20027
|
+
} else {
|
|
20028
|
+
generatedUsername = "user" + String(Math.floor(1e3 + Math.random() * 9e3));
|
|
20029
|
+
}
|
|
20030
|
+
const existing = await strapi.db.query("plugin::users-permissions.user").findOne({
|
|
20031
|
+
where: { username: generatedUsername }
|
|
20032
|
+
});
|
|
20033
|
+
if (existing) {
|
|
20034
|
+
if (type === "mobile") {
|
|
20035
|
+
generatedUsername = "webby" + String(Math.floor(100 + Math.random() * 900));
|
|
20036
|
+
} else {
|
|
20037
|
+
generatedUsername = generatedUsername.substring(0, 4) + String(Math.floor(1e3 + Math.random() * 9e3));
|
|
20038
|
+
generatedUsername = generatedUsername.substring(0, 8);
|
|
20039
|
+
}
|
|
20040
|
+
}
|
|
20041
|
+
const defaultRole = await strapi.db.query("plugin::users-permissions.role").findOne({ where: { type: "public" } });
|
|
20042
|
+
user = await strapi.plugin("users-permissions").service("user").add({
|
|
20043
|
+
email: type === "email" ? normalizedEmail : null,
|
|
20044
|
+
phone_no: type === "mobile" ? mobile : null,
|
|
20045
|
+
username: generatedUsername,
|
|
20046
|
+
confirmed: false,
|
|
20047
|
+
role: defaultRole?.id || 2
|
|
20048
|
+
});
|
|
20049
|
+
isNewUser = true;
|
|
20050
|
+
}
|
|
20051
|
+
const otpCode = Math.floor(1e5 + Math.random() * 9e5);
|
|
20052
|
+
const otpDigits = otpCode.toString().split("");
|
|
20053
|
+
try {
|
|
20054
|
+
const db = strapi.db;
|
|
20055
|
+
const knex = db.connection;
|
|
20056
|
+
const tableName = "up_users";
|
|
20057
|
+
const client = db.config.connection.client;
|
|
20058
|
+
if (client === "postgres") {
|
|
20059
|
+
await knex.raw(
|
|
20060
|
+
`UPDATE ${tableName} SET otp = ?, is_otp_verified = ? WHERE id = ?`,
|
|
20061
|
+
[otpCode, false, user.id]
|
|
20062
|
+
);
|
|
20063
|
+
} else if (client === "mysql" || client === "mysql2") {
|
|
20064
|
+
await knex.raw(
|
|
20065
|
+
`UPDATE \`${tableName}\` SET \`otp\` = ?, \`is_otp_verified\` = ? WHERE \`id\` = ?`,
|
|
20066
|
+
[otpCode, false, user.id]
|
|
20067
|
+
);
|
|
20068
|
+
} else {
|
|
20069
|
+
await knex.raw(
|
|
20070
|
+
`UPDATE ${tableName} SET otp = ?, is_otp_verified = ? WHERE id = ?`,
|
|
20071
|
+
[otpCode, false, user.id]
|
|
20072
|
+
);
|
|
20073
|
+
}
|
|
20074
|
+
} catch (err) {
|
|
20075
|
+
const { extendUserSchemaWithOtpFields } = require_extend_user_schema();
|
|
20076
|
+
await extendUserSchemaWithOtpFields(strapi);
|
|
20077
|
+
const db = strapi.db;
|
|
20078
|
+
const knex = db.connection;
|
|
20079
|
+
const tableName = "up_users";
|
|
20080
|
+
const client = db.config.connection.client;
|
|
20081
|
+
if (client === "postgres") {
|
|
20082
|
+
await knex.raw(
|
|
20083
|
+
`UPDATE ${tableName} SET otp = ?, is_otp_verified = ? WHERE id = ?`,
|
|
20084
|
+
[otpCode, false, user.id]
|
|
20085
|
+
);
|
|
20086
|
+
} else if (client === "mysql" || client === "mysql2") {
|
|
20087
|
+
await knex.raw(
|
|
20088
|
+
`UPDATE \`${tableName}\` SET \`otp\` = ?, \`is_otp_verified\` = ? WHERE \`id\` = ?`,
|
|
20089
|
+
[otpCode, false, user.id]
|
|
20090
|
+
);
|
|
20091
|
+
} else {
|
|
20092
|
+
await knex.raw(
|
|
20093
|
+
`UPDATE ${tableName} SET otp = ?, is_otp_verified = ? WHERE id = ?`,
|
|
20094
|
+
[otpCode, false, user.id]
|
|
20095
|
+
);
|
|
20096
|
+
}
|
|
20097
|
+
}
|
|
20098
|
+
let emailSent = false;
|
|
20099
|
+
if (type === "email") {
|
|
20100
|
+
const otpEmailHTML = `
|
|
20101
|
+
<!DOCTYPE html>
|
|
20102
|
+
<html lang="en">
|
|
20103
|
+
<head>
|
|
20104
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
20105
|
+
<meta charset="UTF-8" />
|
|
20106
|
+
<title>OTP Confirmation</title>
|
|
20107
|
+
</head>
|
|
20108
|
+
<body style="margin: 0; padding: 0; background-color: #f4f4f4; font-family: Arial, sans-serif;">
|
|
20109
|
+
<table align="center" width="100%" cellpadding="0" cellspacing="0" border="0" style="max-width: 650px; margin: 0 auto; background-color: #ffffff;">
|
|
20110
|
+
<tr>
|
|
20111
|
+
<td align="center" style="padding: 60px 20px 8px;">
|
|
20112
|
+
<h1 style="font-weight: bold; color: #111; font-size: 32px; margin: 0;">Your OTP Code for Secure Access</h1>
|
|
20113
|
+
</td>
|
|
20114
|
+
</tr>
|
|
20115
|
+
<tr>
|
|
20116
|
+
<td align="center" style="padding: 16px 30px;">
|
|
20117
|
+
<p style="font-size: 16px; color: #333333; line-height: 24px; margin: 0; max-width: 500px;">
|
|
20118
|
+
To complete your account verification, please use the One-Time Password (OTP) provided below. For security reasons, this OTP will expire in 10 minutes and can only be used once.
|
|
20119
|
+
</p>
|
|
20120
|
+
</td>
|
|
20121
|
+
</tr>
|
|
20122
|
+
<tr>
|
|
20123
|
+
<td align="center" style="padding: 30px 0;">
|
|
20124
|
+
<table cellpadding="0" cellspacing="0" border="0" style="margin: 0 auto;">
|
|
20125
|
+
<tr>
|
|
20126
|
+
<td style="padding: 0 6px;">
|
|
20127
|
+
<table cellpadding="0" cellspacing="0" border="0" style="width: 60px; height: 60px; border: 1px solid #0156D559; border-radius: 8px; background-color: #f8f9fa;">
|
|
20128
|
+
<tr>
|
|
20129
|
+
<td align="center" style="font-size: 28px; font-weight: bold; color: #111;">${otpDigits[0]}</td>
|
|
20130
|
+
</tr>
|
|
20131
|
+
</table>
|
|
20132
|
+
</td>
|
|
20133
|
+
<td style="padding: 0 6px;">
|
|
20134
|
+
<table cellpadding="0" cellspacing="0" border="0" style="width: 60px; height: 60px; border: 1px solid #0156D559; border-radius: 8px; background-color: #f8f9fa;">
|
|
20135
|
+
<tr>
|
|
20136
|
+
<td align="center" style="font-size: 28px; font-weight: bold; color: #111;">${otpDigits[1]}</td>
|
|
20137
|
+
</tr>
|
|
20138
|
+
</table>
|
|
20139
|
+
</td>
|
|
20140
|
+
<td style="padding: 0 6px;">
|
|
20141
|
+
<table cellpadding="0" cellspacing="0" border="0" style="width: 60px; height: 60px; border: 1px solid #0156D559; border-radius: 8px; background-color: #f8f9fa;">
|
|
20142
|
+
<tr>
|
|
20143
|
+
<td align="center" style="font-size: 28px; font-weight: bold; color: #111;">${otpDigits[2]}</td>
|
|
20144
|
+
</tr>
|
|
20145
|
+
</table>
|
|
20146
|
+
</td>
|
|
20147
|
+
<td style="padding: 0 6px;">
|
|
20148
|
+
<table cellpadding="0" cellspacing="0" border="0" style="width: 60px; height: 60px; border: 1px solid #0156D559; border-radius: 8px; background-color: #f8f9fa;">
|
|
20149
|
+
<tr>
|
|
20150
|
+
<td align="center" style="font-size: 28px; font-weight: bold; color: #111;">${otpDigits[3]}</td>
|
|
20151
|
+
</tr>
|
|
20152
|
+
</table>
|
|
20153
|
+
</td>
|
|
20154
|
+
<td style="padding: 0 6px;">
|
|
20155
|
+
<table cellpadding="0" cellspacing="0" border="0" style="width: 60px; height: 60px; border: 1px solid #0156D559; border-radius: 8px; background-color: #f8f9fa;">
|
|
20156
|
+
<tr>
|
|
20157
|
+
<td align="center" style="font-size: 28px; font-weight: bold; color: #111;">${otpDigits[4]}</td>
|
|
20158
|
+
</tr>
|
|
20159
|
+
</table>
|
|
20160
|
+
</td>
|
|
20161
|
+
<td style="padding: 0 6px;">
|
|
20162
|
+
<table cellpadding="0" cellspacing="0" border="0" style="width: 60px; height: 60px; border: 1px solid #0156D559; border-radius: 8px; background-color: #f8f9fa;">
|
|
20163
|
+
<tr>
|
|
20164
|
+
<td align="center" style="font-size: 28px; font-weight: bold; color: #111;">${otpDigits[5]}</td>
|
|
20165
|
+
</tr>
|
|
20166
|
+
</table>
|
|
20167
|
+
</td>
|
|
20168
|
+
</tr>
|
|
20169
|
+
</table>
|
|
20170
|
+
</td>
|
|
20171
|
+
</tr>
|
|
20172
|
+
</table>
|
|
20173
|
+
</body>
|
|
20174
|
+
</html>
|
|
20175
|
+
`;
|
|
20176
|
+
try {
|
|
20177
|
+
await sendEmail({
|
|
20178
|
+
to: email,
|
|
20179
|
+
subject: "Your OTP Code - Strapi WebbyCommerce",
|
|
20180
|
+
html: otpEmailHTML
|
|
20181
|
+
});
|
|
20182
|
+
emailSent = true;
|
|
20183
|
+
} catch (emailError) {
|
|
20184
|
+
strapi.log.error(
|
|
20185
|
+
`[${PLUGIN_ID}] Failed to send OTP email (userId: ${user.id}, email: ${email}):`,
|
|
20186
|
+
emailError
|
|
20187
|
+
);
|
|
20188
|
+
}
|
|
20189
|
+
} else if (type === "mobile") {
|
|
20190
|
+
strapi.log.info(`[${PLUGIN_ID}] OTP for mobile ${mobile}: ${otpCode}`);
|
|
20191
|
+
}
|
|
20192
|
+
ctx.send({
|
|
20193
|
+
success: true,
|
|
20194
|
+
step: "request",
|
|
20195
|
+
method: "otp",
|
|
20196
|
+
message: emailSent ? `OTP sent to ${type}.` : type === "email" ? "User created. OTP email could not be sent; please check email configuration on the server." : `OTP sent to ${type}.`,
|
|
20197
|
+
userId: user.id,
|
|
20198
|
+
isNewUser,
|
|
20199
|
+
emailSent,
|
|
20200
|
+
nextStep: "verify"
|
|
20201
|
+
});
|
|
20202
|
+
return;
|
|
20203
|
+
}
|
|
20204
|
+
if (step === "verify" || !step && otp) {
|
|
20205
|
+
if (!otp || !(type === "email" && email || type === "mobile" && mobile)) {
|
|
20206
|
+
return ctx.badRequest(
|
|
20207
|
+
`${type === "email" ? "Email" : "Mobile number"} and OTP are required.`
|
|
20208
|
+
);
|
|
20209
|
+
}
|
|
20210
|
+
const identifier2 = type === "email" ? email.toLowerCase() : mobile;
|
|
20211
|
+
const user = await strapi.db.query("plugin::users-permissions.user").findOne({
|
|
20212
|
+
where: { [type === "email" ? "email" : "phone_no"]: identifier2 }
|
|
20213
|
+
});
|
|
20214
|
+
if (!user) return ctx.badRequest("User not found.");
|
|
20215
|
+
const db = strapi.db;
|
|
20216
|
+
const knex = db.connection;
|
|
20217
|
+
const tableName = "up_users";
|
|
20218
|
+
const client = db.config.connection.client;
|
|
20219
|
+
let userOtpData;
|
|
20220
|
+
let columnsExist = false;
|
|
20221
|
+
try {
|
|
20222
|
+
if (client === "postgres") {
|
|
20223
|
+
const result = await knex.raw(
|
|
20224
|
+
`SELECT otp, is_otp_verified FROM ${tableName} WHERE id = ?`,
|
|
20225
|
+
[user.id]
|
|
20226
|
+
);
|
|
20227
|
+
userOtpData = result.rows[0];
|
|
20228
|
+
columnsExist = userOtpData && userOtpData.hasOwnProperty("otp") && userOtpData.hasOwnProperty("is_otp_verified");
|
|
20229
|
+
} else if (client === "mysql" || client === "mysql2") {
|
|
20230
|
+
const result = await knex.raw(
|
|
20231
|
+
`SELECT \`otp\`, \`is_otp_verified\` FROM \`${tableName}\` WHERE \`id\` = ?`,
|
|
20232
|
+
[user.id]
|
|
20233
|
+
);
|
|
20234
|
+
userOtpData = result[0][0];
|
|
20235
|
+
columnsExist = userOtpData && userOtpData.hasOwnProperty("otp") && userOtpData.hasOwnProperty("is_otp_verified");
|
|
20236
|
+
} else {
|
|
20237
|
+
const result = await knex.raw(
|
|
20238
|
+
`SELECT otp, is_otp_verified FROM ${tableName} WHERE id = ?`,
|
|
20239
|
+
[user.id]
|
|
20240
|
+
);
|
|
20241
|
+
userOtpData = result[0];
|
|
20242
|
+
columnsExist = userOtpData && userOtpData.hasOwnProperty("otp") && userOtpData.hasOwnProperty("is_otp_verified");
|
|
20243
|
+
}
|
|
20244
|
+
} catch (queryErr) {
|
|
20245
|
+
strapi.log.warn(`[${PLUGIN_ID}] OTP columns not found, attempting to add them:`, queryErr.message);
|
|
20246
|
+
columnsExist = false;
|
|
20247
|
+
}
|
|
20248
|
+
if (!columnsExist) {
|
|
20249
|
+
const { extendUserSchemaWithOtpFields } = require_extend_user_schema();
|
|
20250
|
+
await extendUserSchemaWithOtpFields(strapi);
|
|
20251
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
20252
|
+
try {
|
|
20253
|
+
if (client === "postgres") {
|
|
20254
|
+
const result = await knex.raw(
|
|
20255
|
+
`SELECT otp, is_otp_verified FROM ${tableName} WHERE id = ?`,
|
|
20256
|
+
[user.id]
|
|
20257
|
+
);
|
|
20258
|
+
userOtpData = result.rows[0];
|
|
20259
|
+
columnsExist = userOtpData && userOtpData.hasOwnProperty("otp") && userOtpData.hasOwnProperty("is_otp_verified");
|
|
20260
|
+
} else if (client === "mysql" || client === "mysql2") {
|
|
20261
|
+
const result = await knex.raw(
|
|
20262
|
+
`SELECT \`otp\`, \`is_otp_verified\` FROM \`${tableName}\` WHERE \`id\` = ?`,
|
|
20263
|
+
[user.id]
|
|
20264
|
+
);
|
|
20265
|
+
userOtpData = result[0][0];
|
|
20266
|
+
columnsExist = userOtpData && userOtpData.hasOwnProperty("otp") && userOtpData.hasOwnProperty("is_otp_verified");
|
|
20267
|
+
} else {
|
|
20268
|
+
const result = await knex.raw(
|
|
20269
|
+
`SELECT otp, is_otp_verified FROM ${tableName} WHERE id = ?`,
|
|
20270
|
+
[user.id]
|
|
20271
|
+
);
|
|
20272
|
+
userOtpData = result[0];
|
|
20273
|
+
columnsExist = userOtpData && userOtpData.hasOwnProperty("otp") && userOtpData.hasOwnProperty("is_otp_verified");
|
|
20274
|
+
}
|
|
20275
|
+
} catch (retryErr) {
|
|
20276
|
+
return ctx.badRequest(
|
|
20277
|
+
"OTP fields are not available. Please restart Strapi after extending the user schema."
|
|
20278
|
+
);
|
|
20279
|
+
}
|
|
20280
|
+
}
|
|
20281
|
+
const userOtp = userOtpData?.otp;
|
|
20282
|
+
const isOtpVerified = userOtpData?.is_otp_verified;
|
|
20283
|
+
if (isOtpVerified) return ctx.badRequest("User already verified.");
|
|
20284
|
+
if (userOtp !== parseInt(otp, 10)) return ctx.badRequest("Invalid OTP.");
|
|
20285
|
+
try {
|
|
20286
|
+
if (client === "postgres") {
|
|
20287
|
+
await knex.raw(
|
|
20288
|
+
`UPDATE ${tableName} SET is_otp_verified = ?, confirmed = true, otp = NULL WHERE id = ?`,
|
|
20289
|
+
[true, user.id]
|
|
20290
|
+
);
|
|
20291
|
+
} else if (client === "mysql" || client === "mysql2") {
|
|
20292
|
+
await knex.raw(
|
|
20293
|
+
`UPDATE \`${tableName}\` SET \`is_otp_verified\` = ?, \`confirmed\` = true, \`otp\` = NULL WHERE \`id\` = ?`,
|
|
20294
|
+
[true, user.id]
|
|
20295
|
+
);
|
|
20296
|
+
} else {
|
|
20297
|
+
await knex.raw(
|
|
20298
|
+
`UPDATE ${tableName} SET is_otp_verified = ?, confirmed = 1, otp = NULL WHERE id = ?`,
|
|
20299
|
+
[true, user.id]
|
|
20300
|
+
);
|
|
20301
|
+
}
|
|
20302
|
+
} catch (dbErr) {
|
|
20303
|
+
strapi.log.error(`[${PLUGIN_ID}] Database error during OTP verification:`, dbErr);
|
|
20304
|
+
return ctx.badRequest(
|
|
20305
|
+
"OTP fields are not available in the user schema. Please extend the user schema as described in the plugin README."
|
|
20306
|
+
);
|
|
20307
|
+
}
|
|
20308
|
+
const jwt = strapi.plugins["users-permissions"].services.jwt.issue({
|
|
20309
|
+
id: user.id
|
|
20310
|
+
});
|
|
20311
|
+
ctx.send({
|
|
20312
|
+
success: true,
|
|
20313
|
+
step: "verify",
|
|
20314
|
+
method: "otp",
|
|
20315
|
+
message: "Login successfully!",
|
|
20316
|
+
jwt,
|
|
20317
|
+
user: {
|
|
20318
|
+
id: user.id,
|
|
20319
|
+
username: user.username,
|
|
20320
|
+
email: user.email,
|
|
20321
|
+
phone_no: user.phone_no
|
|
20322
|
+
}
|
|
20323
|
+
});
|
|
20324
|
+
return;
|
|
20325
|
+
}
|
|
20326
|
+
return ctx.badRequest('Invalid step for OTP authentication. Use "request" or "verify".');
|
|
20327
|
+
}
|
|
20328
|
+
if (detectedMethod === "default") {
|
|
20329
|
+
if (step === "login" || !step && identifier && password) {
|
|
20330
|
+
if (!identifier || !password) {
|
|
20331
|
+
return ctx.badRequest("Identifier (email/username) and password are required for login.");
|
|
20332
|
+
}
|
|
20333
|
+
const userService = strapi.plugin("users-permissions").service("user");
|
|
20334
|
+
const jwt = strapi.plugins["users-permissions"].services.jwt;
|
|
20335
|
+
const user = await strapi.db.query("plugin::users-permissions.user").findOne({
|
|
20336
|
+
where: {
|
|
20337
|
+
$or: [
|
|
20338
|
+
{ email: identifier.toLowerCase() },
|
|
20339
|
+
{ username: identifier }
|
|
20340
|
+
]
|
|
20341
|
+
},
|
|
20342
|
+
populate: ["role"]
|
|
20343
|
+
});
|
|
20344
|
+
if (!user) {
|
|
20345
|
+
return ctx.badRequest("Invalid identifier or password.");
|
|
20346
|
+
}
|
|
20347
|
+
if (!user.password) {
|
|
20348
|
+
return ctx.badRequest("Invalid identifier or password.");
|
|
20349
|
+
}
|
|
20350
|
+
const validPassword = await bcrypt.compare(password, user.password);
|
|
20351
|
+
if (!validPassword) {
|
|
20352
|
+
return ctx.badRequest("Invalid identifier or password.");
|
|
20353
|
+
}
|
|
20354
|
+
if (user.blocked) {
|
|
20355
|
+
return ctx.badRequest("Your account has been blocked.");
|
|
20356
|
+
}
|
|
20357
|
+
const token = jwt.issue({
|
|
20358
|
+
id: user.id
|
|
20359
|
+
});
|
|
20360
|
+
ctx.send({
|
|
20361
|
+
success: true,
|
|
20362
|
+
step: "login",
|
|
20363
|
+
method: "default",
|
|
20364
|
+
message: "Login successfully!",
|
|
20365
|
+
jwt: token,
|
|
20366
|
+
user: {
|
|
20367
|
+
id: user.id,
|
|
20368
|
+
username: user.username,
|
|
20369
|
+
email: user.email,
|
|
20370
|
+
phone_no: user.phone_no,
|
|
20371
|
+
role: user.role ? {
|
|
20372
|
+
id: user.role.id,
|
|
20373
|
+
name: user.role.name,
|
|
20374
|
+
type: user.role.type
|
|
20375
|
+
} : null
|
|
20376
|
+
}
|
|
20377
|
+
});
|
|
20378
|
+
return;
|
|
20379
|
+
}
|
|
20380
|
+
if (step === "register" || !step && username && email && password) {
|
|
20381
|
+
if (!username || !email || !password) {
|
|
20382
|
+
return ctx.badRequest("Username, email, and password are required for registration.");
|
|
20383
|
+
}
|
|
20384
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
20385
|
+
if (!emailRegex.test(email.trim())) {
|
|
20386
|
+
return ctx.badRequest("Invalid email format.");
|
|
20387
|
+
}
|
|
20388
|
+
const existingUser = await strapi.db.query("plugin::users-permissions.user").findOne({
|
|
20389
|
+
where: {
|
|
20390
|
+
$or: [
|
|
20391
|
+
{ email: email.toLowerCase() },
|
|
20392
|
+
{ username }
|
|
20393
|
+
]
|
|
20394
|
+
}
|
|
20395
|
+
});
|
|
20396
|
+
if (existingUser) {
|
|
20397
|
+
return ctx.badRequest("Email or username already exists.");
|
|
20398
|
+
}
|
|
20399
|
+
const defaultRole = await strapi.db.query("plugin::users-permissions.role").findOne({ where: { type: "public" } });
|
|
20400
|
+
const user = await strapi.plugin("users-permissions").service("user").add({
|
|
20401
|
+
username: username.trim(),
|
|
20402
|
+
email: email.trim().toLowerCase(),
|
|
20403
|
+
password,
|
|
20404
|
+
confirmed: true,
|
|
20405
|
+
// Auto-confirm for default method
|
|
20406
|
+
role: defaultRole?.id || 2
|
|
20407
|
+
});
|
|
20408
|
+
const jwt = strapi.plugins["users-permissions"].services.jwt.issue({
|
|
20409
|
+
id: user.id
|
|
20410
|
+
});
|
|
20411
|
+
ctx.send({
|
|
20412
|
+
success: true,
|
|
20413
|
+
step: "register",
|
|
20414
|
+
method: "default",
|
|
20415
|
+
message: "Registration successful!",
|
|
20416
|
+
jwt,
|
|
20417
|
+
user: {
|
|
20418
|
+
id: user.id,
|
|
20419
|
+
username: user.username,
|
|
20420
|
+
email: user.email,
|
|
20421
|
+
role: user.role ? {
|
|
20422
|
+
id: user.role.id,
|
|
20423
|
+
name: user.role.name,
|
|
20424
|
+
type: user.role.type
|
|
20425
|
+
} : null
|
|
20426
|
+
}
|
|
20427
|
+
});
|
|
20428
|
+
return;
|
|
20429
|
+
}
|
|
20430
|
+
return ctx.badRequest('Invalid step for default authentication. Use "login" or "register".');
|
|
20431
|
+
}
|
|
20432
|
+
return ctx.badRequest(
|
|
20433
|
+
'Invalid request. Please provide valid authentication credentials. For OTP: provide step="request" with email/mobile and type, or step="verify" with OTP code. For default: provide step="login" with identifier and password, or step="register" with username, email, and password.'
|
|
20434
|
+
);
|
|
20435
|
+
} catch (error) {
|
|
20436
|
+
strapi.log.error(`[${PLUGIN_ID}] Error in unifiedAuth:`, error);
|
|
20437
|
+
strapi.log.error(`[${PLUGIN_ID}] Error stack:`, error.stack);
|
|
20438
|
+
strapi.log.error(`[${PLUGIN_ID}] Request body:`, JSON.stringify(ctx.request.body, null, 2));
|
|
20439
|
+
if (error.message) {
|
|
20440
|
+
return ctx.internalServerError(`Authentication failed: ${error.message}`);
|
|
20441
|
+
}
|
|
20442
|
+
ctx.internalServerError("Authentication failed. Please try again.");
|
|
20443
|
+
}
|
|
20444
|
+
},
|
|
17248
20445
|
/**
|
|
17249
20446
|
* Get authenticated user profile
|
|
17250
20447
|
* Returns all user details for the authenticated user
|
|
@@ -17382,7 +20579,10 @@ var require_auth = __commonJS({
|
|
|
17382
20579
|
if (!currentUser) {
|
|
17383
20580
|
return ctx.notFound("User not found.");
|
|
17384
20581
|
}
|
|
17385
|
-
|
|
20582
|
+
if (!currentUser.password) {
|
|
20583
|
+
return ctx.badRequest("Current password is incorrect.");
|
|
20584
|
+
}
|
|
20585
|
+
const validPassword = await bcrypt.compare(currentPassword, currentUser.password);
|
|
17386
20586
|
if (!validPassword) {
|
|
17387
20587
|
return ctx.badRequest("Current password is incorrect.");
|
|
17388
20588
|
}
|
|
@@ -21376,7 +24576,7 @@ var require_shipping = __commonJS({
|
|
|
21376
24576
|
availableMethods = availableMethods.concat(methods);
|
|
21377
24577
|
}
|
|
21378
24578
|
const uniqueMethods = availableMethods.filter(
|
|
21379
|
-
(method, index,
|
|
24579
|
+
(method, index, self2) => index === self2.findIndex((m) => String(m.id) === String(method.id))
|
|
21380
24580
|
);
|
|
21381
24581
|
const methodsWithCosts = [];
|
|
21382
24582
|
for (const method of uniqueMethods) {
|
|
@@ -21413,7 +24613,7 @@ var require_shipping = __commonJS({
|
|
|
21413
24613
|
}
|
|
21414
24614
|
const finalMethods = await applyShippingRules(methodsWithCosts, cart_items, shipping_address);
|
|
21415
24615
|
const uniqueFinalMethods = finalMethods.filter(
|
|
21416
|
-
(method, index,
|
|
24616
|
+
(method, index, self2) => index === self2.findIndex((m) => String(m.id) === String(method.id))
|
|
21417
24617
|
);
|
|
21418
24618
|
ctx.send({
|
|
21419
24619
|
data: uniqueFinalMethods,
|
|
@@ -23457,7 +26657,7 @@ var require_shipping2 = __commonJS({
|
|
|
23457
26657
|
availableMethods = availableMethods.concat(methods);
|
|
23458
26658
|
}
|
|
23459
26659
|
const uniqueMethods = availableMethods.filter(
|
|
23460
|
-
(method, index,
|
|
26660
|
+
(method, index, self2) => index === self2.findIndex((m) => String(m.id) === String(method.id))
|
|
23461
26661
|
);
|
|
23462
26662
|
const methodsWithCosts = [];
|
|
23463
26663
|
for (const method of uniqueMethods) {
|
|
@@ -23494,7 +26694,7 @@ var require_shipping2 = __commonJS({
|
|
|
23494
26694
|
}
|
|
23495
26695
|
const finalMethods = await this.applyShippingRules(methodsWithCosts, cartItems, shippingAddress);
|
|
23496
26696
|
const uniqueFinalMethods = finalMethods.filter(
|
|
23497
|
-
(method, index,
|
|
26697
|
+
(method, index, self2) => index === self2.findIndex((m) => String(m.id) === String(method.id))
|
|
23498
26698
|
);
|
|
23499
26699
|
return {
|
|
23500
26700
|
methods: uniqueFinalMethods,
|
|
@@ -23867,3 +27067,12 @@ module.exports = {
|
|
|
23867
27067
|
routes,
|
|
23868
27068
|
services
|
|
23869
27069
|
};
|
|
27070
|
+
/*! Bundled license information:
|
|
27071
|
+
|
|
27072
|
+
bcryptjs/dist/bcrypt.js:
|
|
27073
|
+
(**
|
|
27074
|
+
* @license bcrypt.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
|
|
27075
|
+
* Released under the Apache License, Version 2.0
|
|
27076
|
+
* see: https://github.com/dcodeIO/bcrypt.js for details
|
|
27077
|
+
*)
|
|
27078
|
+
*/
|