a7fe32fb82
- consent-sdk/src/types/index.ts: extracted 438 LOC into core.ts, config.ts, vendor.ts, api.ts, events.ts, storage.ts, translations.ts; index.ts is now a 21-LOC barrel re-exporter - consent-sdk/src/core/ConsentManager.ts: extracted normalizeConsentInput, isConsentExpired, needsConsent, ALL_CATEGORIES, MINIMAL_CATEGORIES into consent-manager-helpers.ts; reduced from 467 to 345 LOC - dsms-gateway/main.py: extracted models → models.py, config → config.py, IPFS helpers + verify_token → dependencies.py, route handlers → routers/documents.py and routers/node.py; main.py is now a 41-LOC app factory; test mock paths updated accordingly (27/27 tests pass) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
/**
|
|
* consent-manager-helpers.ts
|
|
*
|
|
* Pure helper functions used by ConsentManager that have no dependency on
|
|
* class instance state. Extracted to keep ConsentManager.ts under the
|
|
* 350 LOC soft target.
|
|
*/
|
|
|
|
import type {
|
|
ConsentState,
|
|
ConsentCategories,
|
|
ConsentInput,
|
|
ConsentConfig,
|
|
} from '../types';
|
|
import { DEFAULT_CONSENT } from './consent-manager-config';
|
|
|
|
/** All categories accepted (used by acceptAll). */
|
|
export const ALL_CATEGORIES: ConsentCategories = {
|
|
essential: true,
|
|
functional: true,
|
|
analytics: true,
|
|
marketing: true,
|
|
social: true,
|
|
};
|
|
|
|
/** Only essential consent (used by rejectAll). */
|
|
export const MINIMAL_CATEGORIES: ConsentCategories = {
|
|
essential: true,
|
|
functional: false,
|
|
analytics: false,
|
|
marketing: false,
|
|
social: false,
|
|
};
|
|
|
|
/**
|
|
* Normalise a ConsentInput into a full ConsentCategories map.
|
|
* Always returns a shallow copy — never mutates the input.
|
|
*/
|
|
export function normalizeConsentInput(input: ConsentInput): ConsentCategories {
|
|
if ('categories' in input && input.categories) {
|
|
return { ...DEFAULT_CONSENT, ...input.categories };
|
|
}
|
|
return { ...DEFAULT_CONSENT, ...(input as Partial<ConsentCategories>) };
|
|
}
|
|
|
|
/**
|
|
* Return true when the stored consent record has passed its expiry date.
|
|
* Falls back to `rememberDays` from config when `expiresAt` is absent.
|
|
*/
|
|
export function isConsentExpired(
|
|
consent: ConsentState | null,
|
|
config: ConsentConfig
|
|
): boolean {
|
|
if (!consent) return false;
|
|
|
|
if (!consent.expiresAt) {
|
|
if (consent.timestamp && config.consent?.rememberDays) {
|
|
const consentDate = new Date(consent.timestamp);
|
|
const expiryDate = new Date(consentDate);
|
|
expiryDate.setDate(expiryDate.getDate() + config.consent.rememberDays);
|
|
return new Date() > expiryDate;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return new Date() > new Date(consent.expiresAt);
|
|
}
|
|
|
|
/**
|
|
* Return true when the user needs to be shown the consent banner.
|
|
*/
|
|
export function needsConsent(
|
|
consent: ConsentState | null,
|
|
config: ConsentConfig
|
|
): boolean {
|
|
if (!consent) return true;
|
|
|
|
if (isConsentExpired(consent, config)) return true;
|
|
|
|
if (config.consent?.recheckAfterDays) {
|
|
const consentDate = new Date(consent.timestamp);
|
|
const recheckDate = new Date(consentDate);
|
|
recheckDate.setDate(recheckDate.getDate() + config.consent.recheckAfterDays);
|
|
if (new Date() > recheckDate) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|