@infuro/cms-core 1.0.47 → 1.0.50
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 +30 -16
- package/dist/admin.cjs +1172 -38
- package/dist/admin.js +1173 -39
- package/dist/api.cjs +37 -37
- package/dist/api.js +5 -5
- package/dist/auth.cjs +52 -23
- package/dist/auth.d.cts +101 -2
- package/dist/auth.d.ts +101 -2
- package/dist/auth.js +3 -2
- package/dist/chunk-3EOM4V2M.cjs +452 -0
- package/dist/{chunk-2HU5R2JE.js → chunk-AYERBA7I.js} +1 -7
- package/dist/{chunk-YXH2UUEZ.js → chunk-IPDHT2UV.js} +257 -16
- package/dist/{chunk-XUCKZPML.cjs → chunk-JCMOOPNX.cjs} +2696 -2601
- package/dist/{chunk-W42UZLQO.js → chunk-LT2WOPKA.js} +2642 -2540
- package/dist/chunk-RK5ETF2I.js +434 -0
- package/dist/{chunk-4PMK3RNA.cjs → chunk-TJ2MIQUT.cjs} +1 -7
- package/dist/{chunk-LMJ7RKPF.cjs → chunk-UUWAUHUW.cjs} +279 -16
- package/dist/{chunk-YC4NUZCS.js → chunk-WRKV6MHB.js} +414 -2
- package/dist/{chunk-Q3HQEM4R.cjs → chunk-YV5PK4JW.cjs} +421 -1
- package/dist/cli.cjs +13 -22
- package/dist/cli.js +13 -22
- package/dist/{event-order-defaults-7Z3UZOEH.cjs → event-order-defaults-DU7V3YND.cjs} +9 -9
- package/dist/{event-order-defaults-XQ3IDPD7.js → event-order-defaults-H4RT7NMR.js} +1 -1
- package/dist/index.cjs +327 -291
- package/dist/index.d.cts +132 -5
- package/dist/index.d.ts +132 -5
- package/dist/index.js +8 -8
- package/dist/migrations/1782400000000-CreateUserDeviceTokens.ts +36 -0
- package/dist/migrations/1782500000000-AddPushToOrderNotificationBindingsChannelEnum.ts +15 -0
- package/dist/{order-notification-dispatcher-6WNG24NY.js → order-notification-dispatcher-3TA4ETYJ.js} +1 -1
- package/dist/{order-notification-dispatcher-6XSU3AR7.cjs → order-notification-dispatcher-ZEAZ5SHV.cjs} +7 -3
- package/package.json +1 -1
- package/dist/chunk-VUQFARRT.cjs +0 -182
- package/dist/chunk-ZF2RQWXB.js +0 -171
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var chunk3EOM4V2M_cjs = require('./chunk-3EOM4V2M.cjs');
|
|
4
|
+
var chunkOY2YTBMP_cjs = require('./chunk-OY2YTBMP.cjs');
|
|
3
5
|
var chunk77NUXO6A_cjs = require('./chunk-77NUXO6A.cjs');
|
|
4
6
|
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
5
7
|
var jwt = require('next-auth/jwt');
|
|
6
8
|
var _CredentialsProvider = require('next-auth/providers/credentials');
|
|
9
|
+
var _GoogleProvider = require('next-auth/providers/google');
|
|
7
10
|
|
|
8
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
12
|
|
|
10
13
|
var _CredentialsProvider__default = /*#__PURE__*/_interopDefault(_CredentialsProvider);
|
|
14
|
+
var _GoogleProvider__default = /*#__PURE__*/_interopDefault(_GoogleProvider);
|
|
11
15
|
|
|
12
16
|
// src/auth/seed-permissions.ts
|
|
13
17
|
async function seedAdministratorPermissions(dataSource, entityMap) {
|
|
@@ -135,6 +139,10 @@ var defaultPublicApiMethods = {
|
|
|
135
139
|
"/api/users/invite": [
|
|
136
140
|
"GET",
|
|
137
141
|
"POST"
|
|
142
|
+
],
|
|
143
|
+
/** Public keys only (e.g. googleEnabled); secrets stay private in the settings handler. */
|
|
144
|
+
"/api/settings/auth_providers": [
|
|
145
|
+
"GET"
|
|
138
146
|
]
|
|
139
147
|
};
|
|
140
148
|
function legacyGetSessionToken(request) {
|
|
@@ -240,7 +248,281 @@ function createCmsMiddleware(config = {}) {
|
|
|
240
248
|
}, "cmsMiddleware");
|
|
241
249
|
}
|
|
242
250
|
chunkUSNT2KNT_cjs.__name(createCmsMiddleware, "createCmsMiddleware");
|
|
251
|
+
|
|
252
|
+
// src/auth/auth-providers-settings.ts
|
|
253
|
+
var AUTH_PROVIDERS_SETTINGS_GROUP = "auth_providers";
|
|
254
|
+
function parseEnabled(raw) {
|
|
255
|
+
if (typeof raw === "boolean") return raw;
|
|
256
|
+
if (typeof raw === "number") return raw !== 0;
|
|
257
|
+
if (typeof raw === "string") {
|
|
258
|
+
const n = raw.trim().toLowerCase();
|
|
259
|
+
return n === "true" || n === "1" || n === "yes" || n === "on";
|
|
260
|
+
}
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
chunkUSNT2KNT_cjs.__name(parseEnabled, "parseEnabled");
|
|
264
|
+
function resolveSettingsEncryptionKey() {
|
|
265
|
+
if (typeof process === "undefined") return void 0;
|
|
266
|
+
return process.env.SETTINGS_ENCRYPTION_KEY?.trim() || process.env.NEXTAUTH_SECRET?.trim() || void 0;
|
|
267
|
+
}
|
|
268
|
+
chunkUSNT2KNT_cjs.__name(resolveSettingsEncryptionKey, "resolveSettingsEncryptionKey");
|
|
269
|
+
function decryptSettingValue(encoded, key) {
|
|
270
|
+
const buf = Buffer.from(encoded, "base64");
|
|
271
|
+
const keyBuf = Buffer.from(key.padEnd(32, "0").slice(0, 32), "utf8");
|
|
272
|
+
const out = Buffer.alloc(buf.length);
|
|
273
|
+
for (let i = 0; i < buf.length; i++) out[i] = buf[i] ^ keyBuf[i % keyBuf.length];
|
|
274
|
+
return out.toString("utf8");
|
|
275
|
+
}
|
|
276
|
+
chunkUSNT2KNT_cjs.__name(decryptSettingValue, "decryptSettingValue");
|
|
277
|
+
async function loadAuthProvidersSettingsFromDb(dataSource, entityMap, encryptionKey) {
|
|
278
|
+
if (!entityMap.configs) return {};
|
|
279
|
+
const key = encryptionKey ?? resolveSettingsEncryptionKey();
|
|
280
|
+
const rows = await dataSource.getRepository(entityMap.configs).find({
|
|
281
|
+
where: {
|
|
282
|
+
settings: AUTH_PROVIDERS_SETTINGS_GROUP,
|
|
283
|
+
deleted: false
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
const out = {};
|
|
287
|
+
for (const row of rows) {
|
|
288
|
+
let val = row.value;
|
|
289
|
+
if (row.encrypted && key) {
|
|
290
|
+
try {
|
|
291
|
+
val = decryptSettingValue(val, key);
|
|
292
|
+
} catch {
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
out[row.key] = val;
|
|
296
|
+
}
|
|
297
|
+
return out;
|
|
298
|
+
}
|
|
299
|
+
chunkUSNT2KNT_cjs.__name(loadAuthProvidersSettingsFromDb, "loadAuthProvidersSettingsFromDb");
|
|
300
|
+
function fromSettingsMap(map) {
|
|
301
|
+
const clientId = String(map.googleClientId ?? map.GOOGLE_CLIENT_ID ?? "").trim();
|
|
302
|
+
const clientSecret = String(map.googleClientSecret ?? map.GOOGLE_CLIENT_SECRET ?? "").trim();
|
|
303
|
+
const enabledFlag = map.googleEnabled !== void 0 && map.googleEnabled !== "" ? parseEnabled(map.googleEnabled) : parseEnabled(map.enabled);
|
|
304
|
+
if (!enabledFlag || !clientId || !clientSecret) return null;
|
|
305
|
+
return {
|
|
306
|
+
enabled: true,
|
|
307
|
+
clientId,
|
|
308
|
+
clientSecret
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
chunkUSNT2KNT_cjs.__name(fromSettingsMap, "fromSettingsMap");
|
|
312
|
+
function fromEnv() {
|
|
313
|
+
const env = typeof process !== "undefined" ? process.env : void 0;
|
|
314
|
+
if (!env) return null;
|
|
315
|
+
const clientId = String(env.GOOGLE_CLIENT_ID ?? "").trim();
|
|
316
|
+
const clientSecret = String(env.GOOGLE_CLIENT_SECRET ?? "").trim();
|
|
317
|
+
const enabledRaw = env.GOOGLE_AUTH_ENABLED;
|
|
318
|
+
const enabled = enabledRaw === void 0 || enabledRaw === "" ? Boolean(clientId && clientSecret) : parseEnabled(enabledRaw);
|
|
319
|
+
if (!enabled || !clientId || !clientSecret) return null;
|
|
320
|
+
return {
|
|
321
|
+
enabled: true,
|
|
322
|
+
clientId,
|
|
323
|
+
clientSecret
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
chunkUSNT2KNT_cjs.__name(fromEnv, "fromEnv");
|
|
327
|
+
async function resolveGoogleAuthConfig(input = {}) {
|
|
328
|
+
if (input.settings) {
|
|
329
|
+
const fromExplicit = fromSettingsMap(input.settings);
|
|
330
|
+
if (fromExplicit?.enabled) {
|
|
331
|
+
logAuth("resolveGoogleAuthConfig: from explicit settings", {
|
|
332
|
+
enabled: true
|
|
333
|
+
});
|
|
334
|
+
return fromExplicit;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (input.dataSource && input.entityMap?.configs) {
|
|
338
|
+
try {
|
|
339
|
+
const map = await loadAuthProvidersSettingsFromDb(input.dataSource, input.entityMap, input.encryptionKey);
|
|
340
|
+
const fromDb = fromSettingsMap(map);
|
|
341
|
+
if (fromDb?.enabled) {
|
|
342
|
+
logAuth("resolveGoogleAuthConfig: from DB settings", {
|
|
343
|
+
enabled: true
|
|
344
|
+
});
|
|
345
|
+
return fromDb;
|
|
346
|
+
}
|
|
347
|
+
if (map.googleEnabled !== void 0 || map.googleClientId !== void 0) {
|
|
348
|
+
logAuth("resolveGoogleAuthConfig: DB present but incomplete/disabled", {
|
|
349
|
+
googleEnabled: map.googleEnabled ?? null,
|
|
350
|
+
hasClientId: Boolean(String(map.googleClientId ?? "").trim()),
|
|
351
|
+
hasClientSecret: Boolean(String(map.googleClientSecret ?? "").trim())
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
} catch (err) {
|
|
355
|
+
logAuth("resolveGoogleAuthConfig: DB load failed", {
|
|
356
|
+
message: err instanceof Error ? err.message : String(err)
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (!input.skipEnvFallback) {
|
|
361
|
+
const envCfg = fromEnv();
|
|
362
|
+
if (envCfg) {
|
|
363
|
+
logAuth("resolveGoogleAuthConfig: from env", {
|
|
364
|
+
enabled: true
|
|
365
|
+
});
|
|
366
|
+
return envCfg;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
chunkUSNT2KNT_cjs.__name(resolveGoogleAuthConfig, "resolveGoogleAuthConfig");
|
|
372
|
+
function googleOAuthRedirectUri(baseUrl) {
|
|
373
|
+
const base = (baseUrl ?? process.env.NEXTAUTH_URL ?? "").replace(/\/$/, "");
|
|
374
|
+
return base ? `${base}/api/auth/callback/google` : "/api/auth/callback/google";
|
|
375
|
+
}
|
|
376
|
+
chunkUSNT2KNT_cjs.__name(googleOAuthRedirectUri, "googleOAuthRedirectUri");
|
|
377
|
+
function isGoogleAuthPubliclyEnabled(settings) {
|
|
378
|
+
if (!settings) return false;
|
|
379
|
+
if (settings.googleEnabled !== void 0 && settings.googleEnabled !== "") {
|
|
380
|
+
return parseEnabled(settings.googleEnabled);
|
|
381
|
+
}
|
|
382
|
+
return parseEnabled(settings.enabled);
|
|
383
|
+
}
|
|
384
|
+
chunkUSNT2KNT_cjs.__name(isGoogleAuthPubliclyEnabled, "isGoogleAuthPubliclyEnabled");
|
|
385
|
+
|
|
386
|
+
// src/auth/create-google-customer.ts
|
|
387
|
+
function normalizeEmail(email) {
|
|
388
|
+
return email.trim().toLowerCase();
|
|
389
|
+
}
|
|
390
|
+
chunkUSNT2KNT_cjs.__name(normalizeEmail, "normalizeEmail");
|
|
391
|
+
async function createCustomerUserFromGoogleOAuth(input) {
|
|
392
|
+
const email = normalizeEmail(input.email);
|
|
393
|
+
if (!email || !input.entityMap.users || !input.entityMap.user_groups) {
|
|
394
|
+
logAuth("createCustomerUserFromGoogleOAuth skipped", {
|
|
395
|
+
reason: "missing_email_or_entities",
|
|
396
|
+
hasUsers: Boolean(input.entityMap.users),
|
|
397
|
+
hasGroups: Boolean(input.entityMap.user_groups)
|
|
398
|
+
});
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
const userRepo = input.dataSource.getRepository(input.entityMap.users);
|
|
402
|
+
const groupRepo = input.dataSource.getRepository(input.entityMap.user_groups);
|
|
403
|
+
try {
|
|
404
|
+
await chunkOY2YTBMP_cjs.retireSoftDeletedUniqueValue(userRepo, "email", email);
|
|
405
|
+
} catch {
|
|
406
|
+
}
|
|
407
|
+
const existing = await userRepo.findOne({
|
|
408
|
+
where: {
|
|
409
|
+
email,
|
|
410
|
+
deleted: false
|
|
411
|
+
},
|
|
412
|
+
relations: [
|
|
413
|
+
"group",
|
|
414
|
+
"group.permissions"
|
|
415
|
+
]
|
|
416
|
+
});
|
|
417
|
+
if (existing) {
|
|
418
|
+
return existing;
|
|
419
|
+
}
|
|
420
|
+
const customerG = await groupRepo.findOne({
|
|
421
|
+
where: {
|
|
422
|
+
name: "Customer",
|
|
423
|
+
deleted: false
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
const groupId = customerG ? Number(customerG.id) : null;
|
|
427
|
+
if (!Number.isFinite(groupId) || groupId == null) {
|
|
428
|
+
logAuth("createCustomerUserFromGoogleOAuth failed", {
|
|
429
|
+
reason: "customer_group_missing",
|
|
430
|
+
email
|
|
431
|
+
});
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
const displayName = typeof input.name === "string" && input.name.trim() || email.split("@")[0] || "Customer";
|
|
435
|
+
try {
|
|
436
|
+
const created = await userRepo.save(userRepo.create({
|
|
437
|
+
name: displayName,
|
|
438
|
+
email,
|
|
439
|
+
password: null,
|
|
440
|
+
blocked: false,
|
|
441
|
+
adminAccess: false,
|
|
442
|
+
groupId,
|
|
443
|
+
inviteStatus: "active",
|
|
444
|
+
inviteToken: null,
|
|
445
|
+
emailVerifiedAt: /* @__PURE__ */ new Date()
|
|
446
|
+
}));
|
|
447
|
+
const userId = Number(created.id);
|
|
448
|
+
if (!Number.isFinite(userId)) {
|
|
449
|
+
logAuth("createCustomerUserFromGoogleOAuth failed", {
|
|
450
|
+
reason: "invalid_id",
|
|
451
|
+
email
|
|
452
|
+
});
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
if (input.entityMap.contacts) {
|
|
456
|
+
try {
|
|
457
|
+
await chunk3EOM4V2M_cjs.linkUnclaimedContactToUser(input.dataSource, input.entityMap.contacts, userId, email);
|
|
458
|
+
} catch {
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (input.entityMap.customer) {
|
|
462
|
+
try {
|
|
463
|
+
await chunk3EOM4V2M_cjs.ensureCustomerForUser(input.dataSource, input.entityMap.customer, {
|
|
464
|
+
id: userId,
|
|
465
|
+
name: displayName,
|
|
466
|
+
email,
|
|
467
|
+
phone: null
|
|
468
|
+
}, {
|
|
469
|
+
phone: null
|
|
470
|
+
});
|
|
471
|
+
} catch {
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const loaded = await userRepo.findOne({
|
|
475
|
+
where: {
|
|
476
|
+
id: userId
|
|
477
|
+
},
|
|
478
|
+
relations: [
|
|
479
|
+
"group",
|
|
480
|
+
"group.permissions"
|
|
481
|
+
]
|
|
482
|
+
});
|
|
483
|
+
if (!loaded) {
|
|
484
|
+
logAuth("createCustomerUserFromGoogleOAuth failed", {
|
|
485
|
+
reason: "reload_failed",
|
|
486
|
+
email,
|
|
487
|
+
userId
|
|
488
|
+
});
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
logAuth("createCustomerUserFromGoogleOAuth ok", {
|
|
492
|
+
email,
|
|
493
|
+
userId
|
|
494
|
+
});
|
|
495
|
+
return loaded;
|
|
496
|
+
} catch (err) {
|
|
497
|
+
const raced = await userRepo.findOne({
|
|
498
|
+
where: {
|
|
499
|
+
email,
|
|
500
|
+
deleted: false
|
|
501
|
+
},
|
|
502
|
+
relations: [
|
|
503
|
+
"group",
|
|
504
|
+
"group.permissions"
|
|
505
|
+
]
|
|
506
|
+
});
|
|
507
|
+
if (raced) {
|
|
508
|
+
logAuth("createCustomerUserFromGoogleOAuth raced_to_existing", {
|
|
509
|
+
email,
|
|
510
|
+
userId: raced.id
|
|
511
|
+
});
|
|
512
|
+
return raced;
|
|
513
|
+
}
|
|
514
|
+
logAuth("createCustomerUserFromGoogleOAuth error", {
|
|
515
|
+
email,
|
|
516
|
+
message: err instanceof Error ? err.message : String(err)
|
|
517
|
+
});
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
chunkUSNT2KNT_cjs.__name(createCustomerUserFromGoogleOAuth, "createCustomerUserFromGoogleOAuth");
|
|
522
|
+
|
|
523
|
+
// src/auth/nextauth-options.ts
|
|
243
524
|
var CredentialsProvider = _CredentialsProvider__default.default.default ?? _CredentialsProvider__default.default;
|
|
525
|
+
var GoogleProvider = _GoogleProvider__default.default.default ?? _GoogleProvider__default.default;
|
|
244
526
|
function parseBooleanSetting(value) {
|
|
245
527
|
if (typeof value === "boolean") return value;
|
|
246
528
|
if (typeof value === "number") return value !== 0;
|
|
@@ -362,8 +644,12 @@ function permitsCustomerLogin(allowCustomerLogin, credentials) {
|
|
|
362
644
|
return !callbackUrlTargetsAdmin(callbackUrl);
|
|
363
645
|
}
|
|
364
646
|
chunkUSNT2KNT_cjs.__name(permitsCustomerLogin, "permitsCustomerLogin");
|
|
647
|
+
function applySessionUserToAuthUser(target, sessionUser) {
|
|
648
|
+
Object.assign(target, sessionUser);
|
|
649
|
+
}
|
|
650
|
+
chunkUSNT2KNT_cjs.__name(applySessionUserToAuthUser, "applySessionUserToAuthUser");
|
|
365
651
|
function getNextAuthOptions(config) {
|
|
366
|
-
const { getUserByEmail, comparePassword, signInPage = "/admin/signin", secret, extend, enablePasswordLogin = true, enableOtpLogin = false, authorizeOtp, allowCustomerLogin } = config;
|
|
652
|
+
const { getUserByEmail, comparePassword, signInPage = "/admin/signin", secret, extend, enablePasswordLogin = true, enableOtpLogin = false, authorizeOtp, allowCustomerLogin, google, createCustomerUserFromGoogle } = config;
|
|
367
653
|
logAuth("getNextAuthOptions init", nextAuthCookieDebugInfo());
|
|
368
654
|
const providers = [];
|
|
369
655
|
if (enablePasswordLogin) {
|
|
@@ -519,6 +805,14 @@ function getNextAuthOptions(config) {
|
|
|
519
805
|
}
|
|
520
806
|
}));
|
|
521
807
|
}
|
|
808
|
+
if (google?.enabled && google.clientId && google.clientSecret) {
|
|
809
|
+
providers.push(GoogleProvider({
|
|
810
|
+
clientId: google.clientId,
|
|
811
|
+
clientSecret: google.clientSecret,
|
|
812
|
+
allowDangerousEmailAccountLinking: true
|
|
813
|
+
}));
|
|
814
|
+
logAuth("getNextAuthOptions: GoogleProvider registered");
|
|
815
|
+
}
|
|
522
816
|
const options = {
|
|
523
817
|
secret: secret ?? process.env.NEXTAUTH_SECRET,
|
|
524
818
|
providers,
|
|
@@ -540,6 +834,94 @@ function getNextAuthOptions(config) {
|
|
|
540
834
|
}
|
|
541
835
|
},
|
|
542
836
|
callbacks: {
|
|
837
|
+
async signIn({ user, account, profile }) {
|
|
838
|
+
if (account?.provider !== "google") return true;
|
|
839
|
+
const emailRaw = typeof user?.email === "string" && user.email || (profile && typeof profile.email === "string" ? profile.email : "");
|
|
840
|
+
const email = emailRaw.trim().toLowerCase();
|
|
841
|
+
if (!email) {
|
|
842
|
+
logAuth("signIn(google) rejected", {
|
|
843
|
+
reason: "missing_email"
|
|
844
|
+
});
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
try {
|
|
848
|
+
let dbUser = await getUserByEmail(email);
|
|
849
|
+
if (!dbUser && allowCustomerLogin === true && createCustomerUserFromGoogle) {
|
|
850
|
+
const profileName = typeof user?.name === "string" && user.name || (profile && typeof profile.name === "string" ? profile.name : null);
|
|
851
|
+
dbUser = await createCustomerUserFromGoogle({
|
|
852
|
+
email,
|
|
853
|
+
name: profileName
|
|
854
|
+
});
|
|
855
|
+
if (dbUser) {
|
|
856
|
+
logAuth("signIn(google) created customer", {
|
|
857
|
+
email,
|
|
858
|
+
userId: dbUser.id
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
if (!dbUser) {
|
|
863
|
+
logAuth("signIn(google) rejected", {
|
|
864
|
+
reason: "user_not_found",
|
|
865
|
+
email
|
|
866
|
+
});
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
if (dbUser.blocked) {
|
|
870
|
+
logAuth("signIn(google) rejected", {
|
|
871
|
+
reason: "blocked",
|
|
872
|
+
email,
|
|
873
|
+
userId: dbUser.id
|
|
874
|
+
});
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
if (dbUser.inviteStatus === "pending") {
|
|
878
|
+
logAuth("signIn(google) rejected", {
|
|
879
|
+
reason: "invite_pending",
|
|
880
|
+
email,
|
|
881
|
+
userId: dbUser.id
|
|
882
|
+
});
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
if (dbUser.deleted) {
|
|
886
|
+
logAuth("signIn(google) rejected", {
|
|
887
|
+
reason: "deleted",
|
|
888
|
+
email,
|
|
889
|
+
userId: dbUser.id
|
|
890
|
+
});
|
|
891
|
+
return false;
|
|
892
|
+
}
|
|
893
|
+
if (isCustomerGroupUser(dbUser) && allowCustomerLogin !== true) {
|
|
894
|
+
logAuth("signIn(google) rejected", {
|
|
895
|
+
reason: "customer_group",
|
|
896
|
+
email,
|
|
897
|
+
userId: dbUser.id
|
|
898
|
+
});
|
|
899
|
+
return false;
|
|
900
|
+
}
|
|
901
|
+
const sessionUser = sessionUserFromNextAuthUser(dbUser);
|
|
902
|
+
if (sessionUser.isVendorPortal && !sessionUser.isRBACAdmin) {
|
|
903
|
+
const multiVendorEnabled = await checkMultiVendorEnabledViaSettingsApi();
|
|
904
|
+
if (!multiVendorEnabled) {
|
|
905
|
+
logAuth("signIn(google) rejected", {
|
|
906
|
+
reason: "multi_vendor_disabled",
|
|
907
|
+
email,
|
|
908
|
+
userId: dbUser.id
|
|
909
|
+
});
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
applySessionUserToAuthUser(user, sessionUser);
|
|
914
|
+
logAuth("signIn(google) ok", summarizeSessionUserForLog(sessionUser));
|
|
915
|
+
return true;
|
|
916
|
+
} catch (err) {
|
|
917
|
+
console.error("[cms-auth] signIn error (google):", err instanceof Error ? err.message : err);
|
|
918
|
+
logAuth("signIn(google) error", {
|
|
919
|
+
email,
|
|
920
|
+
message: err instanceof Error ? err.message : String(err)
|
|
921
|
+
});
|
|
922
|
+
return false;
|
|
923
|
+
}
|
|
924
|
+
},
|
|
543
925
|
async jwt({ token, user, trigger, session }) {
|
|
544
926
|
if (user) {
|
|
545
927
|
logAuth("jwt callback: new sign-in", {
|
|
@@ -608,6 +990,30 @@ function getNextAuthOptions(config) {
|
|
|
608
990
|
return extend ? extend(options) : options;
|
|
609
991
|
}
|
|
610
992
|
chunkUSNT2KNT_cjs.__name(getNextAuthOptions, "getNextAuthOptions");
|
|
993
|
+
async function buildNextAuthOptions(config) {
|
|
994
|
+
const { dataSource, entityMap, settingsEncryptionKey, googleResolve, google, createCustomerUserFromGoogle, ...rest } = config;
|
|
995
|
+
const resolved = google ?? await resolveGoogleAuthConfig({
|
|
996
|
+
dataSource,
|
|
997
|
+
entityMap,
|
|
998
|
+
encryptionKey: settingsEncryptionKey,
|
|
999
|
+
...googleResolve
|
|
1000
|
+
});
|
|
1001
|
+
let createCustomer = createCustomerUserFromGoogle;
|
|
1002
|
+
if (!createCustomer && rest.allowCustomerLogin === true && dataSource && entityMap && entityMap.users && entityMap.user_groups) {
|
|
1003
|
+
createCustomer = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((input) => createCustomerUserFromGoogleOAuth({
|
|
1004
|
+
dataSource,
|
|
1005
|
+
entityMap,
|
|
1006
|
+
email: input.email,
|
|
1007
|
+
name: input.name
|
|
1008
|
+
}), "createCustomer");
|
|
1009
|
+
}
|
|
1010
|
+
return getNextAuthOptions({
|
|
1011
|
+
...rest,
|
|
1012
|
+
google: resolved,
|
|
1013
|
+
createCustomerUserFromGoogle: createCustomer
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
chunkUSNT2KNT_cjs.__name(buildNextAuthOptions, "buildNextAuthOptions");
|
|
611
1017
|
function getStorefrontNextAuthOptions(config) {
|
|
612
1018
|
return getNextAuthOptions({
|
|
613
1019
|
...config,
|
|
@@ -615,15 +1021,29 @@ function getStorefrontNextAuthOptions(config) {
|
|
|
615
1021
|
});
|
|
616
1022
|
}
|
|
617
1023
|
chunkUSNT2KNT_cjs.__name(getStorefrontNextAuthOptions, "getStorefrontNextAuthOptions");
|
|
1024
|
+
async function buildStorefrontNextAuthOptions(config) {
|
|
1025
|
+
return buildNextAuthOptions({
|
|
1026
|
+
...config,
|
|
1027
|
+
allowCustomerLogin: true
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
chunkUSNT2KNT_cjs.__name(buildStorefrontNextAuthOptions, "buildStorefrontNextAuthOptions");
|
|
618
1031
|
|
|
1032
|
+
exports.AUTH_PROVIDERS_SETTINGS_GROUP = AUTH_PROVIDERS_SETTINGS_GROUP;
|
|
1033
|
+
exports.buildNextAuthOptions = buildNextAuthOptions;
|
|
1034
|
+
exports.buildStorefrontNextAuthOptions = buildStorefrontNextAuthOptions;
|
|
619
1035
|
exports.createCmsMiddleware = createCmsMiddleware;
|
|
1036
|
+
exports.createCustomerUserFromGoogleOAuth = createCustomerUserFromGoogleOAuth;
|
|
620
1037
|
exports.defaultPublicApiMethods = defaultPublicApiMethods;
|
|
621
1038
|
exports.getNextAuthOptions = getNextAuthOptions;
|
|
622
1039
|
exports.getStorefrontNextAuthOptions = getStorefrontNextAuthOptions;
|
|
1040
|
+
exports.googleOAuthRedirectUri = googleOAuthRedirectUri;
|
|
623
1041
|
exports.isAuthDebugClientEnabled = isAuthDebugClientEnabled;
|
|
624
1042
|
exports.isAuthDebugEnabled = isAuthDebugEnabled;
|
|
1043
|
+
exports.isGoogleAuthPubliclyEnabled = isGoogleAuthPubliclyEnabled;
|
|
625
1044
|
exports.logAuth = logAuth;
|
|
626
1045
|
exports.logAuthClient = logAuthClient;
|
|
627
1046
|
exports.nextAuthCookieDebugInfo = nextAuthCookieDebugInfo;
|
|
1047
|
+
exports.resolveGoogleAuthConfig = resolveGoogleAuthConfig;
|
|
628
1048
|
exports.seedAdministratorPermissions = seedAdministratorPermissions;
|
|
629
1049
|
exports.summarizeSessionUserForLog = summarizeSessionUserForLog;
|
package/dist/cli.cjs
CHANGED
|
@@ -207,7 +207,7 @@ export async function PATCH(req: Request, ctx: { params: Promise<{ path?: string
|
|
|
207
207
|
export async function DELETE(req: Request, ctx: { params: Promise<{ path?: string[] }> }) { return handle('DELETE', req, ctx); }
|
|
208
208
|
`,
|
|
209
209
|
"src/app/api/auth/[...nextauth]/route.ts": `import NextAuth from 'next-auth';
|
|
210
|
-
import {
|
|
210
|
+
import { buildNextAuthOptions } from '@infuro/cms-core/auth';
|
|
211
211
|
import { getDataSourceInitialized } from '@/lib/data-source';
|
|
212
212
|
import { CMS_ENTITY_MAP, enrichUserWithVendorContext } from '@infuro/cms-core';
|
|
213
213
|
import bcrypt from 'bcryptjs';
|
|
@@ -215,7 +215,9 @@ import bcrypt from 'bcryptjs';
|
|
|
215
215
|
async function getOptions() {
|
|
216
216
|
const dataSource = await getDataSourceInitialized();
|
|
217
217
|
const userRepo = dataSource.getRepository(CMS_ENTITY_MAP.users);
|
|
218
|
-
return
|
|
218
|
+
return buildNextAuthOptions({
|
|
219
|
+
dataSource,
|
|
220
|
+
entityMap: CMS_ENTITY_MAP,
|
|
219
221
|
getUserByEmail: async (email: string) => {
|
|
220
222
|
const user = await userRepo.findOne({
|
|
221
223
|
where: { email },
|
|
@@ -229,24 +231,17 @@ async function getOptions() {
|
|
|
229
231
|
});
|
|
230
232
|
}
|
|
231
233
|
|
|
232
|
-
let handler: ReturnType<typeof NextAuth> | null = null;
|
|
233
|
-
|
|
234
|
-
async function getHandler() {
|
|
235
|
-
if (!handler) handler = NextAuth(await getOptions());
|
|
236
|
-
return handler;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
234
|
type NextAuthContext = { params: Promise<{ nextauth?: string[] }> };
|
|
240
235
|
|
|
241
236
|
export async function GET(req: Request, context: NextAuthContext) {
|
|
242
|
-
return (await
|
|
237
|
+
return NextAuth(await getOptions())(req, context);
|
|
243
238
|
}
|
|
244
239
|
export async function POST(req: Request, context: NextAuthContext) {
|
|
245
|
-
return (await
|
|
240
|
+
return NextAuth(await getOptions())(req, context);
|
|
246
241
|
}
|
|
247
242
|
`,
|
|
248
243
|
"src/app/api/storefront-auth/[...nextauth]/route.ts": `import NextAuth from 'next-auth';
|
|
249
|
-
import {
|
|
244
|
+
import { buildStorefrontNextAuthOptions } from '@infuro/cms-core/auth';
|
|
250
245
|
import { getDataSourceInitialized } from '@/lib/data-source';
|
|
251
246
|
import { CMS_ENTITY_MAP, enrichUserWithVendorContext } from '@infuro/cms-core';
|
|
252
247
|
import bcrypt from 'bcryptjs';
|
|
@@ -254,7 +249,9 @@ import bcrypt from 'bcryptjs';
|
|
|
254
249
|
async function getOptions() {
|
|
255
250
|
const dataSource = await getDataSourceInitialized();
|
|
256
251
|
const userRepo = dataSource.getRepository(CMS_ENTITY_MAP.users);
|
|
257
|
-
return
|
|
252
|
+
return buildStorefrontNextAuthOptions({
|
|
253
|
+
dataSource,
|
|
254
|
+
entityMap: CMS_ENTITY_MAP,
|
|
258
255
|
getUserByEmail: async (email: string) => {
|
|
259
256
|
const user = await userRepo.findOne({
|
|
260
257
|
where: { email },
|
|
@@ -268,20 +265,13 @@ async function getOptions() {
|
|
|
268
265
|
});
|
|
269
266
|
}
|
|
270
267
|
|
|
271
|
-
let handler: ReturnType<typeof NextAuth> | null = null;
|
|
272
|
-
|
|
273
|
-
async function getHandler() {
|
|
274
|
-
if (!handler) handler = NextAuth(await getOptions());
|
|
275
|
-
return handler;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
268
|
type NextAuthContext = { params: Promise<{ nextauth?: string[] }> };
|
|
279
269
|
|
|
280
270
|
export async function GET(req: Request, context: NextAuthContext) {
|
|
281
|
-
return (await
|
|
271
|
+
return NextAuth(await getOptions())(req, context);
|
|
282
272
|
}
|
|
283
273
|
export async function POST(req: Request, context: NextAuthContext) {
|
|
284
|
-
return (await
|
|
274
|
+
return NextAuth(await getOptions())(req, context);
|
|
285
275
|
}
|
|
286
276
|
`,
|
|
287
277
|
"src/app/admin/layout.tsx": `'use client';
|
|
@@ -322,6 +312,7 @@ const cmsMiddleware = createCmsMiddleware({
|
|
|
322
312
|
'/api/users/forgot-password': ['POST'],
|
|
323
313
|
'/api/users/set-password': ['POST'],
|
|
324
314
|
'/api/users/invite': ['GET', 'POST'],
|
|
315
|
+
'/api/settings/auth_providers': ['GET'],
|
|
325
316
|
},
|
|
326
317
|
});
|
|
327
318
|
|
package/dist/cli.js
CHANGED
|
@@ -200,7 +200,7 @@ export async function PATCH(req: Request, ctx: { params: Promise<{ path?: string
|
|
|
200
200
|
export async function DELETE(req: Request, ctx: { params: Promise<{ path?: string[] }> }) { return handle('DELETE', req, ctx); }
|
|
201
201
|
`,
|
|
202
202
|
"src/app/api/auth/[...nextauth]/route.ts": `import NextAuth from 'next-auth';
|
|
203
|
-
import {
|
|
203
|
+
import { buildNextAuthOptions } from '@infuro/cms-core/auth';
|
|
204
204
|
import { getDataSourceInitialized } from '@/lib/data-source';
|
|
205
205
|
import { CMS_ENTITY_MAP, enrichUserWithVendorContext } from '@infuro/cms-core';
|
|
206
206
|
import bcrypt from 'bcryptjs';
|
|
@@ -208,7 +208,9 @@ import bcrypt from 'bcryptjs';
|
|
|
208
208
|
async function getOptions() {
|
|
209
209
|
const dataSource = await getDataSourceInitialized();
|
|
210
210
|
const userRepo = dataSource.getRepository(CMS_ENTITY_MAP.users);
|
|
211
|
-
return
|
|
211
|
+
return buildNextAuthOptions({
|
|
212
|
+
dataSource,
|
|
213
|
+
entityMap: CMS_ENTITY_MAP,
|
|
212
214
|
getUserByEmail: async (email: string) => {
|
|
213
215
|
const user = await userRepo.findOne({
|
|
214
216
|
where: { email },
|
|
@@ -222,24 +224,17 @@ async function getOptions() {
|
|
|
222
224
|
});
|
|
223
225
|
}
|
|
224
226
|
|
|
225
|
-
let handler: ReturnType<typeof NextAuth> | null = null;
|
|
226
|
-
|
|
227
|
-
async function getHandler() {
|
|
228
|
-
if (!handler) handler = NextAuth(await getOptions());
|
|
229
|
-
return handler;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
227
|
type NextAuthContext = { params: Promise<{ nextauth?: string[] }> };
|
|
233
228
|
|
|
234
229
|
export async function GET(req: Request, context: NextAuthContext) {
|
|
235
|
-
return (await
|
|
230
|
+
return NextAuth(await getOptions())(req, context);
|
|
236
231
|
}
|
|
237
232
|
export async function POST(req: Request, context: NextAuthContext) {
|
|
238
|
-
return (await
|
|
233
|
+
return NextAuth(await getOptions())(req, context);
|
|
239
234
|
}
|
|
240
235
|
`,
|
|
241
236
|
"src/app/api/storefront-auth/[...nextauth]/route.ts": `import NextAuth from 'next-auth';
|
|
242
|
-
import {
|
|
237
|
+
import { buildStorefrontNextAuthOptions } from '@infuro/cms-core/auth';
|
|
243
238
|
import { getDataSourceInitialized } from '@/lib/data-source';
|
|
244
239
|
import { CMS_ENTITY_MAP, enrichUserWithVendorContext } from '@infuro/cms-core';
|
|
245
240
|
import bcrypt from 'bcryptjs';
|
|
@@ -247,7 +242,9 @@ import bcrypt from 'bcryptjs';
|
|
|
247
242
|
async function getOptions() {
|
|
248
243
|
const dataSource = await getDataSourceInitialized();
|
|
249
244
|
const userRepo = dataSource.getRepository(CMS_ENTITY_MAP.users);
|
|
250
|
-
return
|
|
245
|
+
return buildStorefrontNextAuthOptions({
|
|
246
|
+
dataSource,
|
|
247
|
+
entityMap: CMS_ENTITY_MAP,
|
|
251
248
|
getUserByEmail: async (email: string) => {
|
|
252
249
|
const user = await userRepo.findOne({
|
|
253
250
|
where: { email },
|
|
@@ -261,20 +258,13 @@ async function getOptions() {
|
|
|
261
258
|
});
|
|
262
259
|
}
|
|
263
260
|
|
|
264
|
-
let handler: ReturnType<typeof NextAuth> | null = null;
|
|
265
|
-
|
|
266
|
-
async function getHandler() {
|
|
267
|
-
if (!handler) handler = NextAuth(await getOptions());
|
|
268
|
-
return handler;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
261
|
type NextAuthContext = { params: Promise<{ nextauth?: string[] }> };
|
|
272
262
|
|
|
273
263
|
export async function GET(req: Request, context: NextAuthContext) {
|
|
274
|
-
return (await
|
|
264
|
+
return NextAuth(await getOptions())(req, context);
|
|
275
265
|
}
|
|
276
266
|
export async function POST(req: Request, context: NextAuthContext) {
|
|
277
|
-
return (await
|
|
267
|
+
return NextAuth(await getOptions())(req, context);
|
|
278
268
|
}
|
|
279
269
|
`,
|
|
280
270
|
"src/app/admin/layout.tsx": `'use client';
|
|
@@ -315,6 +305,7 @@ const cmsMiddleware = createCmsMiddleware({
|
|
|
315
305
|
'/api/users/forgot-password': ['POST'],
|
|
316
306
|
'/api/users/set-password': ['POST'],
|
|
317
307
|
'/api/users/invite': ['GET', 'POST'],
|
|
308
|
+
'/api/settings/auth_providers': ['GET'],
|
|
318
309
|
},
|
|
319
310
|
});
|
|
320
311
|
|