Initial commit for push service
This commit is contained in:
71
pom.xml
Normal file
71
pom.xml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<modules>
|
||||||
|
<module>push-service-client-lib</module>
|
||||||
|
<module>push-service-server</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.1.2.RELEASE</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>de.77zzcx7</groupId>
|
||||||
|
<artifactId>push-service-parent</artifactId>
|
||||||
|
<version>1-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<description>A micro service to send push notifications</description>
|
||||||
|
<name>push-service-parent</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.9</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.9</maven.compiler.target>
|
||||||
|
<java.version>1.9</java.version>
|
||||||
|
<!-- Property to define the parallel deployment version.
|
||||||
|
See e.g. https://tomcat.apache.org/tomcat-8.5-doc/config/context.html
|
||||||
|
Should be the same as the project.version but padded with zeros to six digits. -->
|
||||||
|
<parallelDeploymentVersion>000001</parallelDeploymentVersion>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>77zzcx7-snapshots</id>
|
||||||
|
<url>http://192.168.10.1:8100/repository/77zzcx7-snapshots/</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
<repository>
|
||||||
|
<id>77zzcx7-releases</id>
|
||||||
|
<url>http://192.168.10.1:8100/repository/77zzcx7-releases/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>nl.martijndwars</groupId>
|
||||||
|
<artifactId>web-push</artifactId>
|
||||||
|
<version>5.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
|
<version>1.64</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
</project>
|
||||||
40
push-service-client-lib/pom.xml
Normal file
40
push-service-client-lib/pom.xml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>push-service-parent</artifactId>
|
||||||
|
<groupId>de.77zzcx7</groupId>
|
||||||
|
<version>1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>push-service-client-lib</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>Client libraries for push-service</description>
|
||||||
|
<name>push-service-client-lib</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package de.pushservice.client;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
public enum ResponseReason {
|
||||||
|
OK(HttpStatus.OK),
|
||||||
|
UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
|
private final HttpStatus httpStatus;
|
||||||
|
|
||||||
|
ResponseReason(HttpStatus httpStatus) {
|
||||||
|
this.httpStatus = httpStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseEntity toResponseEntity() {
|
||||||
|
return new ResponseEntity<>(this.name(), this.httpStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpStatus getHttpStatus() {
|
||||||
|
return this.httpStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseReason fromResponseEntity(ResponseEntity<String> entity) {
|
||||||
|
for (ResponseReason reason : values()) {
|
||||||
|
if (reason.name().equals(entity.getBody())) {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package de.pushservice.client.dto;
|
||||||
|
|
||||||
|
import de.pushservice.client.model.Urgency;
|
||||||
|
|
||||||
|
public class MessageDto {
|
||||||
|
private String payload;
|
||||||
|
private String topic;
|
||||||
|
private Urgency urgency;
|
||||||
|
|
||||||
|
public String getPayload() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayload(String payload) {
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Urgency getUrgency() {
|
||||||
|
return urgency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrgency(Urgency urgency) {
|
||||||
|
this.urgency = urgency;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package de.pushservice.client.dto;
|
||||||
|
|
||||||
|
public class NotificationRequestDto {
|
||||||
|
private SubscriptionDto subscriptionDto;
|
||||||
|
private MessageDto messageDto;
|
||||||
|
|
||||||
|
public SubscriptionDto getSubscriptionDto() {
|
||||||
|
return subscriptionDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubscriptionDto(SubscriptionDto subscriptionDto) {
|
||||||
|
this.subscriptionDto = subscriptionDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageDto getMessageDto() {
|
||||||
|
return messageDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageDto(MessageDto messageDto) {
|
||||||
|
this.messageDto = messageDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package de.pushservice.client.dto;
|
||||||
|
|
||||||
|
public class SubscriptionDto {
|
||||||
|
private String auth;
|
||||||
|
private String endpoint;
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
public void setAuth(String auth) {
|
||||||
|
this.auth = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuth() {
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndpoint(String endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEndpoint() {
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package de.pushservice.client.model;
|
||||||
|
|
||||||
|
public enum Urgency {
|
||||||
|
VERY_LOW,
|
||||||
|
LOW,
|
||||||
|
NORMAL,
|
||||||
|
HIGH
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
self.addEventListener('push', function(event) {
|
||||||
|
console.log('Received push');
|
||||||
|
let notificationTitle = 'Hello';
|
||||||
|
const notificationOptions = {
|
||||||
|
body: 'Thanks for sending this push msg.',
|
||||||
|
icon: './images/logo-192x192.png',
|
||||||
|
badge: './images/badge-72x72.png',
|
||||||
|
tag: 'simple-push-demo-notification',
|
||||||
|
data: {
|
||||||
|
url: 'https://developers.google.com/web/fundamentals/getting-started/push-notifications/',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (event.data) {
|
||||||
|
const dataText = event.data.text();
|
||||||
|
notificationTitle = 'Received Payload';
|
||||||
|
notificationOptions.body = `Push data: '${dataText}'`;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.waitUntil(
|
||||||
|
Promise.all([
|
||||||
|
self.registration.showNotification(
|
||||||
|
notificationTitle, notificationOptions),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* Step one: run a function on load (or whenever is appropriate for you)
|
||||||
|
* Function run on load sets up the service worker if it is supported in the
|
||||||
|
* browser. Requires a serviceworker in a `sw.js`. This file contains what will
|
||||||
|
* happen when we receive a push notification.
|
||||||
|
* If you are using webpack, see the section below.
|
||||||
|
*/
|
||||||
|
$(function () {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.register('/service-worker.js').then(initialiseState);
|
||||||
|
} else {
|
||||||
|
console.warn('Service workers are not supported in this browser.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step two: The serviceworker is registered (started) in the browser. Now we
|
||||||
|
* need to check if push messages and notifications are supported in the browser
|
||||||
|
*/
|
||||||
|
function initialiseState() {
|
||||||
|
|
||||||
|
// Check if desktop notifications are supported
|
||||||
|
if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
|
||||||
|
console.warn('Notifications aren\'t supported.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user has disabled notifications
|
||||||
|
// If a user has manually disabled notifications in his/her browser for
|
||||||
|
// your page previously, they will need to MANUALLY go in and turn the
|
||||||
|
// permission back on. In this statement you could show some UI element
|
||||||
|
// telling the user how to do so.
|
||||||
|
if (Notification.permission === 'denied') {
|
||||||
|
console.warn('The user has blocked notifications.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check is push API is supported
|
||||||
|
if (!('PushManager' in window)) {
|
||||||
|
console.warn('Push messaging isn\'t supported.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
|
||||||
|
|
||||||
|
// Get the push notification subscription object
|
||||||
|
serviceWorkerRegistration.pushManager.getSubscription().then(function (subscription) {
|
||||||
|
|
||||||
|
// If this is the user's first visit we need to set up
|
||||||
|
// a subscription to push notifications
|
||||||
|
if (!subscription) {
|
||||||
|
subscribe();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the server state with the new subscription
|
||||||
|
sendSubscriptionToServer(subscription);
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
// Handle the error - show a notification in the GUI
|
||||||
|
console.warn('Error during getSubscription()', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step three: Create a subscription. Contact the third party push server (for
|
||||||
|
* example mozilla's push server) and generate a unique subscription for the
|
||||||
|
* current browser.
|
||||||
|
*/
|
||||||
|
function subscribe() {
|
||||||
|
navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
|
||||||
|
|
||||||
|
// Contact the third party push server. Which one is contacted by
|
||||||
|
// pushManager is configured internally in the browser, so we don't
|
||||||
|
// need to worry about browser differences here.
|
||||||
|
//
|
||||||
|
// When .subscribe() is invoked, a notification will be shown in the
|
||||||
|
// user's browser, asking the user to accept push notifications from
|
||||||
|
// <yoursite.com>. This is why it is async and requires a catch.
|
||||||
|
serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true}).then(function (subscription) {
|
||||||
|
|
||||||
|
// Update the server state with the new subscription
|
||||||
|
return sendSubscriptionToServer(subscription);
|
||||||
|
})
|
||||||
|
.catch(function (e) {
|
||||||
|
if (Notification.permission === 'denied') {
|
||||||
|
console.warn('Permission for Notifications was denied');
|
||||||
|
} else {
|
||||||
|
console.error('Unable to subscribe to push.', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step four: Send the generated subscription object to our server.
|
||||||
|
*/
|
||||||
|
function sendSubscriptionToServer(subscription) {
|
||||||
|
|
||||||
|
// Get public key and user auth from the subscription object
|
||||||
|
var key = subscription.getKey ? subscription.getKey('p256dh') : '';
|
||||||
|
var auth = subscription.getKey ? subscription.getKey('auth') : '';
|
||||||
|
|
||||||
|
// This example uses the new fetch API. This is not supported in all
|
||||||
|
// browsers yet.
|
||||||
|
return fetch('/profile/subscription', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
endpoint: subscription.endpoint,
|
||||||
|
// Take byte[] and turn it into a base64 encoded string suitable for
|
||||||
|
// POSTing to a server over HTTP
|
||||||
|
key: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : '',
|
||||||
|
auth: auth ? btoa(String.fromCharCode.apply(null, new Uint8Array(auth))) : ''
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
56
push-service-server/pom.xml
Normal file
56
push-service-server/pom.xml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>push-service-parent</artifactId>
|
||||||
|
<groupId>de.77zzcx7</groupId>
|
||||||
|
<version>1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>push-service-server</artifactId>
|
||||||
|
<packaging>${packaging.type}</packaging>
|
||||||
|
<description>The server part of the push-service</description>
|
||||||
|
<name>push-service-server</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<packaging.type>jar</packaging.type>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>nl.martijndwars</groupId>
|
||||||
|
<artifactId>web-push</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.77zzcx7</groupId>
|
||||||
|
<artifactId>push-service-client-lib</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>build-war</id>
|
||||||
|
<properties>
|
||||||
|
<packaging.type>war</packaging.type>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}##${parallelDeploymentVersion}</finalName>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package de.pushservice.server;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class PushServiceApplication extends SpringBootServletInitializer {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PushServiceApplication.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||||
|
return application.sources(PushServiceApplication.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package de.pushservice.server.controller;
|
||||||
|
|
||||||
|
import de.pushservice.client.ResponseReason;
|
||||||
|
import de.pushservice.client.dto.NotificationRequestDto;
|
||||||
|
import de.pushservice.server.decorator.MessageDecorator;
|
||||||
|
import de.pushservice.server.decorator.SubscriptionDecorator;
|
||||||
|
import nl.martijndwars.webpush.Notification;
|
||||||
|
import nl.martijndwars.webpush.PushService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class PushServiceController {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(PushServiceController.class);
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public ResponseEntity notify(NotificationRequestDto notificationRequestDto) {
|
||||||
|
try {
|
||||||
|
final SubscriptionDecorator subscription = SubscriptionDecorator
|
||||||
|
.fromDto(notificationRequestDto.getSubscriptionDto());
|
||||||
|
final Notification notification = MessageDecorator.fromDto(notificationRequestDto.getMessageDto())
|
||||||
|
.toNotification(subscription);
|
||||||
|
final PushService extPushService = new PushService();
|
||||||
|
|
||||||
|
extPushService.send(notification);
|
||||||
|
|
||||||
|
return ResponseReason.OK.toResponseEntity();
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
LOGGER.error("Error while sending notification!", e);
|
||||||
|
|
||||||
|
return ResponseReason.UNKNOWN_ERROR.toResponseEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package de.pushservice.server.decorator;
|
||||||
|
|
||||||
|
import de.pushservice.client.dto.MessageDto;
|
||||||
|
import nl.martijndwars.webpush.Notification;
|
||||||
|
import nl.martijndwars.webpush.Urgency;
|
||||||
|
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
|
||||||
|
public class MessageDecorator {
|
||||||
|
private MessageDto dto;
|
||||||
|
|
||||||
|
private MessageDecorator(MessageDto dto) {
|
||||||
|
this.dto = dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final MessageDecorator fromDto(MessageDto dto) {
|
||||||
|
return new MessageDecorator(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Notification toNotification(SubscriptionDecorator subscription) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
|
||||||
|
return Notification.builder()
|
||||||
|
.endpoint(subscription.getEndpoint())
|
||||||
|
.userPublicKey(subscription.getUserPublicKey())
|
||||||
|
.userAuth(subscription.getAuthAsBytes())
|
||||||
|
.payload(dto.getPayload())
|
||||||
|
.urgency(getExtUrgency())
|
||||||
|
.topic(dto.getTopic())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Urgency getExtUrgency() {
|
||||||
|
return Urgency.valueOf(dto.getUrgency().name());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package de.pushservice.server.decorator;
|
||||||
|
|
||||||
|
import de.pushservice.client.dto.SubscriptionDto;
|
||||||
|
import org.bouncycastle.jce.ECNamedCurveTable;
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
|
||||||
|
import org.bouncycastle.jce.spec.ECPublicKeySpec;
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
|
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class SubscriptionDecorator {
|
||||||
|
private SubscriptionDto dto;
|
||||||
|
|
||||||
|
private SubscriptionDecorator(SubscriptionDto dto) {
|
||||||
|
this.dto = dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final SubscriptionDecorator fromDto(SubscriptionDto dto) {
|
||||||
|
return new SubscriptionDecorator(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] getAuthAsBytes() {
|
||||||
|
return Base64.getDecoder().decode(dto.getAuth());
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getKeyAsBytes() {
|
||||||
|
return Base64.getDecoder().decode(dto.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
PublicKey getUserPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
|
||||||
|
KeyFactory kf = KeyFactory.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
|
||||||
|
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
|
||||||
|
ECPoint point = ecSpec.getCurve().decodePoint(getKeyAsBytes());
|
||||||
|
ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, ecSpec);
|
||||||
|
|
||||||
|
return kf.generatePublic(pubSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getEndpoint() {
|
||||||
|
return dto.getEndpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user