aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-08-02 21:01:06 -0700
committerAnton Tananaev <anton@traccar.org>2022-08-02 21:01:06 -0700
commitbb7bdcfc3389b6822b7680837386e3650962f30a (patch)
tree624eb4d9d8dcb6fff2169db85213387cf91ee26b
parentbd55a835340547aabc3f401bb97e181a3e70df8f (diff)
downloadtrackermap-server-bb7bdcfc3389b6822b7680837386e3650962f30a.tar.gz
trackermap-server-bb7bdcfc3389b6822b7680837386e3650962f30a.tar.bz2
trackermap-server-bb7bdcfc3389b6822b7680837386e3650962f30a.zip
Notifications unsubscribe option
-rw-r--r--src/main/java/org/traccar/api/resource/PasswordResource.java2
-rw-r--r--src/main/java/org/traccar/api/signature/TokenManager.java4
-rw-r--r--src/main/java/org/traccar/notification/TextTemplateFormatter.java13
-rw-r--r--templates/full/alarm.vm4
-rw-r--r--templates/full/commandResult.vm4
-rw-r--r--templates/full/deviceFuelDrop.vm2
-rw-r--r--templates/full/deviceInactive.vm4
-rw-r--r--templates/full/deviceMoving.vm2
-rw-r--r--templates/full/deviceOffline.vm4
-rw-r--r--templates/full/deviceOnline.vm4
-rw-r--r--templates/full/deviceOverspeed.vm2
-rw-r--r--templates/full/deviceStopped.vm2
-rw-r--r--templates/full/deviceUnknown.vm4
-rw-r--r--templates/full/driverChanged.vm4
-rw-r--r--templates/full/geofenceEnter.vm2
-rw-r--r--templates/full/geofenceExit.vm2
-rw-r--r--templates/full/ignitionOff.vm2
-rw-r--r--templates/full/ignitionOn.vm2
-rw-r--r--templates/full/maintenance.vm2
-rw-r--r--templates/full/media.vm4
-rw-r--r--templates/full/textMessage.vm2
21 files changed, 61 insertions, 10 deletions
diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java
index 1fb08b02a..625ff4cb1 100644
--- a/src/main/java/org/traccar/api/resource/PasswordResource.java
+++ b/src/main/java/org/traccar/api/resource/PasswordResource.java
@@ -62,7 +62,7 @@ public class PasswordResource extends BaseResource {
new Columns.All(), new Condition.Equals("email", "email", email)));
if (user != null) {
var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user);
- velocityContext.put("token", tokenManager.generateToken(user.getId(), null));
+ velocityContext.put("token", tokenManager.generateToken(user.getId()));
var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full");
mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody());
}
diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java
index a51234a95..a352ecc10 100644
--- a/src/main/java/org/traccar/api/signature/TokenManager.java
+++ b/src/main/java/org/traccar/api/signature/TokenManager.java
@@ -46,6 +46,10 @@ public class TokenManager {
this.cryptoManager = cryptoManager;
}
+ public String generateToken(long userId) throws IOException, GeneralSecurityException, StorageException {
+ return generateToken(userId, null);
+ }
+
public String generateToken(
long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException {
Data data = new Data();
diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java
index bca18f53c..be894af96 100644
--- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java
+++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java
@@ -23,14 +23,18 @@ import org.apache.velocity.tools.generic.DateTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.traccar.api.signature.TokenManager;
import org.traccar.helper.model.UserUtil;
import org.traccar.model.Server;
import org.traccar.model.User;
+import org.traccar.storage.StorageException;
import javax.inject.Inject;
+import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
import java.util.Locale;
public class TextTemplateFormatter {
@@ -38,10 +42,12 @@ public class TextTemplateFormatter {
private static final Logger LOGGER = LoggerFactory.getLogger(TextTemplateFormatter.class);
private final VelocityEngine velocityEngine;
+ private final TokenManager tokenManager;
@Inject
- public TextTemplateFormatter(VelocityEngine velocityEngine) {
+ public TextTemplateFormatter(VelocityEngine velocityEngine, TokenManager tokenManager) {
this.velocityEngine = velocityEngine;
+ this.tokenManager = tokenManager;
}
public VelocityContext prepareContext(Server server, User user) {
@@ -51,6 +57,11 @@ public class TextTemplateFormatter {
if (user != null) {
velocityContext.put("user", user);
velocityContext.put("timezone", UserUtil.getTimezone(server, user));
+ try {
+ velocityContext.put("token", tokenManager.generateToken(user.getId()));
+ } catch (IOException | GeneralSecurityException | StorageException e) {
+ LOGGER.warn("Token generation failed", e);
+ }
}
velocityContext.put("webUrl", velocityEngine.getProperty("web.url"));
diff --git a/templates/full/alarm.vm b/templates/full/alarm.vm
index 8eac3930a..5d367dc3a 100644
--- a/templates/full/alarm.vm
+++ b/templates/full/alarm.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Alarm: $position.getString("alarm")<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
-</html>
+</html>
diff --git a/templates/full/commandResult.vm b/templates/full/commandResult.vm
index 443e1a399..c3b62edf5 100644
--- a/templates/full/commandResult.vm
+++ b/templates/full/commandResult.vm
@@ -5,6 +5,8 @@
Device: $device.name<br>
Result: $position.getString("result")<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
-Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a>
+Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceFuelDrop.vm b/templates/full/deviceFuelDrop.vm
index bf7a16b97..3fb9aa63c 100644
--- a/templates/full/deviceFuelDrop.vm
+++ b/templates/full/deviceFuelDrop.vm
@@ -5,5 +5,7 @@
Device: $device.name<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceInactive.vm b/templates/full/deviceInactive.vm
index 626db1dc4..01fa319b5 100644
--- a/templates/full/deviceInactive.vm
+++ b/templates/full/deviceInactive.vm
@@ -7,6 +7,8 @@
Device: $device.name<br>
Inactive<br>
Last Update: $dateTool.format("YYYY-MM-dd HH:mm:ss", $lastUpdate, $locale, $timezone)<br>
-Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a>
+Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceMoving.vm b/templates/full/deviceMoving.vm
index b22b90428..e3941b324 100644
--- a/templates/full/deviceMoving.vm
+++ b/templates/full/deviceMoving.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Moving<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceOffline.vm b/templates/full/deviceOffline.vm
index 332bfe3d9..8f2c515b2 100644
--- a/templates/full/deviceOffline.vm
+++ b/templates/full/deviceOffline.vm
@@ -5,6 +5,8 @@
Device: $device.name<br>
Offline<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
-Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a>
+Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceOnline.vm b/templates/full/deviceOnline.vm
index 3ca3cfa9b..81a4ccbc8 100644
--- a/templates/full/deviceOnline.vm
+++ b/templates/full/deviceOnline.vm
@@ -5,6 +5,8 @@
Device: $device.name<br>
Online<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
-Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a>
+Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceOverspeed.vm b/templates/full/deviceOverspeed.vm
index f303b734c..5f38b3f88 100644
--- a/templates/full/deviceOverspeed.vm
+++ b/templates/full/deviceOverspeed.vm
@@ -15,5 +15,7 @@ Device: $device.name<br>
Exceeds the speed: $speedString#{if}($geofence) in $geofence.name#{else}#{end}<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceStopped.vm b/templates/full/deviceStopped.vm
index 9f8a30707..e3246b277 100644
--- a/templates/full/deviceStopped.vm
+++ b/templates/full/deviceStopped.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Stopped<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/deviceUnknown.vm b/templates/full/deviceUnknown.vm
index 0e6e9b4b4..e012845e6 100644
--- a/templates/full/deviceUnknown.vm
+++ b/templates/full/deviceUnknown.vm
@@ -5,6 +5,8 @@
Device: $device.name<br>
Status is unknown<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
-Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a>
+Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/driverChanged.vm b/templates/full/driverChanged.vm
index 65e2768b5..f9b6d0ae2 100644
--- a/templates/full/driverChanged.vm
+++ b/templates/full/driverChanged.vm
@@ -5,6 +5,8 @@
Device: $device.name<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
-Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end}
+Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end}<br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/geofenceEnter.vm b/templates/full/geofenceEnter.vm
index 2d9cd3613..5ae14a8d3 100644
--- a/templates/full/geofenceEnter.vm
+++ b/templates/full/geofenceEnter.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Has entered geofence: $geofence.name<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/geofenceExit.vm b/templates/full/geofenceExit.vm
index ae1eb5520..08887a93a 100644
--- a/templates/full/geofenceExit.vm
+++ b/templates/full/geofenceExit.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Has exited geofence: $geofence.name<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/ignitionOff.vm b/templates/full/ignitionOff.vm
index 0ec50918b..a43e4aabb 100644
--- a/templates/full/ignitionOff.vm
+++ b/templates/full/ignitionOff.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Ignition OFF<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/ignitionOn.vm b/templates/full/ignitionOn.vm
index 7e0d6532d..1ba9ef030 100644
--- a/templates/full/ignitionOn.vm
+++ b/templates/full/ignitionOn.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Ignition ON<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/maintenance.vm b/templates/full/maintenance.vm
index 798de637d..39ccb21bc 100644
--- a/templates/full/maintenance.vm
+++ b/templates/full/maintenance.vm
@@ -6,5 +6,7 @@ Device: $device.name<br>
Maintenance is required: $maintenance.name<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/media.vm b/templates/full/media.vm
index 6651deffc..1c94265fb 100644
--- a/templates/full/media.vm
+++ b/templates/full/media.vm
@@ -6,6 +6,8 @@ Device: $device.name<br>
Type: $event.getString("media")<br>
File: <a href="$webUrl/api/media/$device.uniqueId/$event.getString("file")">$event.getString("file")</a><br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
-Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a>
+Link: <a href="$webUrl?eventId=$event.id">$webUrl?eventId=$event.id</a><br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
diff --git a/templates/full/textMessage.vm b/templates/full/textMessage.vm
index 7222b4d91..fb20275e3 100644
--- a/templates/full/textMessage.vm
+++ b/templates/full/textMessage.vm
@@ -5,5 +5,7 @@
Device: $device.name<br>
Message: $event.getString("message")<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
+<br>
+<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>