diff --git a/pom.xml b/pom.xml index 1b5b052..8beabf4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,10 +5,10 @@ 4.0.0 com.clevertap.apns - apns-http2 - 1.0.7 + apns-http2-madlogic + 1.0.8 - apns-http2 + apns-http2-madlogic A library for communicating with the Apple Push Gateway in HTTP/2. https://github.com/CleverTap/apns-http2 @@ -81,7 +81,6 @@ - org.apache.maven.plugins maven-assembly-plugin @@ -106,9 +105,9 @@ - bintray-clevertap-Maven - clevertap-Maven - https://api.bintray.com/maven/clevertap/Maven/apns-http2/;publish=1 + madlogic-nexus + Madlogic-Nexus + https://nexus.sqoony.com/nexus/content/repositories/apns-http2-madlogic/ diff --git a/src/main/java/com/clevertap/apns/CertificateUtils.java b/src/main/java/com/clevertap/apns/CertificateUtils.java index 6fdf335..94d89b9 100644 --- a/src/main/java/com/clevertap/apns/CertificateUtils.java +++ b/src/main/java/com/clevertap/apns/CertificateUtils.java @@ -119,7 +119,7 @@ public static Map splitCertificateSubject(String subject) { * @param production Validate the certificate environment, if required * @param certificate The certificate to be validated * @throws CertificateException When the certificate is not valid, or if it's expired, - * or if it's not a push certificate + * or if it's not a push or voip certificate */ public static void validateCertificate(boolean production, X509Certificate certificate) throws CertificateException { @@ -131,14 +131,25 @@ public static void validateCertificate(boolean production, X509Certificate certi // Ensure that it's a push certificate final Map stringStringMap = CertificateUtils.splitCertificateSubject(certificate.getSubjectDN().getName()); final String cn = stringStringMap.get("CN"); - if (!cn.toLowerCase().contains("push")) { + if (!cn.toLowerCase().contains("push") && !cn.toLowerCase().contains("voip")) { throw new CertificateException("Not a push certificate - " + cn); } + } - if (production && cn.toLowerCase().contains("apple development ios push services")) { - throw new CertificateEnvironmentMismatchException("Invalid environment for this certificate"); - } else if (!production && cn.toLowerCase().contains("apple production ios push services")) { - throw new CertificateEnvironmentMismatchException("Invalid environment for this certificate"); - } + /** + * Checks whether the given certificate is a 'voip' certificate + * + * @param certificate The certificate to be checked + * @throws CertificateException When the certificate is not valid, or if it's expired + */ + public static boolean checkIsVoipCertificate(X509Certificate certificate) + throws CertificateException { + if (certificate == null) throw new CertificateException("Null certificate"); + + // Ensure that it's a push certificate + final Map stringStringMap = CertificateUtils.splitCertificateSubject(certificate.getSubjectDN().getName()); + final String cn = stringStringMap.get("CN"); + + return cn.toLowerCase().contains("voip"); } } diff --git a/src/main/java/com/clevertap/apns/Notification.java b/src/main/java/com/clevertap/apns/Notification.java index 1410615..a23a52b 100644 --- a/src/main/java/com/clevertap/apns/Notification.java +++ b/src/main/java/com/clevertap/apns/Notification.java @@ -288,7 +288,11 @@ public int size() { */ public Notification build() { root.put("aps", aps); - aps.put("alert", alert); + + //No need to add the alert if it's empty. + if (alert.size() > 0) { + aps.put("alert", alert); + } final String payload; try { diff --git a/src/main/java/com/clevertap/apns/clients/SyncOkHttpApnsClient.java b/src/main/java/com/clevertap/apns/clients/SyncOkHttpApnsClient.java index 86e8c22..aaa3196 100644 --- a/src/main/java/com/clevertap/apns/clients/SyncOkHttpApnsClient.java +++ b/src/main/java/com/clevertap/apns/clients/SyncOkHttpApnsClient.java @@ -61,6 +61,8 @@ public class SyncOkHttpApnsClient implements ApnsClient { private long lastJWTTokenTS = 0; private String cachedJWTToken = null; + private boolean isVoip; + /** * Creates a new client which uses token authentication API. * @@ -171,6 +173,8 @@ public SyncOkHttpApnsClient(InputStream certificate, String password, boolean pr final X509Certificate cert = (X509Certificate) ks.getCertificate(ks.aliases().nextElement()); CertificateUtils.validateCertificate(production, cert); + this.isVoip = CertificateUtils.checkIsVoipCertificate(cert); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, password.toCharArray()); KeyManager[] keyManagers = kmf.getKeyManagers(); @@ -264,10 +268,6 @@ public void writeTo(BufferedSink sink) throws IOException { }) .header("content-length", notification.getPayload().getBytes(Constants.UTF_8).length + ""); - if (topic != null) { - rb.header("apns-topic", topic); - } - if (collapseId != null) { rb.header("apns-collapse-id", collapseId); } @@ -280,12 +280,25 @@ public void writeTo(BufferedSink sink) throws IOException { rb.header("apns-expiration", String.valueOf(expiration)); } - if (priority != null) { - rb.header("apns-priority", String.valueOf(priority.getCode())); + if (this.isVoip) { + rb.header("apns-push-type", "voip"); + + if (topic != null) { + rb.header("apns-topic", topic + ".voip"); + } } + else { + if (topic != null) { + rb.header("apns-topic", topic); + } + + if (pushType != null) { + rb.header("apns-push-type", pushType); + } - if (pushType != null) { - rb.header("apns-push-type", pushType); + if (priority != null) { + rb.header("apns-priority", String.valueOf(priority.getCode())); + } } if (keyID != null && teamID != null && apnsAuthKey != null) {