| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 | 
							- using System.Security.Claims;
 
- using System.Security.Cryptography;
 
- using Microsoft.IdentityModel.Tokens;
 
- using System.IdentityModel.Tokens.Jwt;
 
- using static System.Net.Mime.MediaTypeNames;
 
- using Microsoft.Net.Http.Headers;
 
- using Microsoft.Extensions.Configuration;
 
- using NPOI.SS.Formula.Functions;
 
- using System.Net.Http;
 
- using Flurl.Http.Configuration;
 
- using System.Net;
 
- using QuzrtzJob.Factory;
 
- using Org.BouncyCastle.Crypto.Parameters;
 
- using System.IO;
 
- using CurlThin;
 
- using CurlThin.Enums;
 
- using CurlThin.Helpers;
 
- using CurlThin.Native;
 
- using CurlThin.SafeHandles;
 
- namespace OASystem.API.OAMethodLib.APNs
 
- {
 
-     public enum NotificationType : int
 
-     {
 
-         Alert = 0,
 
-         Sound = 1,
 
-         Badge = 2,
 
-         Silent = 3
 
-     }
 
-     /// <summary>
 
-     /// APNs 生成 JWT token,添加服务的时候,使用单利
 
-     /// </summary>
 
-     public class APNsService : IAPNsService
 
-     {
 
-         static string token = null;
 
-         static string baseUrl = null;
 
-         private readonly ILogger<APNsService> _logger;
 
-         //private static readonly HttpClient _httpClientFactory = new HttpClient { BaseAddress = new Uri("https://api.push.apple.com:443/3/device/") };
 
-         private readonly IConfiguration _configuration;
 
-         //private readonly IHttpClientFactory _httpClientFactory;
 
-         public APNsService(ILogger<APNsService> logger, IConfiguration configuration)
 
-         {
 
-             this._configuration = configuration;
 
-             //this._httpClientFactory = httpClientFactory;
 
-             //APNsService.baseUrl = this._configuration["apple:pushNotificationServer"];
 
-             //APNsService.baseUrl = this._configuration["apple:pushNotificationServer_Production"];
 
-             //
 
-             //APNsService.baseUrl = string.Format("https://api.push.apple.com:443/3/device/");
 
-             _logger = logger;
 
-         }
 
-         /// <summary>
 
-         /// 生成 APNs JWT token
 
-         /// </summary>
 
-         /// <returns></returns>
 
-         public string GetnerateAPNsJWTToken()
 
-         {
 
-             return this.GetnerateAPNsJWTToken(APNsService.token);
 
-         }
 
-         //private static CngKey GetPrivateKey()
 
-         //{
 
-         //    using (var reader = System.IO.File.OpenText("File/AuthKey_RMV7Y4KM9V.p8"))
 
-         //    {
 
-         //        var ecPrivateKeyParameters = (ECPrivateKeyParameters)new PemReader(reader).ReadObject();
 
-         //        var x = ecPrivateKeyParameters.Parameters.G.AffineXCoord.GetEncoded();
 
-         //        var y = ecPrivateKeyParameters.Parameters.G.AffineYCoord.GetEncoded();
 
-         //        var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned();
 
-         //        return EccKey.New(x, y, d);
 
-         //    }
 
-         //}
 
-         /// <summary>
 
-         /// 生成 APNs JWT token
 
-         /// </summary>
 
-         /// <returns></returns>
 
-         private string GetnerateAPNsJWTToken(string oldToken)
 
-         {
 
-             var tokenHandler = new JwtSecurityTokenHandler();
 
-             var iat = ((DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1).Ticks) / TimeSpan.TicksPerSecond);
 
-             // 判断原 token 是否超过 50 分钟,如果未超过,直接返回
 
-             if (string.IsNullOrWhiteSpace(oldToken) == false)
 
-             {
 
-                 JwtPayload oldPayload = tokenHandler.ReadJwtToken(oldToken).Payload;
 
-                 var oldIat = oldPayload.Claims.FirstOrDefault(c => c.Type == "iat");
 
-                 if (oldIat != null)
 
-                 {
 
-                     if (long.TryParse(oldIat.Value, out long oldIatValue) == true)
 
-                     {
 
-                         // 两次间隔小于 50 分钟,使用原 token
 
-                         if ((iat - oldIatValue) < (50 * 60))
 
-                         {
 
-                             return oldToken;
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             var kid = _configuration["apple:kid"];
 
-             //var securityKey = _configuration["apple:securityKey"].Replace("\n", "");
 
-             var securityKey = string.Format("MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQglyUl7hjI75YJUVMbZLN6TpkiFzuTXUN+UIjuJA7+y8ugCgYIKoZIzj0DAQehRANCAAS8GR7lKNst4KENCp45OXCMyiytvzK0qdRBrx0l+bMaHjiU+Upfox82G+Xy4wd8hI+0wMDh341aNelqEdYUUx3O");
 
-             var iss = _configuration["apple:iss"];
 
-             var claims = new Claim[]
 
-             {
 
-                 new Claim("iss", iss),
 
-                 new Claim("iat", iat.ToString())
 
-             };
 
-             string msg = string.Empty;
 
-             msg += $"[GetnerateAPNsJWTToken] 0";
 
-             try
 
-             {
 
-                 msg += $"[GetnerateAPNsJWTToken] 1";
 
-                 var eCDsa = ECDsa.Create();
 
-                 msg += $"[GetnerateAPNsJWTToken] 2";
 
-                 eCDsa.ImportPkcs8PrivateKey(Convert.FromBase64String(securityKey), out _);
 
-                 msg += $"[GetnerateAPNsJWTToken] 3";
 
-                 var key = new ECDsaSecurityKey(eCDsa);
 
-                 msg += $"[GetnerateAPNsJWTToken] 4";
 
-                 key.KeyId = kid;
 
-                 msg += $"[GetnerateAPNsJWTToken] 5";
 
-                 var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.EcdsaSha256);
 
-                 msg += $"[GetnerateAPNsJWTToken] 6";
 
-                 var jwtHeader = new JwtHeader(signingCredentials);
 
-                 msg += $"[GetnerateAPNsJWTToken] 7";
 
-                 var jwtPayload = new JwtPayload(claims);
 
-                 msg += $"[GetnerateAPNsJWTToken] 8";
 
-                 var jwtSecurityToken = new JwtSecurityToken(jwtHeader, jwtPayload);
 
-                 msg += $"[GetnerateAPNsJWTToken] 9";
 
-                 APNsService.token = tokenHandler.WriteToken(jwtSecurityToken);
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 return msg += $"[GetnerateAPNsJWTToken] --> ExMsg:[{ex.Message}]";
 
-             }
 
-             return APNsService.token;
 
-         }
 
-         public async Task<Result> PushNotification1(string apnsTopic, string deviceToken, NotificationType type, string title, string subtitle, string body, bool isTarget, string viewCode, PageParam_PriceAuditH5 pageParam)
 
-         {
 
-             var res = new Result() { Code = 0, Msg = "", Data = "" };
 
-             //This string is for extracting libcurl and ssl libs to the bin directory.
 
-             CurlResources.Init();
 
-             var global = CurlNative.Init();
 
-             var easy = CurlNative.Easy.Init();
 
-             string content = string.Empty;
 
-             try
 
-             {
 
-                 var token = GetnerateAPNsJWTToken();
 
-                 var dataCopier = new DataCallbackCopier();
 
-                 CurlNative.Easy.SetOpt(easy, CURLoption.URL, $"https://api.push.apple.com:443/3/device/{deviceToken}");
 
-                 CurlNative.Easy.SetOpt(easy, CURLoption.WRITEFUNCTION, dataCopier.DataHandler);
 
-                 //This string is needed when you call a https endpoint.
 
-                 CurlNative.Easy.SetOpt(easy, CURLoption.CAINFO, CurlResources.CaBundlePath);
 
-                 var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, APNsService.baseUrl + deviceToken)
 
-                 {
 
-                     Headers =
 
-                     {
 
-                         { HeaderNames.Authorization, "bearer " +  token },
 
-                         { "apns-topic", apnsTopic },
 
-                         { "apns-expiration", "0" }
 
-                     },
 
-                     Version = new Version(2, 0)
 
-                 };
 
-                 if (isTarget)
 
-                 {
 
-                     var notContent = new
 
-                     {
 
-                         aps = new
 
-                         {
 
-                             alert = new
 
-                             {
 
-                                 title = title,
 
-                                 subtitle = subtitle,
 
-                                 body = body
 
-                             }
 
-                         },
 
-                         ViewCode = viewCode,
 
-                         PageParam = pageParam
 
-                     };
 
-                     var contentJson = new StringContent(System.Text.Json.JsonSerializer.Serialize(notContent), System.Text.Encoding.UTF8, Application.Json);
 
-                     CurlNative.Easy.SetOpt(easy, CURLoption.POSTFIELDS, System.Text.Json.JsonSerializer.Serialize(notContent));
 
-                 }
 
-                 else
 
-                 {
 
-                     var notContent = new
 
-                     {
 
-                         aps = new
 
-                         {
 
-                             alert = new
 
-                             {
 
-                                 title = title,
 
-                                 subtitle = subtitle,
 
-                                 body = body
 
-                             }
 
-                         }
 
-                     };
 
-                     var contentJson = new StringContent(System.Text.Json.JsonSerializer.Serialize(notContent), System.Text.Encoding.UTF8, Application.Json);
 
-                     CurlNative.Easy.SetOpt(easy, CURLoption.POSTFIELDS, System.Text.Json.JsonSerializer.Serialize(notContent));
 
-                 }
 
-                 var headers = CurlNative.Slist.Append(SafeSlistHandle.Null, $"Authorization: Bearer {token}");
 
-                 CurlNative.Slist.Append(headers, $"apns-topic: {apnsTopic}");
 
-                 CurlNative.Slist.Append(headers, $"apns-expiration: 0");
 
-                 CurlNative.Easy.SetOpt(easy, CURLoption.HTTPHEADER, headers.DangerousGetHandle());
 
-                 //Your set of ciphers, full list is here https://curl.se/docs/ssl-ciphers.html
 
-                 CurlNative.Easy.SetOpt(easy, CURLoption.SSL_CIPHER_LIST, "ECDHE-RSA-AES256-GCM-SHA384");
 
-                 res.Msg += $"[PushNotification1] --> 发送请求";
 
-                 CurlNative.Easy.Perform(easy);
 
-                 content = Encoding.UTF8.GetString(dataCopier.Stream.ToArray());
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 res.Msg += $"[PushNotification1] ExMsg:{ex.Message}";
 
-                 if (ex.InnerException != null)
 
-                 {
 
-                     res.Msg += $"[PushNotification1] InnerException:{ex.InnerException.Message}";
 
-                 }
 
-             }
 
-             finally
 
-             {
 
-                 easy.Dispose();
 
-                 if (global == CURLcode.OK)
 
-                     CurlNative.Cleanup();
 
-             }
 
-             res.Data = content;
 
-             return res;
 
-         }
 
-         /// <summary>
 
-         /// 发送推送通知
 
-         /// </summary>
 
-         /// <param name="apnsTopic">APP Id</param>
 
-         /// <param name="deviceToken">设备标识</param>[文件:AuthKey_RMV7Y4KM9V.p8]
 
-         /// <param name="type">通知类型</param>
 
-         /// <param name="title">标题</param>
 
-         /// <param name="subtitle">子标题</param>
 
-         /// <param name="body">通知内容</param>
 
-         /// <returns></returns>
 
-         public async Task<Result> PushNotification(string apnsTopic, string deviceToken, NotificationType type, string title, string subtitle, string body)
 
-         {
 
-             Result result = new Result() { Code = -1, Msg = "[PushNotification] Start" };
 
-             result.Msg += "\r\n[PushNotification] Start";
 
-             _logger.LogInformation($"[PushNotification] Start");
 
-             var responseData = FailedAPNsReponseData();
 
-             var token = this.GetnerateAPNsJWTToken();
 
-             try
 
-             {
 
-                 var _httpClientFactory = new HttpClient { BaseAddress = new Uri("https://api.push.apple.com:443/3/device/") };
 
-                 result.Msg += $"\r\n[PushNotification] --> [HttpClient] --> Init --> jsonStr:{JsonConvert.SerializeObject(_httpClientFactory)}";
 
-                 var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, APNsService.baseUrl + deviceToken)
 
-                 {
 
-                     Headers =
 
-                     {
 
-                         { HeaderNames.Authorization, "bearer " +  token },
 
-                         { "apns-topic", apnsTopic },
 
-                         { "apns-expiration", "0" }
 
-                     },
 
-                     Version = new Version(2, 0)
 
-                 };
 
-                 result.Msg += $"\r\n[PushNotification] --> [httpRequestMessage] --> Init --> jsonStr:{JsonConvert.SerializeObject(httpRequestMessage)}";
 
-                 var notContent = new
 
-                 {
 
-                     aps = new
 
-                     {
 
-                         alert = new
 
-                         {
 
-                             title = title,
 
-                             subtitle = subtitle,
 
-                             body = body
 
-                         }
 
-                     }
 
-                 };
 
-                 //var content = new StringContent(JsonSerializerTool.SerializeDefault(notContent), System.Text.Encoding.UTF8, Application.Json);
 
-                 var content = new StringContent(System.Text.Json.JsonSerializer.Serialize(notContent), System.Text.Encoding.UTF8, Application.Json);
 
-                 httpRequestMessage.Content = content;
 
-                 result.Msg += $"\r\n[PushNotification] --> [httpRequestMessage] --> Content --> jsonStr:{JsonConvert.SerializeObject(httpRequestMessage)}";
 
-                 try
 
-                 {
 
-                     //ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
 
-                     //HttpClientHandler handler = new HttpClientHandler()
 
-                     //{
 
-                     //    Proxy = new WebProxy("https://api.push.apple.com:443/3/device/"),
 
-                     //    SslProtocols = System.Security.Authentication.SslProtocols.Tls12, // Enforce TLS 1.2
 
-                     //    UseProxy = true
 
-                     //};
 
-                     //HttpClient client = new HttpClient(handler);
 
-                     //var httpResponseMessage = await client.SendAsync(httpRequestMessage);
 
-                     var httpResponseMessage = await _httpClientFactory.SendAsync(httpRequestMessage);
 
-                     if (httpResponseMessage.IsSuccessStatusCode)
 
-                     {
 
-                         responseData.Code = 200;
 
-                         result.Code = 0;
 
-                         result.Msg = "";
 
-                         result.Data = responseData;
 
-                         result.Msg += $"\r\n[PushNotification] End jsonStr[{JsonConvert.SerializeObject(result)}]";
 
-                         return result;
 
-                     }
 
-                     else
 
-                     {
 
-                         responseData.Data = httpResponseMessage.StatusCode;
 
-                         result.Code = -2;
 
-                         result.Msg = "";
 
-                         result.Data = responseData;
 
-                         result.Msg += $"\r\n[PushNotification] End jsonStr[{JsonConvert.SerializeObject(result)}]";
 
-                         return result;
 
-                     }
 
-                 }
 
-                 catch (Exception e)
 
-                 {
 
-                     responseData.Data = e.Message;
 
-                     result.Code = -3;
 
-                     result.Msg = "";
 
-                     result.Data = responseData;
 
-                     result.Msg += $"\r\n[PushNotification] --> [httpClientFactory] ExceptionMsg:{e.Message}";
 
-                     result.Msg += $"\r\n[PushNotification] --> [httpClientFactory] InnerExceptionData:{e.InnerException}";
 
-                     result.Msg += $"\r\n[PushNotification] --> [httpClientFactory] InnerExceptionMsg:{e.InnerException.Message}";
 
-                     return result;
 
-                 }
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 result.Msg += $"\r\n[PushNotification] InnerExceptionData:{JsonConvert.SerializeObject(ex.InnerException)}";
 
-                 result.Msg += $"\r\n[PushNotification] InnerExceptionMsg:{ex.InnerException.Message}";
 
-             }
 
-             return result;
 
-         }
 
-         public APNsReponseData FailedAPNsReponseData()
 
-         {
 
-             return new APNsReponseData() { Code = 400, Data = "" };
 
-         }
 
-     }
 
-     public class APNsReponseData
 
-     {
 
-         public int Code { get; set; } = 0;
 
-         public object Data { get; set; } = "";
 
-     }
 
-     public class PageParam_PriceAuditH5
 
-     {
 
-         public string diid { get; set; }
 
-         public string uid { get; set; }
 
-     }
 
- }
 
 
  |