Skip to content

Commit d91f2d7

Browse files
committed
transport cleanup
1 parent b0b7dbc commit d91f2d7

7 files changed

Lines changed: 121 additions & 69 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [Unreleased]
6+
7+
### Changed
8+
- Breaking: renamed the public transport struct from `Subscription` to `WebPushSubscription` everywhere with no compatibility alias.
9+
- Breaking: renamed `PushMessage.sub` to `PushMessage.subscription` for API consistency.
10+
- Breaking: removed app-level metadata fields `deviceId`, `disabledTags`, and `deleted` from the transport struct.
11+
- `validateSubscription()` now validates only the required Web Push transport fields: `endpoint`, `p256dh`, and `auth`.
12+
513
## [2.0.0] - 2026-03-28
614

715
### Added

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ void loop() {}
5353

5454
## Usage
5555

56-
### Subscription / Structured Payload
56+
### WebPushSubscription / Structured Payload
5757

5858
```cpp
59-
Subscription sub;
60-
sub.endpoint = "https://fcm.googleapis.com/fcm/send/...";
61-
sub.p256dh = "BME...";
62-
sub.auth = "nsa...";
59+
WebPushSubscription subscription;
60+
subscription.endpoint = "https://fcm.googleapis.com/fcm/send/...";
61+
subscription.p256dh = "BME...";
62+
subscription.auth = "nsa...";
6363

6464
PushPayload payload;
6565
payload.title = "Hello";
@@ -71,7 +71,7 @@ payload.icon = "https://example.com/icon.png";
7171
### Async Send
7272

7373
```cpp
74-
WebPushEnqueueResult enqueue = webPush.send(sub, payload, [](WebPushResult result) {
74+
WebPushEnqueueResult enqueue = webPush.send(subscription, payload, [](WebPushResult result) {
7575
if (!result.ok()) {
7676
ESP_LOGE("WEBPUSH", "Push failed: %s (status %d)",
7777
result.message, result.statusCode);
@@ -95,13 +95,13 @@ doc["title"] = "Hello";
9595
doc["body"] = "ESP32";
9696
doc["tag"] = "demo";
9797

98-
WebPushResult result = webPush.send(sub, doc);
98+
WebPushResult result = webPush.send(subscription, doc);
9999
```
100100

101101
### Sync Send
102102

103103
```cpp
104-
WebPushResult result = webPush.send(sub, payload);
104+
WebPushResult result = webPush.send(subscription, payload);
105105
if (!result.ok()) {
106106
ESP_LOGW("WEBPUSH", "Sync push failed: %s", result.message);
107107
}
@@ -111,7 +111,7 @@ if (!result.ok()) {
111111

112112
```cpp
113113
PushMessage msg;
114-
msg.sub = sub;
114+
msg.subscription = subscription;
115115
msg.payload = "{\"title\":\"Hello\",\"body\":\"ESP32\"}";
116116

117117
// Raw payload strings remain supported, but they are not schema-validated.
@@ -156,12 +156,12 @@ if (webPush.isInitialized()) {
156156
- `bool init(const WebPushVapidConfig&, const WebPushConfig& = {})`
157157
- `WebPushEnqueueResult send(const PushMessage&, WebPushResultCB cb)`
158158
- `WebPushResult send(const PushMessage&)`
159-
- `WebPushEnqueueResult send(const Subscription&, const PushPayload&, WebPushResultCB cb)`
160-
- `WebPushResult send(const Subscription&, const PushPayload&)`
161-
- `WebPushEnqueueResult send(const Subscription&, const JsonDocument&, WebPushResultCB cb)`
162-
- `WebPushResult send(const Subscription&, const JsonDocument&)`
163-
- `WebPushEnqueueResult send(const Subscription&, JsonVariantConst, WebPushResultCB cb)`
164-
- `WebPushResult send(const Subscription&, JsonVariantConst)`
159+
- `WebPushEnqueueResult send(const WebPushSubscription&, const PushPayload&, WebPushResultCB cb)`
160+
- `WebPushResult send(const WebPushSubscription&, const PushPayload&)`
161+
- `WebPushEnqueueResult send(const WebPushSubscription&, const JsonDocument&, WebPushResultCB cb)`
162+
- `WebPushResult send(const WebPushSubscription&, const JsonDocument&)`
163+
- `WebPushEnqueueResult send(const WebPushSubscription&, JsonVariantConst, WebPushResultCB cb)`
164+
- `WebPushResult send(const WebPushSubscription&, JsonVariantConst)`
165165
- `void requestStop()`
166166
- `WebPushJoinStatus join(uint32_t timeoutMs)`
167167
- `void setNetworkValidator(WebPushNetworkValidator)`

examples/basic_web_push/basic_web_push.ino

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ void setup() {
2828

2929
webPush.init(vapid, cfg);
3030

31-
Subscription sub;
32-
sub.endpoint = "https://fcm.googleapis.com/fcm/send/...";
33-
sub.p256dh = "BMEp256dhBase64Url...";
34-
sub.auth = "authSecretBase64Url...";
31+
WebPushSubscription subscription;
32+
subscription.endpoint = "https://fcm.googleapis.com/fcm/send/...";
33+
subscription.p256dh = "BMEp256dhBase64Url...";
34+
subscription.auth = "authSecretBase64Url...";
3535

3636
PushPayload payload;
3737
payload.title = "Hello";
3838
payload.body = "ESP32";
3939
payload.tag = "basic-demo";
4040
payload.icon = "https://www.esptoolkit.hu/icon.png";
4141

42-
WebPushEnqueueResult enqueue = webPush.send(sub, payload, [](WebPushResult result) {
42+
WebPushEnqueueResult enqueue = webPush.send(subscription, payload, [](WebPushResult result) {
4343
if (!result.ok()) {
4444
Serial.printf(
4545
"[webpush] async failed: %s (status %d)\n",
@@ -63,7 +63,7 @@ void setup() {
6363
jsonPayload["body"] = "ESP32";
6464
jsonPayload["tag"] = "basic-demo";
6565

66-
WebPushResult syncResult = webPush.send(sub, jsonPayload);
66+
WebPushResult syncResult = webPush.send(subscription, jsonPayload);
6767
if (!syncResult.ok()) {
6868
Serial.printf(
6969
"[webpush] sync failed: %s\n",

src/esp_webPush/webPush.cpp

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -237,17 +237,19 @@ WebPushResult ESPWebPush::send(const PushMessage &msg) {
237237
}
238238

239239
WebPushEnqueueResult ESPWebPush::send(
240-
const Subscription &sub, const PushPayload &payload, WebPushResultCB callback
240+
const WebPushSubscription &subscription, const PushPayload &payload, WebPushResultCB callback
241241
) {
242242
PushMessage message;
243243
WebPushResult result{};
244-
if (!buildMessage(sub, payload, message, result)) {
244+
if (!buildMessage(subscription, payload, message, result)) {
245245
return enqueueResultForError(result.error);
246246
}
247247
return send(message, std::move(callback));
248248
}
249249

250-
WebPushResult ESPWebPush::send(const Subscription &sub, const PushPayload &payload) {
250+
WebPushResult ESPWebPush::send(
251+
const WebPushSubscription &subscription, const PushPayload &payload
252+
) {
251253
if (_stopRequested.load(std::memory_order_acquire)) {
252254
return resultForError(WebPushError::ShuttingDown);
253255
}
@@ -257,34 +259,38 @@ WebPushResult ESPWebPush::send(const Subscription &sub, const PushPayload &paylo
257259

258260
PushMessage message;
259261
WebPushResult result{};
260-
if (!buildMessage(sub, payload, message, result)) {
262+
if (!buildMessage(subscription, payload, message, result)) {
261263
return result;
262264
}
263265
return send(message);
264266
}
265267

266268
WebPushEnqueueResult ESPWebPush::send(
267-
const Subscription &sub, const JsonDocument &payload, WebPushResultCB callback
269+
const WebPushSubscription &subscription, const JsonDocument &payload, WebPushResultCB callback
268270
) {
269-
return send(sub, payload.as<JsonVariantConst>(), std::move(callback));
271+
return send(subscription, payload.as<JsonVariantConst>(), std::move(callback));
270272
}
271273

272-
WebPushResult ESPWebPush::send(const Subscription &sub, const JsonDocument &payload) {
273-
return send(sub, payload.as<JsonVariantConst>());
274+
WebPushResult ESPWebPush::send(
275+
const WebPushSubscription &subscription, const JsonDocument &payload
276+
) {
277+
return send(subscription, payload.as<JsonVariantConst>());
274278
}
275279

276280
WebPushEnqueueResult ESPWebPush::send(
277-
const Subscription &sub, JsonVariantConst payload, WebPushResultCB callback
281+
const WebPushSubscription &subscription, JsonVariantConst payload, WebPushResultCB callback
278282
) {
279283
PushMessage message;
280284
WebPushResult result{};
281-
if (!buildMessage(sub, payload, message, result)) {
285+
if (!buildMessage(subscription, payload, message, result)) {
282286
return enqueueResultForError(result.error);
283287
}
284288
return send(message, std::move(callback));
285289
}
286290

287-
WebPushResult ESPWebPush::send(const Subscription &sub, JsonVariantConst payload) {
291+
WebPushResult ESPWebPush::send(
292+
const WebPushSubscription &subscription, JsonVariantConst payload
293+
) {
288294
if (_stopRequested.load(std::memory_order_acquire)) {
289295
return resultForError(WebPushError::ShuttingDown);
290296
}
@@ -294,7 +300,7 @@ WebPushResult ESPWebPush::send(const Subscription &sub, JsonVariantConst payload
294300

295301
PushMessage message;
296302
WebPushResult result{};
297-
if (!buildMessage(sub, payload, message, result)) {
303+
if (!buildMessage(subscription, payload, message, result)) {
298304
return result;
299305
}
300306
return send(message);
@@ -369,7 +375,10 @@ WebPushResult ESPWebPush::invalidPayloadResult() const {
369375
}
370376

371377
bool ESPWebPush::buildMessage(
372-
const Subscription &sub, const PushPayload &payload, PushMessage &message, WebPushResult &result
378+
const WebPushSubscription &subscription,
379+
const PushPayload &payload,
380+
PushMessage &message,
381+
WebPushResult &result
373382
) const {
374383
std::string serializedPayload;
375384
const char *payloadError = serializePushPayload(payload, serializedPayload);
@@ -379,13 +388,16 @@ bool ESPWebPush::buildMessage(
379388
return false;
380389
}
381390

382-
message.sub = sub;
391+
message.subscription = subscription;
383392
message.payload = std::move(serializedPayload);
384393
return true;
385394
}
386395

387396
bool ESPWebPush::buildMessage(
388-
const Subscription &sub, JsonVariantConst payload, PushMessage &message, WebPushResult &result
397+
const WebPushSubscription &subscription,
398+
JsonVariantConst payload,
399+
PushMessage &message,
400+
WebPushResult &result
389401
) const {
390402
std::string serializedPayload;
391403
const char *payloadError = validateAndSerializePushPayload(payload, serializedPayload);
@@ -395,7 +407,7 @@ bool ESPWebPush::buildMessage(
395407
return false;
396408
}
397409

398-
message.sub = sub;
410+
message.subscription = subscription;
399411
message.payload = std::move(serializedPayload);
400412
return true;
401413
}
@@ -423,22 +435,22 @@ WebPushResult ESPWebPush::handleMessage(const PushMessage &msg) {
423435
continue;
424436
}
425437

426-
std::vector<uint8_t> body = encryptPayload(msg.payload, msg.sub);
438+
std::vector<uint8_t> body = encryptPayload(msg.payload, msg.subscription);
427439
if (body.empty()) {
428440
result.error = WebPushError::EncryptFailed;
429441
result.message = errorToString(result.error);
430442
return result;
431443
}
432444

433-
const std::string aud = endpointOrigin(msg.sub.endpoint);
445+
const std::string aud = endpointOrigin(msg.subscription.endpoint);
434446
const std::string jwt = jwtForAudience(aud);
435447
if (jwt.empty()) {
436448
result.error = WebPushError::JwtFailed;
437449
result.message = errorToString(result.error);
438450
return result;
439451
}
440452

441-
WebPushResult request = sendPushRequest(msg.sub.endpoint, jwt, body);
453+
WebPushResult request = sendPushRequest(msg.subscription.endpoint, jwt, body);
442454
if (request.ok()) {
443455
return request;
444456
}
@@ -520,8 +532,10 @@ uint32_t ESPWebPush::calcRetryDelayMs(uint8_t attempt) const {
520532
return delay;
521533
}
522534

523-
bool ESPWebPush::validateSubscription(const Subscription &sub, WebPushResult &result) const {
524-
if (sub.deleted || sub.endpoint.empty() || sub.p256dh.empty() || sub.auth.empty()) {
535+
bool ESPWebPush::validateSubscription(
536+
const WebPushSubscription &subscription, WebPushResult &result
537+
) const {
538+
if (subscription.endpoint.empty() || subscription.p256dh.empty() || subscription.auth.empty()) {
525539
result.error = WebPushError::InvalidSubscription;
526540
result.message = errorToString(result.error);
527541
return false;
@@ -539,7 +553,7 @@ bool ESPWebPush::validatePayloadSize(const std::string &payload, WebPushResult &
539553
}
540554

541555
bool ESPWebPush::validateMessage(const PushMessage &msg, WebPushResult &result) const {
542-
if (!validateSubscription(msg.sub, result)) {
556+
if (!validateSubscription(msg.subscription, result)) {
543557
return false;
544558
}
545559
return validatePayloadSize(msg.payload, result);

src/esp_webPush/webPush.h

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,14 @@ struct WebPushVapidConfig {
3737
std::string privateKeyBase64;
3838
};
3939

40-
struct Subscription {
40+
struct WebPushSubscription {
4141
std::string endpoint;
4242
std::string p256dh;
4343
std::string auth;
44-
std::string deviceId;
45-
std::vector<std::string> disabledTags;
46-
bool deleted = false;
4744
};
4845

4946
struct PushMessage {
50-
Subscription sub;
47+
WebPushSubscription subscription;
5148
std::string payload;
5249
};
5350

@@ -161,17 +158,23 @@ class ESPWebPush {
161158
WebPushEnqueueResult send(const PushMessage &msg, WebPushResultCB callback);
162159
WebPushResult send(const PushMessage &msg);
163160
WebPushEnqueueResult send(
164-
const Subscription &sub, const PushPayload &payload, WebPushResultCB callback
161+
const WebPushSubscription &subscription,
162+
const PushPayload &payload,
163+
WebPushResultCB callback
165164
);
166-
WebPushResult send(const Subscription &sub, const PushPayload &payload);
165+
WebPushResult send(const WebPushSubscription &subscription, const PushPayload &payload);
167166
WebPushEnqueueResult send(
168-
const Subscription &sub, const JsonDocument &payload, WebPushResultCB callback
167+
const WebPushSubscription &subscription,
168+
const JsonDocument &payload,
169+
WebPushResultCB callback
169170
);
170-
WebPushResult send(const Subscription &sub, const JsonDocument &payload);
171+
WebPushResult send(const WebPushSubscription &subscription, const JsonDocument &payload);
171172
WebPushEnqueueResult send(
172-
const Subscription &sub, JsonVariantConst payload, WebPushResultCB callback
173+
const WebPushSubscription &subscription,
174+
JsonVariantConst payload,
175+
WebPushResultCB callback
173176
);
174-
WebPushResult send(const Subscription &sub, JsonVariantConst payload);
177+
WebPushResult send(const WebPushSubscription &subscription, JsonVariantConst payload);
175178

176179
void setNetworkValidator(WebPushNetworkValidator validator);
177180

@@ -203,19 +206,19 @@ class ESPWebPush {
203206
uint32_t calcRetryDelayMs(uint8_t attempt) const;
204207
bool waitForStopAwareDelay(uint32_t delayMs) const;
205208

206-
bool validateSubscription(const Subscription &sub, WebPushResult &result) const;
209+
bool validateSubscription(const WebPushSubscription &subscription, WebPushResult &result) const;
207210
bool validatePayloadSize(const std::string &payload, WebPushResult &result) const;
208211
bool validateMessage(const PushMessage &msg, WebPushResult &result) const;
209212
bool validateVapidSubject(WebPushResult &result) const;
210213
bool validateVapidKeys(WebPushResult &result);
211214
bool buildMessage(
212-
const Subscription &sub,
215+
const WebPushSubscription &subscription,
213216
const PushPayload &payload,
214217
PushMessage &message,
215218
WebPushResult &result
216219
) const;
217220
bool buildMessage(
218-
const Subscription &sub,
221+
const WebPushSubscription &subscription,
219222
JsonVariantConst payload,
220223
PushMessage &message,
221224
WebPushResult &result
@@ -276,7 +279,7 @@ class ESPWebPush {
276279

277280
std::vector<uint8_t> encryptPayload(
278281
const std::string &plaintext,
279-
const Subscription &sub
282+
const WebPushSubscription &subscription
280283
);
281284

282285
bool generateSalt(uint8_t *saltBin);

src/esp_webPush/webPush_crypto.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,20 +416,22 @@ bool ESPWebPush::buildRecordBody(
416416
return true;
417417
}
418418

419-
std::vector<uint8_t> ESPWebPush::encryptPayload(const std::string &plaintext, const Subscription &sub) {
419+
std::vector<uint8_t> ESPWebPush::encryptPayload(
420+
const std::string &plaintext, const WebPushSubscription &subscription
421+
) {
420422
std::lock_guard<std::mutex> guard(_cryptoMutex);
421423
if (!initCrypto()) {
422424
return {};
423425
}
424426

425427
std::vector<uint8_t> userPubKey;
426-
if (!decodeP256PublicKey(sub.p256dh, userPubKey)) {
428+
if (!decodeP256PublicKey(subscription.p256dh, userPubKey)) {
427429
ESP_LOGE(kTag, "encryptPayload: client public key invalid");
428430
return {};
429431
}
430432

431433
std::vector<uint8_t> authSecret;
432-
if (!base64UrlDecode(sub.auth, authSecret) || authSecret.size() != 16) {
434+
if (!base64UrlDecode(subscription.auth, authSecret) || authSecret.size() != 16) {
433435
ESP_LOGE(kTag, "encryptPayload: auth secret invalid");
434436
return {};
435437
}

0 commit comments

Comments
 (0)