Commit 71bf563
authored
v2.4.0: license activation required (BREAKING CHANGE) (#2530)
* feat(licensing): mirror evolution-go license activation system
Phase 1 of the licensing rollout — backend only. Brings the same
activation lifecycle that already exists in evolution-go (pkg/core)
into evolution-api as src/licensing/, plus a public /license/* router
and a gate middleware that 503s API traffic until activation.
Module layout (mirrors pkg/core/*.go):
- src/licensing/model.ts (config keys, type contracts)
- src/licensing/store.ts (Prisma RuntimeConfig CRUD + hardware-based instance ID)
- src/licensing/endpoint.ts (XOR-decoded URL with parts-array dev fallback)
- src/licensing/transport.ts (axios + HMAC-SHA256 signing)
- src/licensing/integrity.ts (paridade-only stubs - Baileys does not consume)
- src/licensing/runtime.ts (RuntimeContext, initializeRuntime, gateMiddleware,
heartbeat, shutdown, completeActivation)
Public routes (no auth) - same contract as evolution-go:
- GET /license/status -> {status, instance_id, api_key (masked)}
- GET /license/register?redirect_uri -> POST /v1/register/init upstream
- GET /license/activate?code= -> POST /v1/register/exchange + activate
Bootstrap order in src/main.ts:
1. setDB(prisma)
2. initializeRuntime({tier: 'evolution-api', version, globalApiKey})
3. /license router (always public)
4. gateMiddleware (503 LICENSE_REQUIRED before business routers)
5. business routers
6. startHeartbeat (30 min, fire-and-forget)
7. SIGTERM/SIGINT -> POST /v1/deactivate (best-effort)
Behaviour notes:
- AUTHENTICATION_API_KEY is reused as bootstrap key (mirrors GLOBAL_API_KEY in Go).
If a license already exists in the DB, the service runs locally even if the
licensing server is unreachable.
- Gate middleware allowlist: /license/*, /manager/**, /assets/**, /store/**,
/health, /server/ok, /favicon.ico, /ws, common static extensions.
- Heartbeat carries optional telemetry_bundle with messages_sent / messages_recv
that callers can feed via trackMessageSent() / trackMessageRecv().
Schema:
- New Prisma model RuntimeConfig (key/value) on both postgresql and mysql schemas.
Run npm run db:migrate:dev per provider before starting the service.
Endpoint URL ofuscation:
- Set LICENSE_ENDPOINT_ENCODED + LICENSE_ENDPOINT_XOR_KEY (hex) in release builds
to avoid the licensing URL appearing as a plain string in the bundle.
- Dev fallback assembles license.evolutionfoundation.com.br from a parts array,
same technique as evolution-go.
Phase 2 (manager-v2 UI for the activation flow) lands in a separate PR
under evolution-foundation/evolution-manager-v2.
* feat(licensing): add Prisma migration for RuntimeConfig table
Adds the database migration that creates the licensing storage table
(postgres + mysql). This was missing from the previous licensing commit.
Without this migration, npm run db:deploy is a no-op and the server
will fail to find the table at boot.
* release: 2.4.0 - license activation required
Polishes the licensing rollout for public release:
- Better error UX: HTTP 503 now carries instance_id, docs_url and an
actionable message instructing the operator to open the manager UI
or set AUTHENTICATION_API_KEY in .env.
- Better boot banner: lists the activation paths (manager UI, env var)
with the docs URL and the instance_id.
- Auto-detect missing migration: if the RuntimeConfig table is absent,
the server prints a clear banner asking the operator to run
npm run db:deploy and exits 1, instead of throwing a Prisma stack
trace from inside the bootstrap.
- Version bump 2.3.7 -> 2.4.0.
- CHANGELOG entry with BREAKING CHANGE notice and migration guide.
- README section 'License Activation' linking to
docs.evolutionfoundation.com.br/licensing.
* build(manager): refresh manager/dist with v2.4.0 bundle
- Bumps the embedded manager UI to the version published on
evolution-foundation/evolution-manager-v2 main, which now includes
the license-aware login flow that mirrors evolution-go-manager.
- Removes the legacy manager/dist/assets/test-interactive.js stand-alone
script — its functionality is now a proper React component
(TestInteractiveModal) inside the bundle, accessed from the instance
card on the dashboard.
- Updates the manager-v2 submodule pointer to track main.
* style(licensing): apply prettier/eslint autofix and hoist DOCS_URL
The autofix from the pre-push hook reorders imports, normalizes line
breaks and reformats the constructor signature. Also moves DOCS_URL to
the top of the module so the auto-detect error path can reference it
without hitting the temporal dead zone.
* feat(licensing): bake licensing endpoint into bundle at build time
Mirrors evolution-go/tools/build-dist/obfuscate.go: the URL of the licensing
server is now XOR-encoded into the JS bundle by tsup `define`, so it never
appears as a plain literal in dist/main.js. The Dockerfile accepts the pair
as build-args (NOT runtime env vars) so an operator cannot point the running
service at a different licensing server.
- src/licensing/endpoint.ts: read from compile-time `__LICENSE_ENDPOINT_*__`
identifiers replaced by tsup; keep parts-array fallback for dev builds.
- tsup.config.ts: `define` reads LICENSE_ENDPOINT_ENCODED / _XOR_KEY from
build env at the moment npm run build is invoked.
- tools/encode-url.js: helper to generate the hex pair for a given URL.
Usage: eval "$(node tools/encode-url.js <url>)".
- Dockerfile: ARG + ENV plumbing for the build stage only.
- CHANGELOG: notes about the build-time obfuscation.
* chore: drop evolution-manager-v2 submodule
The manager-v2 source repository is now private, so the CI checkout step
fails when trying to fetch the submodule (no PAT configured, GITHUB_TOKEN
has no cross-repo read scope). Drop the submodule entirely — the runtime
artefact already lives under manager/dist/ in this repo, which is what
the Express server serves. Source for the manager continues to be
maintained at evolution-foundation/evolution-manager-v2 (private).
* style(licensing): prettier autofix on endpoint.ts
* docs(changelog): expand 2.4.0 entry with all features since 2.3.7
Previous entry only covered the licensing rollout. The release actually
includes 50 commits worth of work:
- Manager v2 completely redesigned (Tailwind v4 + @evoapi/design-system,
dual-provider support, advanced sessions panels, license flow,
Test Interactive modal, full i18n).
- Carousel message endpoint (POST /message/sendCarousel).
- Cross-client fix for buttons and list rendering on WhatsApp
Web/Desktop/iOS via the <biz> stanza node and the legacy listMessage
payload.
- Interactive buttons via deviceSentMessage with corrected CTA limits
and PIX payment_info support.
- Catalog orderMessage and quoted productMessage support.
- New messaging-history.set event with cumulative counts.
- markMessageAsPlayed audio receipt endpoint.
- SQS custom base_url.
- LID -> phone-number mapping with cache.
- Multiple bug fixes (mentionsEveryOne, getLastMessage, markMessageAsRead,
list-message JSON cloning, Cloud API race conditions, instance logout
idempotency, zombie-instance cleanup, network family timeout, etc.).1 parent 9a4ae2b commit 71bf563
27 files changed
Lines changed: 1802 additions & 942 deletions
File tree
- manager/dist
- assets
- prisma
- mysql-migrations/20260506184850_add_runtime_config
- postgresql-migrations/20260506184850_add_runtime_config
- src
- api/routes
- licensing
- tools
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
1 | 248 | | |
2 | 249 | | |
3 | 250 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
34 | 44 | | |
35 | 45 | | |
36 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
127 | 154 | | |
128 | 155 | | |
129 | 156 | | |
| |||
This file was deleted.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments