Download the PHP package nextdevit/ndit-license-client without Composer

On this page you can find all versions of the php package nextdevit/ndit-license-client. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package ndit-license-client

nextdevit/ndit-license-client

The client half of the NDIT licensing system: one Laravel package installed inside every Type A (self-hosted) NextDevIT product. The Hub issues Ed25519-signed licenses; this package consumes them — activation, signature verification, local storage, the 72-hour heartbeat, state resolution and entitlement gating.

The design law, in one sentence: the package owns mechanism, the product owns policy. It knows how to verify a signature, count down grace and answer NditLicense::can('module.x'). It has no opinion about what locking module.x means. Each product wires the events, middleware and gates below to its own feature boundaries — its degrade map.

Two consequences worth internalising before you wire anything:

Customers receive the full source of this package. That is deliberate: it holds no secrets, only public keys. Its protective value comes from unforgeable server responses, gates scattered at feature boundaries, and the moats enforced server-side — not from hiding code.


Requirements

PHP ≥ 8.2, with ext-sodium (bundled since PHP 7.2)
Laravel 12 or 13
Dependencies illuminate/* only — zero third-party packages
Network Outbound 443 to app.nextdevit.com (a blocked host degrades gracefully, see Troubleshooting)

Works on hostile hosting by design: database queues, cron-only scheduling, no Redis, shared hosting.


Install

Published on Packagist — no repositories entry needed.

The service provider is auto-discovered and the migration loads itself — a fresh install answers ndit-license:status with never_activated and nothing else is required to boot.


Configure

Env var Default Notes
NDIT_LICENSE_PRODUCT — Required. Hub product slug; must equal the token's product claim
NDIT_LICENSE_API_BASE https://app.nextdevit.com/api/v1/license Must be https
NDIT_LICENSE_KEY_K1 production k1 Base64 Ed25519 public key. Set it only when NDIT_LICENSE_API_BASE points at your own Hub — key and Hub move together
NDIT_LICENSE_DRIVER live live or fake
NDIT_LICENSE_FAKE_SCENARIO active See the fake driver table below
NDIT_LICENSE_ALLOW_FAKE false Escape hatch for a deliberate production demo
NDIT_LICENSE_PRODUCT_VERSION — Reported in telemetry
NDIT_LICENSE_CONNECT_TIMEOUT / NDIT_LICENSE_TIMEOUT 5 / 15 Seconds

Platform policy — 72 h heartbeat, 14 d grace, 30 d token, ±48 h clock tolerance — is hardcoded as defaults. Override keys exist for emergencies and are never varied in practice.

Publish tags: ndit-license-config · ndit-license-migrations · ndit-license-vue · ndit-license-lang


Wire it

a. The activation page

The package ships a Vue component and no route, because where activation lives is a product decision.

The whole controller recipe:

Then decide where — if anywhere — a never-activated install should be pushed to that page:

ndit-licensed is registered as an alias and applied nowhere by default. Leave your point-of-sale, checkout or any other business-critical route out of it. A customer whose license server is unreachable must still be able to serve their customers.

b. Gates

Four ways to ask the same pure question:

entitled: answers a JSON request with 403 {code, entitlement, state}. For web requests it returns a plain 403, or — if you set ndit-license.routes.locked_redirect — redirects there with the blocked entitlement flashed as ndit-license.locked, which is what you want for an upsell page.

Share state with the front end once, in your Inertia middleware:

shareable() gives you state, entitlements, key_masked, grace countdown, renewal countdown, upsell_url and a banner with a translation key and params — everything a banner or settings page needs, with no raw key anywhere in it.

c. Your degrade map

Listen to these seven events and decide what each one means for your product:

Event Payload Typically
LicenseActivated claims, domain Seed module registry, finish setup wizard
LicenseValidated claims, previous previous was grace/degraded ⇒ this IS the recovery signal
EnteredGrace lastValidatedAt, daysLeft Start warning; change nothing else
LicenseDegraded lastValidatedAt Switch off non-essential modules
LicenseRevoked reason (revoked|expired) Same lock, different copy
LicenseDeactivated source (local|remote|limit_reached) Back to the activation page
EntitlementsUpdated old, new Add or retire modules — no customer action

Design your map so that every state leaves the customer's core business workable. Grace and degraded are for feature reduction, never for a locked front door.

d. Scheduling

The command no-ops internally until the window opens, so any frequency is safe.

For hosts whose cron is dead or throttled, append the opportunistic middleware to an admin group. It dispatches a queued job when a check is overdue and returns immediately — it never makes an admin wait on a network call:

e. Telemetry disclosure

Every activation and heartbeat sends exactly this:

Field Value
product_version NDIT_LICENSE_PRODUCT_VERSION
php PHP_VERSION
laravel Framework version

Plus the license key, product slug, domain and instance UUID that the call is about. No customer data, no usage data, no PII.

Add product-specific fields from a service provider:

Registered at runtime, so it survives config:cache. Whatever you add here, document it in your product's own privacy notes. That rule is not optional.


The fake driver

Set NDIT_LICENSE_DRIVER=fake and your entire licensing integration becomes CI-testable — including tamper, grace, revoke and limit-reached — with no Hub.

Fixture responses are signed with a committed test keypair and travel the exact production verification path, so a tamper test tests something real.

NDIT_LICENSE_FAKE_SCENARIO What you get
active Everything works
grace Activates, then backdates 4 days: grace banner without time travel
degraded Activates, then backdates 15 days
revoked Validate returns a signed revoked negative
invalid_key Every endpoint answers invalid_key 401
limit_reached Activation blocked with a plausible activation summary
updates_expired License fine, downloads refused with a renewal link
unreachable Throws the same ConnectionException the live transport does

Two extra switches reach codes no scenario owns: ndit-license.fake.force_rate_limit (429 + retry_after) and ndit-license.fake.force_error (e.g. wrong_product, not_activated).

The fake driver refuses to construct in production unless NDIT_LICENSE_ALLOW_FAKE=true.


Commands

Command Purpose
ndit-license:activate {key} {--domain=} Scripted activation. Exit 0 activated · 1 the Hub said no · 2 no trustworthy answer, retry later
ndit-license:status Full local report: state, masked key, entitlements, dates, next heartbeat window
ndit-license:heartbeat {--force} Scheduler entry. Exits 0 even on failure (a failed heartbeat is normal grace behaviour); --force exits 1 so a human gets an answer
ndit-license:deactivate {--confirm} Frees the activation slot and clears the local license

Troubleshooting

"Grace" or "Limited" banner, and the customer swears nothing changed. The server cannot reach app.nextdevit.com:443. Grace lasts 14 days from the last successful validation, then features reduce. Run ndit-license:heartbeat --force to see the actual error. Nine times in ten it is an outbound firewall rule or a DNS change on the host.

Clock skew. Tokens are rejected if iat is more than 48 hours from the server's clock. A wildly wrong server clock looks exactly like an unreachable Hub. Check date on the box.

"All activation slots are in use." The license is active on other domains. The error carries the list with last-seen dates — free one in the customer portal and retry. Dev and staging domains do not consume slots.

APP_KEY was rotated. The stored key becomes unreadable, heartbeats stop and the install slides into grace with a "re-activate" banner. Re-activating with the same key is enough: the instance UUID lives in a plain column, so the same Hub slot is reused rather than a new one consumed.

A cloned database. The clone reuses the instance UUID but presents a new domain, which triggers the re-activation flow — by design.


Security posture


Versioning

Semver. Private repo, consumed via a Composer VCS entry.

Version Meaning
v0.1.0 Fake driver complete — a product can build and CI-test its whole integration
v0.2.0 Heartbeat, events, commands, activation UI
v1.0.0 Live driver verified against Hub staging

Supported: PHP 8.2 / 8.3 / 8.4 × Laravel 12 / 13.

CI runs the full suite on all five combinations that can exist. PHP 8.2 with Laravel 13 is not one of them — Laravel 13 itself requires PHP ≥ 8.3.

Key rotation is a minor release: a k2 entry is added to keys and both are accepted while the Hub migrates.


All versions of ndit-license-client with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
ext-sodium Version *
illuminate/console Version ^12.0|^13.0
illuminate/contracts Version ^12.0|^13.0
illuminate/database Version ^12.0|^13.0
illuminate/events Version ^12.0|^13.0
illuminate/http Version ^12.0|^13.0
illuminate/queue Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package nextdevit/ndit-license-client contains the following files

Loading the files please wait ...