تخطَّ إلى المحتوى
getnextpdf.com

Enterprise الإصدار

‏⁨Licensing⁩ — مرجع متعمّق

هذه الصفحة هي المرجع المتعمّق لسطح الترخيص في ⁨NextPDF Enterprise⁩ — الوحدة التي تحلّ كل قدرة ⁨Enterprise⁩ أخرى. تغطّي نموذج حالة الاستحقاق (EntitlementEvaluator وEntitlementStatus وEntitlementResult)، وحجب القدرة المُنفَّذ (FeatureGate وCapabilityCode وCapabilityRegistry)، وآلة إنفاذ القناة ذات المؤقّتَين (ChannelEnforcementPolicy وOnlineCheckScheduler)، والعميل الموقَّع عبر الإنترنت (LicenseClient). ولا يحتاج تقييم الاستحقاق العادي إلى شبكة. ويوجد العميل عبر الإنترنت لعمليات صريحة هي التفعيل، ونبض الحياة، وإلغاء التفعيل، والتحقّق عبر الإنترنت، وفحص التجديد. وتبقى تفاصيل الآلية الداخلية في التوثيق الداخلي لمستودع المصدر وهي خارج نطاق هذا الدليل.

تُشحَن هذه القدرة في ‏⁨NextPDF Enterprise⁩ (nextpdf/enterprise) وتُفعَّل بغلاف ترخيص من طبقة ⁨Enterprise⁩. وأيّ عملية نشر بلا ذلك الاستحقاق لا تُحمِّل أصناف القدرة. قارِن الإصدارات واحصل على ترخيص.

والترخيص سطح ⁨Enterprise⁩ أساسي. وهو حاضر دائمًا فور تثبيت حزمة ⁨Enterprise⁩ إلى جوار حزمة ⁨Core⁩، لأنه السطح الذي يحلّ كل شيء آخر. ولا يملك ⁨NextPDF Pro⁩ سطح استحقاق منفصلًا؛ إذ يُشحَن نموذج الحالة، وآلة الإنفاذ، والعميل عبر الإنترنت في nextpdf/enterprise فقط. أمّا ⁨NextPDF Core⁩ (‏⁨Apache-2.0⁩) فلا يملك نموذج استحقاق على الإطلاق — والمضيف الذي يحتاج سلوك ⁨Apache-2.0⁩ غير المرخَّص يستخدم محرّك ⁨Core⁩ مباشرةً، لا مسار ⁨Enterprise⁩.

سطح واجهة برمجة التطبيقات العامة

قسم بعنوان «سطح واجهة برمجة التطبيقات العامة»

تقع كل الأنواع تحت NextPDF\Enterprise\Licensing. وتوجد آلة الإنفاذ في نطاق الأسماء الفرعي Channel، وتركيب وقت التشغيل في Runtime، وأنواع الحالة الموقَّعة في Online.

الرمزالمعاملاتالسلوك الافتراضييُعيديرمي أو يفشل بـملاحظات
EntitlementEvaluator::evaluate()?LicenseKey $license، ?DateTimeImmutable $now = nullيربط ترخيصًا مُتحقَّقًا منه (أو ⁨null⁩) بقرار الاستحقاق الكاملEntitlementResultلا شيءترخيص ⁨null⁩ يُنتج نتيجة «لا ترخيص» المغلقة عند الفشل
EntitlementEvaluator::evaluateEnforced()?LicenseKey $license، EnforcementOutcome $outcomeيحوّل نتيجة إنفاذ محسوبة مسبقًا إلى نتيجة استحقاقEntitlementResultلا شيءيأتي الإصدار الفعّال من النتيجة؛ وكل تخفيض إنفاذ يستقرّ على ⁨Core⁩
EntitlementEvaluator::resolveBrandingMode()، ::resolveBrandingStrategy()?LicenseKey $license، ?DateTimeImmutable $now = nullيحلّ قرار العلامة التجارية للمخرَج المُولَّدBrandingMode / BrandingStrategyلا شيءسلطة العلامة التجارية الوحيدة؛ وقناة التقييم وحدها تضع العلامة المائية
EntitlementResultكائن قيمة للقراءة فقطيحمل الحالة، والإصدار، والقناة، ووضع العلامة التجارية، وأعلام وقت التشغيل/التحديث/الدعم، وتحذيرًا اختياريًالا شيءمساعدات: isFullyActive()، isExpired()، isDowngradedToCore()، shouldApplyEvaluationBranding()
EntitlementStatusتعداد مدعوم بسلسلة نصيةActive، GracePeriod، DowngradedToCore، EvaluationExpired، NoLicenseلا شيءPerpetualFallback مُبقًى لكنه مُهمَل؛ محفوظ فقط كي يستمرّ مستهلكو ما قبل 6.0 في التصريف
FeatureGate::hasCapability()CapabilityCode $capabilityيفحص القدرة إزاء الإصدار الفعّال المُنفَّذ وحالة الحزمةboolلا شيءمغلق عند الفشل إلى core عند أي خطأ في المُحلِّل
FeatureGate::requireCapability()CapabilityCode $capabilityيمرّ بصمت أو يرمي بسياق بيع إضافي مُهيكَلvoidSpectrumAuthenticationException SPEC-LIC-001 (غير مُرخَّص) أو SPEC-LIC-002 (حزمة منتهية)يحمل السياق required_capability، required_pack، current_packs، upgrade_info_url
FeatureGate::isFeatureEnabled()، ::requireFeature()string $featureفحص مُعرِّف ميزة قديمbool / voidSpectrumAuthenticationException SPEC-AUTH-007 (مسار require)توافق قديم؛ فضّل فحوص القدرة
مُوصِّلات FeatureGateلا شيءاستبطان الترخيصمتغيّرلا شيءcurrentEdition()، isLicenseValid()، isInGracePeriod()، getActivePacks()، trialPolicy()
CapabilityCodeتعداد مدعوم بسلسلة نصيةمُعرِّفات القدرة القانونية (core.*، pro.*، enterprise.*، pack.*)لا شيءisPack()، packName()، minimumEdition()، forEdition()
CapabilityRegistryLicenseKey، أنماط المساراتحلّ مسار-إلى-قدرة والبحث عن الحزمة قبل الإرسالمتغيّرلا شيءيغطّي registerDefaultRoutes() مسارات الخدمة المُوثَّقة
LicenseKeyكائن قيمة للقراءة فقطمطالبات ترخيص مُحلَّلة ومُتحقَّق منهالا شيءisExpired()، isInGracePeriod()، isFullyExpired()، hasFeature()، hasCapability()، activePackNames()؛ وmaxSlots تعاقدي فقط
LicenseValidator::buildVerifiedLicenseKey()array $dataيبني LicenseKey مُنمَّطًا من حمولة مُتحقَّق منها سلفًاLicenseKeySpectrumAuthenticationException SPEC-AUTH-001 عند مخالفة المخطّطيدعم المخطّط 2.0 و1.0 والحمولات القديمة
PackDefinition / PackRegistryكائنات قيمة للقراءة فقطحالة حزمة إضافية بانتهاء وسماح مستقلَّينمتغيّرلا شيءisActive()، isFullyExpired()، activePacks()، activeCapabilities()
TrialPolicybool $enabled، int $maxPagesPerSecond = 2، وحقول العلامة المائيةسياسة سقف معدّل معالجة التجربةلا شيءfromLicenseKey()، disabled()، isThrottled()؛ وتبقى سلطة العلامة التجارية لدى المُقيِّم
ChannelEnforcementPolicy::enforce()LicenseKey $license، LocalState $state، int $systemNow، bool $revoked = falseيُشغّل آلة المؤقّتَين إضافةً إلى الإبطال وإعادة وسم التجربةEnforcementOutcomeلا شيءيتجاوز الإبطال كل مؤقّت وكل حالة تجربة
OnlineCheckScheduler::evaluate()، ::recordSuccessfulOnlineCheck()الترخيص، والحالة المحلّية، والطوابع الزمنيةتقييم بمؤقّتَين؛ وتجديد المدّة من وقت الخادم المُتحقَّق منهEnforcementOutcome / LocalStateلا شيءيمنح ONLINE_GRACE_SECONDS مهلة حيوية مدّتها 48 ساعة بعد انقضاء المدّة
EnforcementDecision / EnforcementReason / EnforcementOutcomeتعدادات + كائن قيمة للقراءة فقطActive، Grace، DowngradedToCore إضافةً إلى السبب الدقيقلا شيءيرتبط كل سبب بقرار واحد على نحو حتمي
Runtime\EntitlementResolver::currentEntitlement()لا شيءواجهة: الاستحقاق المُنفَّذ الذي يقدّمه وقت التشغيلEntitlementResultمُحدَّد بالتنفيذيركّب EnforcedEntitlementResolver المخبأ، والحالة، والسياسة، والمُقيِّم، مغلقًا عند الفشل إلى ⁨Core⁩
LicenseStateCache::get()، ::getOrThrow()bool $forceRefresh = falseمخبأ الترخيص المُتحقَّق منه الداعم للبوّابة?LicenseKeygetOrThrow(): SpectrumAuthenticationException SPEC-AUTH-008؛ وLicenseConfigurationException عند توصيل غير صالحinvalidate()، isCacheValid()
LicenseClient::activate()، ::heartbeat()، ::deactivate()، ::verifyOnline()string $licenseJws، string $deploymentId، ?string $machineFingerprintHash = null، ?string $expectedLicenseId = null، ?string $clientNonce = nullتبادل حالة موقَّعة واحد؛ والاستجابة يُتحقَّق منها إزاء الجذر المُثبَّت وتُربَط بالرمز العشوائي المُرسَلStatusResponseLicenseClientException (النقل، أو رمز غير 200، أو رمز عشوائي مُقدَّم غير صالح)؛ وSpectrumAuthenticationException (استجابة مزوّرة، أو مُلاعَب بها، أو قديمة، أو خاطئة الرمز العشوائي، أو خاطئة الترخيص، أو خاطئة النوع)لا يُرسَل أبدًا سوى بصمة مُملَّحة، ولا تُرسَل بصمة خام قطّ
LicenseClient::checkRenewal()string $licenseId، string $customerIdفحص توفّر التجديد؛ و404 هو الجواب المعتاد «لا يوجد متوفّر»مصفوفة تجديد (available، download_url، expires_at)LicenseClientException (غير قابل للوصول، أو رمز غير 200/404، أو download_url رفضته السياسة)يُفحَص عنوان جسم الاستجابة غير الموقَّع ضدّ ⁨SSRF⁩ قبل أن يتمكّن من الإفلات
LicenseClient::__construct()راجع سياج التوقيعيتحقّق من النقل، ومخطّط ⁨URL⁩، ومجموعة التثبيت عند الإنشاءLicenseConfigurationException (نقل لا يفرض السياسة، أو مخطّط غير مسموح، أو ⁨HTTP⁩ صِرف بلا تثبيتات، أو مجموعة تثبيت مُشوَّهة)يكشف getPinSet() مجموعة التثبيت النشطة لأدوات التدوير
Online\StatusResponseكائن قيمة للقراءة فقطالحالة الموقَّعة المُتحقَّق منهالا شيءisLive() خاطئة عند revoked / expired / released؛ وتحمل leaseExpiresAt، وأعداد المقاعد، ولقطة استحقاق
LicenseChannelMode / OnlineMode / OnlinePolicyتعدادات + كائن قيمة للقراءة فقطمطالبات القناة وسياسة الاتصاللا شيءsigned_source مقابل ioncube؛ ووضع الاتصال required / optional / disabled مع intervalDays وleaseDays
LicenseEditionتعداد مدعوم بسلسلة نصيةCore، Pro، Enterpriseلا شيءيُنفّذ satisfies() تسلسل الطبقات
public function __construct(private ?EvaluationBrandingConfig $evaluationBrandingConfig = null)
public function evaluate(?LicenseKey $license, ?DateTimeImmutable $now = null): EntitlementResult
public function evaluateEnforced(?LicenseKey $license, EnforcementOutcome $outcome): EntitlementResult
public function resolveBrandingMode(?LicenseKey $license, ?DateTimeImmutable $now = null): BrandingMode
public function resolveBrandingStrategy(?LicenseKey $license, ?DateTimeImmutable $now = null): BrandingStrategy
public function __construct(private readonly LicenseStateCache $licenseCache, private readonly EntitlementResolver $entitlementResolver, private readonly string $upgradeInfoUrl = self::DEFAULT_UPGRADE_URL)
public function isFeatureEnabled(string $feature): bool
public function requireFeature(string $feature): void
public function currentEdition(): ?string
public function isLicenseValid(): bool
public function isInGracePeriod(): bool
public function hasCapability(CapabilityCode $capability): bool
public function requireCapability(CapabilityCode $capability): void
public function getActivePacks(): array
public function trialPolicy(): TrialPolicy
public function __construct(private readonly ClientInterface $httpClient, private readonly RequestFactoryInterface $requestFactory, private readonly StreamFactoryInterface $streamFactory, private readonly StatusX5cValidator $statusValidator, private readonly string $baseUrl = self::DEFAULT_BASE_URL, #[SensitiveParameter] private readonly ?string $apiKey = null, array $pinnedPublicKeys = [], array $backupPins = [], private readonly OutboundHttpPolicy $policy = new OutboundHttpPolicy(allowedSchemes: ['https'], connectTimeoutSeconds: 10, readTimeoutSeconds: 30, maxResponseBytes: 10_485_760, followRedirects: false, allowPrivateTargets: false, retryAttempts: 0, retryBaseBackoffMs: 250))
public function activate(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponse
public function heartbeat(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponse
public function deactivate(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponse
public function verifyOnline(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponse
public function getPinSet(): ?PinSet
public function checkRenewal(string $licenseId, string $customerId): array

يُنتج تقييم الاستحقاق إحدى خمس حالات راهنة، لكلٍّ منها نتيجة ثابتة في وقت التشغيل:

الحالةوقت التشغيلالقدرات الفعّالةالتحديثات / الدعمالعلامة التجارية
Activeمسموحالإصدار المُستحَقّ + الحِزم النشطةنعم (مدفوع)؛ لا (تقييم)لا شيء (مدفوع)؛ علامة مائية (تقييم)
GracePeriodمسموحالإصدار المُستحَقّ + الحِزم النشطةنعملا شيء (مدفوع)
DowngradedToCoreمسموح⁨Core⁩ فقطلالا شيء (مدفوع)؛ علامة مائية (تجربة)
EvaluationExpiredمقيَّدلا شيءلاعلامة مائية
NoLicenseمُعطَّل (مغلق عند الفشل)لا شيءلاعلامة مائية
  • انتهاء المدفوع لا يُعطِّل أبدًا وقت التشغيل المُثبَّت. تبقى runtimeAllowed صادقة في كل حالة مدفوعة. وبعد نافذة السماح يُخفَّض الإصدار الفعّال إلى ⁨Core⁩: تستمرّ قدرات ⁨Core⁩ في العمل بلا حدّ، وتُحجَب كل قدرات ⁨Pro⁩/⁨Enterprise⁩/الحِزم، وتُلغى التحديثات والدعم. وتُسمّي حالة EntitlementStatus::PerpetualFallback المُهمَلة سياسة الانتهاء لما قبل ⁨6.0⁩، وهي موجودة فقط لتوافق التصريف.
  • لا تنتهي كل حالة بتنفيذ ⁨Core⁩. يُبقي السماح على الإصدار المُستحَقّ الكامل مع تحذير تجديد مؤرَّخ. ويُقيِّد انتهاء التقييم وقت التشغيل ويُبقي العلامة المائية. وتُعطِّل حالة «لا ترخيص» مسارات ⁨Enterprise⁩ مغلقةً عند الفشل وتضع علامة مائية ظاهرة على أي مخرَج قديم، فلا يمكن أن تمرّ أبدًا بوصفها تنفيذًا مدفوعًا.
  • ترتيب حلّ ثابت. الترخيص المنتهي بالكامل لا يحلّ أي قدرة. وتؤجَّل قدرات الحزمة إلى حالة الحزمة النشطة الخاصة بها وانتهائها المستقلّ. وتُحلّ قدرات الإصدار إزاء الإصدار الفعّال المُنفَّذ على التسلسل الصارم ⁨Enterprise ⊇ Pro ⊇ Core⁩. ولا يُستشار LicenseKey::$edition الخام أبدًا للحجب.
  • مؤقّتان؛ والأشدّ تقييدًا يفوز. يقود مؤقّت الاستحقاق (كلتا القناتين) الحالات ⁨Active⁩ و⁨Grace⁩ والتخفيض إلى ⁨Core⁩ بعد السماح. ولا ينطبق مؤقّت الحيوية عبر الإنترنت إلا على قناة ioncube بوضع اتصال required: إذ يجب أن تكون المدّة، إضافةً إلى مهلة حيوية مدّتها 48 ساعة، حيّة. وفي وضع عدم الاتصال بعد انقضاء المدّة، يتوقّف المميَّز مؤقّتًا عند طبقة ⁨Core⁩؛ ثم يُعيد فحصٌ لاحق مُتحقَّق منه عبر الإنترنت إرساء المدّة فيستأنف المميَّز. أمّا قناة signed_source — وأي وضع اتصال غير required — فلا مؤقّت حيوية لها وتبقى قادرة على العمل دون اتصال وفي بيئة معزولة.
  • مكافحة الإرجاع حتمية. يُقيَّم الإنفاذ إزاء أرضية رتيبة: فالوقت الفعّال هو الأقصى بين ساعة النظام وآخر وقت مُتحقَّق منه، فلا يمنح تغييرُ الساعة إلى الوراء وقتًا إضافيًا. والإرجاع الذي يتجاوز تفاوت الانحراف والسماح المتبقّي يفرض التخفيض إلى ⁨Core⁩.
  • تتقدّم المدد بالوقت الموثوق فقط. يسجّل الفحص الناجح عبر الإنترنت وقت الخادم المُتحقَّق منه والموقَّع، لا الساعة المحلّية أبدًا، فلا يمكن لقفزة ساعة محلّية إلى الأمام أن تضخّم المدّة.
  • للعلامة التجارية سلطة واحدة. قناة التقييم وحدها تُطلِق العلامة المائية. والترخيص المدفوع يحلّ إلى بلا علامة تجارية في كل حالة، بما فيها الحالات المُخفَّضة.
  • التجربة طبقة سياسة على المؤقّتات نفسها. يُحدّ معدّل المعالجة (الافتراضي صفحتان في الثانية)، وتُطبَّق علامة التقييم المائية، والانتهاء صارم بلا سماح. ولا يتغيّر سوى السبب المُبلَّغ عنه؛ أمّا القرار والإصدار الفعّال فيتبعان الآلة المدفوعة.
  • العقد عبر الإنترنت موقَّع من طرف إلى طرف. يحمل كل طلب رمزًا عشوائيًا للعميل من ⁨CSPRNG⁩. وكل استجابة هي ⁨JWS⁩ مضغوط بـ⁨EdDSA⁩ من نوع الوسائط application/nextpdf-status+jwt، يُتحقَّق منه عبر سلسلة ⁨x5c⁩ إلى جذر مُثبَّت مُدمَج في التصريف، ومربوط بالرمز العشوائي المُرسَل، ومُعرِّف الترخيص المُثبَّت، ونقطة النهاية المُستدعاة. وقد أُحيل نقل الغلاف غير الموقَّع القديم إلى التقاعد؛ ولم يبقَ سوى مسار ثقة واحد بالضبط. وتنتقل تثبيتات ⁨SPKI⁩ المُهيَّأة في ترويسة X-NextPDF-Pinned-Public-Key، ويجب أن تتضمّن مجموعة التثبيت تثبيتًا احتياطيًا.
  • لا إنفاذ للمقاعد في وقت التشغيل. maxSlots تعاقدي فقط — لا قياس بُعدي ولا اتصال بيتي إلزامي للتشغيل العادي.

الحالات الحدّية وأوضاع الفشل

قسم بعنوان «الحالات الحدّية وأوضاع الفشل»
  • فحص القدرة على ترخيص منتهٍ بالكامل يختصر إلى «غير متوفّر» قبل تشغيل أي منطق حزمة أو إصدار.
  • يمكن أن تنتهي حزمة إضافية بينما الترخيص الأساسي نشط. وعندها يُقرأ الرفض «حزمة منتهية» (SPEC-LIC-002)، لا «غير مُرخَّص» (SPEC-LIC-001)، ويُدرِج الحِزم النشطة حاليًا.
  • ملفّ حالة إنفاذ محلّي حاضر لكن يتعذّر قراءته أو تحليله إشارة تلاعب. وتفشل الآلة مغلقةً إلى التخفيض إلى ⁨Core⁩ مع EnforcementReason::CorruptState. أمّا الملفّ الغائب لسبب مشروع فليس فاسدًا ويمضي على نحو طبيعي.
  • إرجاع الساعة إلى ما دون الأرضية الرتيبة بما يتجاوز تفاوت الانحراف (الافتراضي 120 ثانية) والسماح المتبقّي يفرض التخفيض إلى ⁨Core⁩ على نحو حتمي.
  • مدّة حيوية منقضية تُخفِّض ترخيص ioncube نشطًا لولا ذلك؛ وانتهاء الاستحقاق يُخفِّض بصرف النظر عن حالة المدّة.
  • evaluate(null) مغلق عند الفشل: وقت التشغيل غير مسموح، وتُطبَّق العلامة المائية، ويذكر التحذير عنوان ⁨URL⁩ الخاص بالتسعير. والمضيفون الذين يحتاجون سلوك ⁨Core⁩ غير المرخَّص عليهم إنشاء محرّك ⁨Core⁩ مباشرةً.
  • ترخيص التقييم المنتهي بلا سماح وبلا احتياط؛ ووقت التشغيل مقيَّد وتبقى العلامة المائية.
  • يعامل checkRenewal() رمز ⁨HTTP⁩ 404 بوصفه الجواب المعتاد «لا يوجد متوفّر». وأي رمز آخر غير 200 يرفع LicenseClientException، وdownload_url الذي يخالف السياسة الصادرة يفشل مغلقًا قبل أن يفلت من الطريقة.
  • استجابة حالة مزوّرة، أو مُلاعَب بها، أو قديمة، أو خاطئة الرمز العشوائي، أو خاطئة الترخيص لا تُنتج أبدًا StatusResponse؛ إذ يرمي التحقّق SpectrumAuthenticationException. أمّا حالة موقَّعة لكنها revoked أو expired أو released فتُتحقَّق وتظهر بوصفها إشارة تخفيض (isLive() خاطئة).
  • تُرفَض استجابة حالة سُكَّت لتبادل مختلف: إذ يجب أن يطابق response_type المُتحقَّق منه نقطة النهاية المُستدعاة.
  • يفشل FeatureGate مغلقًا عند أي خطأ في المُحلِّل: إذ يتدهور الإصدار الفعّال إلى core ولا تُمنَح أي قدرة مميَّزة.
  • EnforcedEntitlementResolver مغلق عند الفشل من طرف إلى طرف: إذ يُنتج أي استثناء في سلسلته نتيجة «لا ترخيص» (‏⁨Core⁩) وسجلّ خطأ ⁨PSR-3⁩، ولا يمنح أبدًا امتيازًا.

لا تضيف طبقة الترخيص أي سياسة تشفير خاصة بها. وتواقيع الترخيص والحالة هي تحقّقات ⁨Ed25519⁩ يجريها مزوّد التشفير في المضيف. وفي بناء مقيَّد بـ⁨FIPS⁩، تفشل خوارزمية لا يعتمدها المزوّد عند حدّ التشفير بخطأ صريح؛ ولا يُخفَّض أي شيء بصمت. وهذه مطالبات قدرة بشأن كود ⁨NextPDF⁩: فـ⁨NextPDF⁩ ليس وحدة تشفير مُصدَّقًا عليها، ولا يحمل أي اعتماد، ولا يمنح أيًّا منه.

المطالبةالمعيارالبند
ملفّات الترخيص واستجابات الحالة هي ⁨JWS⁩ بتسلسل مضغوط، يُتحقَّق منها مغلقةً عند الفشل.RFC 7515§3.1
تواقيع الترخيص والحالة هي ⁨Ed25519⁩.RFC 8032§5.1
تتحقّق سلسلة ⁨x5c⁩ في استجابة موقَّعة رجوعًا إلى مرتكز ثقة مُثبَّت مُدمَج في التصريف.RFC 5280§6.1
يجب أن تتضمّن مجموعة تثبيت ⁨SPKI⁩ مُهيَّأة تثبيتًا احتياطيًا لمفتاح لم يُنشَر بعد.RFC 7469§4.3
المطالبات المُتحقَّق منها (iss وaud وexp وnbf وiat) هي أسماء مطالبات مُسجَّلة.RFC 7519§4.1

كل البنود مُعاد صياغتها؛ ولا يُعاد إنتاج أي نصّ معياري. ‏⁨NextPDF⁩ لا يقدّم أي ادّعاء اعتماد. والدعم لا يساوي المطابقة، والمطابقة لا تساوي الاعتماد. وتوائم الوحدة سلوكها مع البنود المُستشهَد بها بوصفه قدرة؛ وقبول غلاف ترخيص أو حالة يقرّره مُتحقِّق الجذر المُثبَّت الخاص بـ⁨NextPDF⁩، لا سلطة خارجية.

  • أنشِئ LicenseClient بنقل يفرض السياسة (قانونيًا SecurityAwareHttpClient). ويُرفَض عميل ⁨PSR-18⁩ خام عند الإنشاء كي لا تُرسَل حركة الترخيص أبدًا دون ضوابط مكافحة ⁨SSRF⁩، وعدم إعادة التوجيه، وسقف البايتات، والمُهَل.
  • يجب أن يفكّ الرمز العشوائي للعميل الذي يقدّمه المستدعِي إلى 16 بايت على الأقل من العشوائية. ويؤسّس المصدر هذا الحدّ على RFC 8555 §⁨6.5⁩؛ وهذا البند خارج المتن المُستشهَد به، فالحدّ مذكور هنا من مصدر المنتج فقط.
  • احجُب الميزات عبر FeatureGate؛ ولا تتفرّع أبدًا على LicenseKey::$edition الخام. فالبوّابة لا تستشير سوى الإصدار الفعّال المُنفَّذ وتفشل مغلقةً إلى core.
  • لا تُبدِّل على EntitlementStatus::PerpetualFallback المُهمَلة في كود جديد. بل اختبر isDowngradedToCore() أو طابِق DowngradedToCore بدلًا منها.
  • عامِل رفض القدرة حمولة معالجة. وأظهِر للمستدعِي سياقها المُهيكَل وعنوان ⁨URL⁩ الترقية بدلًا من اختزالها إلى خطأ عام.
  • تتعلّق هذه الوحدة بوظيفة تشفير؛ فعامِلها بوصفها حسّاسة أمنيًا في مراجعتك الخاصة. وتحكم شروطَ السعة والمقاعد اتفاقيةُ الترخيص، لا الإنفاذ في وقت التشغيل. وهذا المرجع ليس رأيًا قانونيًا؛ استشر مستشاري الامتثال والقانون لديك.

توثّق هذه الصفحة السلوك القابل للملاحظة خارجيًا وسطح واجهة برمجة التطبيقات العامة المدعوم فقط. أمّا مسارات نطاقات الأسماء الداخلية، وأصناف المساعدة، وجداول الآلية، وأسماء ملفّات أدلّة التشغيل، وبادئات التذاكر فخارج النطاق.