fix(audit): documenso — M2 (reservation EOI-milestone pollution), L11 (v2 numericId GET fallback), L12 (API URL normalize/validate), L13 (event dedup)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
import { env } from '@/lib/env';
|
||||
import { normalizeBrandingUrl } from '@/lib/branding/url';
|
||||
import { getSetting } from '@/lib/services/settings.service';
|
||||
import { normalizeDocumensoApiUrl } from '@/lib/validators/settings';
|
||||
|
||||
// ─── Setting key constants ───────────────────────────────────────────────────
|
||||
|
||||
@@ -430,18 +431,28 @@ export async function getPortDocumensoConfig(portId: string): Promise<PortDocume
|
||||
readSetting<string>(SETTING_KEYS.publicSiteUrl, portId),
|
||||
]);
|
||||
|
||||
// Defense-in-depth: normalize any persisted Documenso API URL override at
|
||||
// read time. Writes are normalized + URL-validated by upsertSettingSchema,
|
||||
// but values stored before that validation landed (or seeded directly) may
|
||||
// still carry a `/api/v1`|`/api/v2` suffix that would double-path requests
|
||||
// (documensoFetch appends `/api/vN/...` to this base). Strip it here too.
|
||||
const normalizedApiUrl =
|
||||
typeof apiUrl === 'string' && apiUrl.length > 0
|
||||
? (normalizeDocumensoApiUrl(apiUrl) as string)
|
||||
: apiUrl;
|
||||
|
||||
// Determine the resolution source for the two credentials. Used by
|
||||
// the documenso client to enrich 401/403 error messages so operators
|
||||
// can tell at a glance whether the failing key is per-port or env.
|
||||
type Source = 'port' | 'global' | 'env' | 'default' | 'none';
|
||||
const apiUrlSource: Source = apiUrl ? 'port' : env.DOCUMENSO_API_URL ? 'env' : 'none';
|
||||
const apiUrlSource: Source = normalizedApiUrl ? 'port' : env.DOCUMENSO_API_URL ? 'env' : 'none';
|
||||
const apiKeySource: Source = apiKey ? 'port' : env.DOCUMENSO_API_KEY ? 'env' : 'none';
|
||||
|
||||
return {
|
||||
// Env values are now optional (admin is canonical). Empty / zero
|
||||
// defaults let consumers proceed and fail at the actual API call with
|
||||
// a clearer "not configured" error rather than crashing at type-check.
|
||||
apiUrl: apiUrl ?? env.DOCUMENSO_API_URL ?? '',
|
||||
apiUrl: normalizedApiUrl ?? env.DOCUMENSO_API_URL ?? '',
|
||||
apiKey: apiKey ?? env.DOCUMENSO_API_KEY ?? '',
|
||||
apiVersion: apiVersion ?? env.DOCUMENSO_API_VERSION,
|
||||
apiKeySource,
|
||||
|
||||
Reference in New Issue
Block a user