create-nextblock 0.13.7 → 0.13.9
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/package.json +1 -1
- package/templates/nextblock-template/app/(auth-pages)/two-factor/actions.ts +21 -1
- package/templates/nextblock-template/app/(auth-pages)/two-factor/components/TwoFactorForm.tsx +34 -10
- package/templates/nextblock-template/app/actions/email.ts +78 -7
- package/templates/nextblock-template/app/actions/feedback.ts +57 -14
- package/templates/nextblock-template/app/actions/interactions.test.ts +3 -0
- package/templates/nextblock-template/app/actions/productGridActions.ts +40 -0
- package/templates/nextblock-template/app/actions.ts +17 -4
- package/templates/nextblock-template/app/api/cms/ecommerce/product-picker/route.ts +151 -0
- package/templates/nextblock-template/app/cms/CmsClientLayout.tsx +4 -1
- package/templates/nextblock-template/app/cms/blocks/components/BlockTypeSelector.tsx +17 -5
- package/templates/nextblock-template/app/cms/blocks/components/MultiEntityPicker.tsx +251 -0
- package/templates/nextblock-template/app/cms/blocks/editors/ProductGridBlockEditor.tsx +375 -18
- package/templates/nextblock-template/app/cms/components/EcommerceActiveContext.tsx +27 -0
- package/templates/nextblock-template/app/cms/settings/bot-protection/actions.ts +9 -6
- package/templates/nextblock-template/app/cms/settings/bot-protection/components/BotProtectionForm.tsx +1 -5
- package/templates/nextblock-template/app/cms/settings/copyright/actions.ts +9 -6
- package/templates/nextblock-template/app/cms/settings/copyright/components/CopyrightForm.tsx +1 -5
- package/templates/nextblock-template/app/cms/settings/cortex-ai/actions.ts +18 -8
- package/templates/nextblock-template/app/cms/settings/email/actions.ts +59 -29
- package/templates/nextblock-template/app/cms/settings/email/components/EmailForm.tsx +5 -1
- package/templates/nextblock-template/app/cms/settings/global-css/actions.ts +6 -5
- package/templates/nextblock-template/app/cms/settings/global-css/components/GlobalCssForm.tsx +2 -1
- package/templates/nextblock-template/app/cms/settings/google-analytics/actions.ts +18 -7
- package/templates/nextblock-template/app/cms/settings/google-analytics/components/GoogleAnalyticsForm.tsx +1 -1
- package/templates/nextblock-template/app/cms/settings/privacy/actions.ts +16 -7
- package/templates/nextblock-template/app/cms/settings/privacy/components/PrivacyForm.tsx +1 -1
- package/templates/nextblock-template/app/cms/settings/registration/actions.ts +18 -7
- package/templates/nextblock-template/app/cms/settings/registration/components/RegistrationForm.tsx +1 -1
- package/templates/nextblock-template/app/cms/settings/security/actions.ts +227 -131
- package/templates/nextblock-template/app/cms/settings/security/components/SecurityPanel.tsx +134 -18
- package/templates/nextblock-template/components/blocks/ProductGridClient.tsx +114 -0
- package/templates/nextblock-template/lib/auth/twoFactor.test.ts +254 -0
- package/templates/nextblock-template/lib/auth/twoFactor.ts +56 -13
- package/templates/nextblock-template/lib/blocks/ProductGridBlock.tsx +78 -139
- package/templates/nextblock-template/lib/blocks/blockRegistry.ts +3 -3
- package/templates/nextblock-template/lib/blocks/blockTypes.ts +19 -0
- package/templates/nextblock-template/lib/blocks/ecommerce-block-schemas.ts +61 -2
- package/templates/nextblock-template/lib/blocks/product-grid-data.ts +210 -0
- package/templates/nextblock-template/lib/cms/action-result.ts +12 -0
- package/templates/nextblock-template/lib/config/email-settings.ts +40 -3
- package/templates/nextblock-template/next-env.d.ts +1 -1
- package/templates/nextblock-template/package.json +1 -1
- package/templates/nextblock-template/tsconfig.tsbuildinfo +1 -1
|
@@ -170,14 +170,46 @@ export async function saveEmailSettings(input: SaveEmailSettingsInput): Promise<
|
|
|
170
170
|
throw new Error('Failed to save email credentials.');
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
+
|
|
174
|
+
// The mailer memoizes the resolved transport config; make the new values live now.
|
|
175
|
+
invalidateEmailConfigCache();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Resolving SMTP costs two service-role reads plus an AES decrypt of each secret, and
|
|
179
|
+
// transactional email (2FA codes especially) is latency-sensitive. The values only change
|
|
180
|
+
// when an admin saves the form, so memoize briefly and bust the cache on save.
|
|
181
|
+
const CONFIG_CACHE_TTL_MS = 60_000;
|
|
182
|
+
let configCache: { value: ResolvedEmailConfig | null; expiresAt: number } | null = null;
|
|
183
|
+
|
|
184
|
+
/** Drop the memoized SMTP config so the next resolve re-reads the DB. */
|
|
185
|
+
export function invalidateEmailConfigCache(): void {
|
|
186
|
+
configCache = null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Cheap "can this instance actually send mail right now?" check for UI gating. Never
|
|
191
|
+
* logs — an unconfigured instance is an expected state here, not an error condition.
|
|
192
|
+
*/
|
|
193
|
+
export async function isEmailConfigured(): Promise<boolean> {
|
|
194
|
+
return (await resolveEmailServerConfig({ silent: true })) !== null;
|
|
173
195
|
}
|
|
174
196
|
|
|
175
197
|
/**
|
|
176
198
|
* Resolve the full SMTP transport config, DB-first with an env fallback. Uses the
|
|
177
199
|
* service-role client so it works from any context (the secret row is ADMIN-only under
|
|
178
200
|
* RLS). Returns null when host/user/pass/from cannot be resolved from either source.
|
|
201
|
+
*
|
|
202
|
+
* Memoized for CONFIG_CACHE_TTL_MS; pass `silent` when "not configured" is an expected
|
|
203
|
+
* answer (UI gating) rather than a misconfiguration worth warning about.
|
|
179
204
|
*/
|
|
180
|
-
export async function resolveEmailServerConfig(
|
|
205
|
+
export async function resolveEmailServerConfig(
|
|
206
|
+
options: { silent?: boolean } = {},
|
|
207
|
+
): Promise<ResolvedEmailConfig | null> {
|
|
208
|
+
const cached = configCache;
|
|
209
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
210
|
+
return cached.value;
|
|
211
|
+
}
|
|
212
|
+
|
|
181
213
|
let pub: EmailPublicSettings = DEFAULT_EMAIL_PUBLIC_SETTINGS;
|
|
182
214
|
let secret: Record<string, unknown> = {};
|
|
183
215
|
|
|
@@ -201,12 +233,15 @@ export async function resolveEmailServerConfig(): Promise<ResolvedEmailConfig |
|
|
|
201
233
|
const pass = resolveConfigValue(tryDecryptWithEnvKey(secret['pass']), 'SMTP_PASS');
|
|
202
234
|
|
|
203
235
|
if (!host || !port || !user || !pass || !fromEmail) {
|
|
204
|
-
|
|
236
|
+
if (!options.silent) {
|
|
237
|
+
console.warn('Email is not configured (CMS or SMTP_* env). Outbound email will not be sent.');
|
|
238
|
+
}
|
|
239
|
+
configCache = { value: null, expiresAt: Date.now() + CONFIG_CACHE_TTL_MS };
|
|
205
240
|
return null;
|
|
206
241
|
}
|
|
207
242
|
|
|
208
243
|
const portNumber = Number(port);
|
|
209
|
-
|
|
244
|
+
const resolved: ResolvedEmailConfig = {
|
|
210
245
|
host,
|
|
211
246
|
port: portNumber,
|
|
212
247
|
// Honor the CMS toggle; fall back to the SMTPS convention (465 ⇒ implicit TLS).
|
|
@@ -214,4 +249,6 @@ export async function resolveEmailServerConfig(): Promise<ResolvedEmailConfig |
|
|
|
214
249
|
auth: { user, pass },
|
|
215
250
|
from: fromName ? `"${fromName}" <${fromEmail}>` : fromEmail,
|
|
216
251
|
};
|
|
252
|
+
configCache = { value: resolved, expiresAt: Date.now() + CONFIG_CACHE_TTL_MS };
|
|
253
|
+
return resolved;
|
|
217
254
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="next" />
|
|
2
2
|
/// <reference types="next/image-types/global" />
|
|
3
|
-
import "./.next/
|
|
3
|
+
import "./.next/types/routes.d.ts";
|
|
4
4
|
|
|
5
5
|
// NOTE: This file should not be edited
|
|
6
6
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|