public void TestGetVapidHeadersInvalidPublicKey() { var publicKey = UrlBase64.Encode(new byte[1]); var privateKey = UrlBase64.Encode(new byte[32]); Assert.ThrowsException <ArgumentException>( delegate { VapidHelper.GetVapidHeaders(ValidAudience, ValidSubject, publicKey, privateKey); }); }
public void TestGetVapidHeadersSubjectNotAUrlOrMailTo() { var publicKey = TestPublicKey; var privateKey = TestPrivateKey; Assert.ThrowsException <ArgumentException>( delegate { VapidHelper.GetVapidHeaders(ValidAudience, @"invalid subject", publicKey, privateKey); }); }
public void TestGetVapidHeadersSubjectNotAUrlOrMailTo() { var publicKey = UrlBase64.Encode(new byte[65]); var privatekey = UrlBase64.Encode(new byte[32]); Assert.Throws(typeof(ArgumentException), delegate { VapidHelper.GetVapidHeaders(ValidAudience, @"invalid subject", publicKey, privatekey); }); }
public void TestGetVapidHeadersAudienceNotAUrl() { var publicKey = UrlBase64.Encode(new byte[65]); var privatekey = UrlBase64.Encode(new byte[32]); Assert.Throws(typeof(ArgumentException), delegate { VapidHelper.GetVapidHeaders(@"invalid audience", ValidSubject, publicKey, privatekey); }); }
public void TestGetVapidHeaders() { string publicKey = UrlBase64.Encode(new byte[65]); string privatekey = UrlBase64.Encode(new byte[32]); Dictionary <string, string> headers = VapidHelper.GetVapidHeaders(VALID_AUDIENCE, VALID_SUBJECT, publicKey, privatekey); Assert.IsTrue(headers.ContainsKey("Authorization")); Assert.IsTrue(headers.ContainsKey("Crypto-Key")); }
public void TestGetVapidHeaders() { var publicKey = TestPublicKey; var privateKey = TestPrivateKey; var headers = VapidHelper.GetVapidHeaders(ValidAudience, ValidSubject, publicKey, privateKey); Assert.IsTrue(headers.ContainsKey(@"Authorization")); Assert.IsTrue(headers.ContainsKey(@"Crypto-Key")); }
public void TestGetVapidHeaders() { var publicKey = UrlBase64.Encode(new byte[65]); var privatekey = UrlBase64.Encode(new byte[32]); var headers = VapidHelper.GetVapidHeaders(ValidAudience, ValidSubject, publicKey, privatekey); Assert.True(headers.ContainsKey(@"Authorization")); Assert.True(headers.ContainsKey(@"Crypto-Key")); }
public void TestGetVapidHeadersInvalidPublicKey() { string publicKey = UrlBase64.Encode(new byte[1]); string privatekey = UrlBase64.Encode(new byte[32]); Assert.Throws(typeof(ArgumentException), delegate { VapidHelper.GetVapidHeaders(VALID_AUDIENCE, VALID_SUBJECT, publicKey, privatekey); }); }
public void TestGetVapidHeadersSubjectNotAUrlOrMailTo() { string publicKey = UrlBase64.Encode(new byte[65]); string privatekey = UrlBase64.Encode(new byte[32]); Assert.Throws(typeof(ArgumentException), delegate { VapidHelper.GetVapidHeaders(VALID_AUDIENCE, "invalid subject", publicKey, privatekey); }); }
public void TestGetVapidHeadersAudienceNotAUrl() { string publicKey = UrlBase64.Encode(new byte[65]); string privatekey = UrlBase64.Encode(new byte[32]); Assert.Throws(typeof(ArgumentException), delegate { VapidHelper.GetVapidHeaders("invalid audience", VALID_SUBJECT, publicKey, privatekey); }); }
public void TestGetVapidHeadersAudienceNotAUrl() { var publicKey = TestPublicKey; var privateKey = TestPrivateKey; Assert.ThrowsException <ArgumentException>( delegate { VapidHelper.GetVapidHeaders("invalid audience", ValidSubjectMailto, publicKey, privateKey); }); }
public void TestExpirationInPastExceptions() { var publicKey = TestPublicKey; var privateKey = TestPrivateKey; Assert.ThrowsException <ArgumentException>( delegate { VapidHelper.GetVapidHeaders(ValidAudience, ValidSubjectMailto, publicKey, privateKey, 1552715607); }); }
/// <summary> /// To get a request without sending a push notification call this method. /// This method will throw an ArgumentException if there is an issue with the input. /// </summary> /// <param name="subscription">The PushSubscription you wish to send the notification to.</param> /// <param name="payload">The payload you wish to send to the user</param> /// <param name="options"> /// Options for the GCM API key and vapid keys can be passed in if they are unique for each /// notification. /// </param> /// <returns>A HttpRequestMessage object that can be sent.</returns> public HttpRequestMessage GenerateRequestDetails(PushSubscription subscription, string payload, Dictionary <string, object> options = null) { if (!Uri.IsWellFormedUriString(subscription.Endpoint, UriKind.Absolute)) { throw new ArgumentException(@"You must pass in a subscription with at least a valid endpoint"); } var request = new HttpRequestMessage(HttpMethod.Post, subscription.Endpoint); if (!string.IsNullOrEmpty(payload) && (string.IsNullOrEmpty(subscription.Auth) || string.IsNullOrEmpty(subscription.P256DH))) { throw new ArgumentException( @"To send a message with a payload, the subscription must have 'auth' and 'p256dh' keys."); } var currentGcmApiKey = _gcmApiKey; var currentVapidDetails = _vapidDetails; var timeToLive = DefaultTtl; var extraHeaders = new Dictionary <string, object>(); if (options != null) { var validOptionsKeys = new List <string> { "headers", "gcmAPIKey", "vapidDetails", "TTL" }; foreach (var key in options.Keys) { if (!validOptionsKeys.Contains(key)) { throw new ArgumentException(key + " is an invalid options. The valid options are" + string.Join(",", validOptionsKeys)); } } if (options.ContainsKey("headers")) { var headers = options["headers"] as Dictionary <string, object>; extraHeaders = headers ?? throw new ArgumentException("options.headers must be of type Dictionary<string,object>"); } if (options.ContainsKey("gcmAPIKey")) { var gcmApiKey = options["gcmAPIKey"] as string; currentGcmApiKey = gcmApiKey ?? throw new ArgumentException("options.gcmAPIKey must be of type string"); } if (options.ContainsKey("vapidDetails")) { var vapidDetails = options["vapidDetails"] as VapidDetails; currentVapidDetails = vapidDetails ?? throw new ArgumentException("options.vapidDetails must be of type VapidDetails"); } if (options.ContainsKey("TTL")) { var ttl = options["TTL"] as int?; if (ttl == null) { throw new ArgumentException("options.TTL must be of type int"); } //at this stage ttl cannot be null. timeToLive = (int)ttl; } } string cryptoKeyHeader = null; request.Headers.Add("TTL", timeToLive.ToString()); foreach (var header in extraHeaders) { request.Headers.Add(header.Key, header.Value.ToString()); } if (!string.IsNullOrEmpty(payload)) { if (string.IsNullOrEmpty(subscription.P256DH) || string.IsNullOrEmpty(subscription.Auth)) { throw new ArgumentException( @"Unable to send a message with payload to this subscription since it doesn't have the required encryption key"); } var encryptedPayload = Encryptor.Encrypt(subscription.P256DH, subscription.Auth, payload); request.Content = new ByteArrayContent(encryptedPayload.Payload); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); request.Content.Headers.ContentLength = encryptedPayload.Payload.Length; request.Content.Headers.ContentEncoding.Add("aesgcm"); request.Headers.Add("Encryption", "salt=" + encryptedPayload.Base64EncodeSalt()); cryptoKeyHeader = @"dh=" + encryptedPayload.Base64EncodePublicKey(); } else { request.Content = new ByteArrayContent(new byte[0]); request.Content.Headers.ContentLength = 0; } var isGcm = subscription.Endpoint.StartsWith(@"https://android.googleapis.com/gcm/send"); if (isGcm) { if (!string.IsNullOrEmpty(currentGcmApiKey)) { request.Headers.TryAddWithoutValidation("Authorization", "key=" + currentGcmApiKey); } } else if (currentVapidDetails != null) { var uri = new Uri(subscription.Endpoint); var audience = uri.Scheme + @"://" + uri.Host; var vapidHeaders = VapidHelper.GetVapidHeaders(audience, currentVapidDetails.Subject, currentVapidDetails.PublicKey, currentVapidDetails.PrivateKey, currentVapidDetails.Expiration); request.Headers.Add(@"Authorization", vapidHeaders["Authorization"]); if (string.IsNullOrEmpty(cryptoKeyHeader)) { cryptoKeyHeader = vapidHeaders["Crypto-Key"]; } else { cryptoKeyHeader += @";" + vapidHeaders["Crypto-Key"]; } } request.Headers.Add("Crypto-Key", cryptoKeyHeader); return(request); }