Skip to content

Commit 8ddd4ac

Browse files
Added methods to mock the private key used for encryption
1 parent 03a6e8d commit 8ddd4ac

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

Sources/WebPush/WebPushManager.swift

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public actor WebPushManager: Sendable {
135135
}
136136

137137
deinit {
138-
if !didShutdown, case let .httpClient(httpClient) = executor {
138+
if !didShutdown, case let .httpClient(httpClient, _) = executor {
139139
try? httpClient.syncShutdown()
140140
}
141141
}
@@ -260,11 +260,12 @@ public actor WebPushManager: Sendable {
260260
logger: Logger? = nil
261261
) async throws {
262262
switch executor {
263-
case .httpClient(let httpClient):
263+
case .httpClient(let httpClient, let privateKey):
264264
var logger = logger ?? backgroundActivityLogger
265-
logger[metadataKey: "message"] = "\(message)"
265+
logger[metadataKey: "message"] = ".data(\(message.base64URLEncodedString()))"
266266
try await execute(
267267
httpClient: httpClient,
268+
applicationServerECDHPrivateKey: privateKey,
268269
data: message,
269270
subscriber: subscriber,
270271
expiration: expiration,
@@ -345,9 +346,10 @@ public actor WebPushManager: Sendable {
345346
var logger = logger
346347
logger[metadataKey: "message"] = "\(message)"
347348
switch executor {
348-
case .httpClient(let httpClient):
349+
case .httpClient(let httpClient, let privateKey):
349350
try await execute(
350351
httpClient: httpClient,
352+
applicationServerECDHPrivateKey: privateKey,
351353
data: message.data,
352354
subscriber: subscriber,
353355
expiration: expiration,
@@ -367,13 +369,15 @@ public actor WebPushManager: Sendable {
367369
/// Send a message via HTTP Client, mocked or otherwise, encrypting it on the way.
368370
/// - Parameters:
369371
/// - httpClient: The protocol implementing HTTP-like functionality.
372+
/// - applicationServerECDHPrivateKey: The private key to use for the key exchange. If nil, one will be generated.
370373
/// - message: The message to send as raw data.
371374
/// - subscriber: The subscriber to sign the message against.
372375
/// - expiration: The expiration of the message.
373376
/// - urgency: The urgency of the message.
374377
/// - logger: The logger to use for status updates.
375378
func execute(
376379
httpClient: some HTTPClientProtocol,
380+
applicationServerECDHPrivateKey: P256.KeyAgreement.PrivateKey?,
377381
data message: some DataProtocol,
378382
subscriber: some SubscriberProtocol,
379383
expiration: Expiration,
@@ -398,7 +402,7 @@ public actor WebPushManager: Sendable {
398402

399403
/// Prepare authorization, private keys, and payload ahead of time to bail early if they can't be created.
400404
let authorization = try loadCurrentVAPIDAuthorizationHeader(endpoint: subscriber.endpoint, signingKey: signingKey)
401-
let applicationServerECDHPrivateKey = P256.KeyAgreement.PrivateKey()
405+
let applicationServerECDHPrivateKey = applicationServerECDHPrivateKey ?? P256.KeyAgreement.PrivateKey()
402406

403407
/// Perform key exchange between the user agent's public key and our private key, deriving a shared secret.
404408
let userAgent = subscriber.userAgentKeyMaterial
@@ -511,7 +515,7 @@ extension WebPushManager: Service {
511515
} onCancelOrGracefulShutdown: { [backgroundActivityLogger, executor] in
512516
backgroundActivityLogger.debug("Shutting down WebPushManager")
513517
do {
514-
if case let .httpClient(httpClient) = executor {
518+
if case let .httpClient(httpClient, _) = executor {
515519
try httpClient.syncShutdown()
516520
}
517521
} catch {
@@ -715,10 +719,17 @@ extension WebPushManager {
715719

716720
/// An internal type representing the executor for a push message.
717721
package enum Executor: Sendable {
722+
/// Use an HTTP client and optional private key to send an encrypted payload to a subscriber.
723+
///
724+
/// This is used in tests to capture the encrypted request and make sure it is well-formed.
725+
case httpClient(any HTTPClientProtocol, P256.KeyAgreement.PrivateKey?)
726+
718727
/// Use an HTTP client to send an encrypted payload to a subscriber.
719728
///
720729
/// This is used in tests to capture the encrypted request and make sure it is well-formed.
721-
case httpClient(any HTTPClientProtocol)
730+
package static func httpClient(_ httpClient: any HTTPClientProtocol) -> Self {
731+
.httpClient(httpClient, nil)
732+
}
722733

723734
/// Use a handler to capture the original message.
724735
///

0 commit comments

Comments
 (0)