diff options
-rw-r--r-- | src/main/java/org/traccar/api/resource/PasswordResource.java | 2 | ||||
-rw-r--r-- | src/main/java/org/traccar/api/signature/TokenManager.java | 4 | ||||
-rw-r--r-- | src/main/java/org/traccar/notification/TextTemplateFormatter.java | 13 | ||||
-rw-r--r-- | templates/full/alarm.vm | 4 | ||||
-rw-r--r-- | templates/full/commandResult.vm | 4 | ||||
-rw-r--r-- | templates/full/deviceFuelDrop.vm | 2 | ||||
-rw-r--r-- | templates/full/deviceInactive.vm | 4 | ||||
-rw-r--r-- | templates/full/deviceMoving.vm | 2 | ||||
-rw-r--r-- | templates/full/deviceOffline.vm | 4 | ||||
-rw-r--r-- | templates/full/deviceOnline.vm | 4 | ||||
-rw-r--r-- | templates/full/deviceOverspeed.vm | 2 | ||||
-rw-r--r-- | templates/full/deviceStopped.vm | 2 | ||||
-rw-r--r-- | templates/full/deviceUnknown.vm | 4 | ||||
-rw-r--r-- | templates/full/driverChanged.vm | 4 | ||||
-rw-r--r-- | templates/full/geofenceEnter.vm | 2 | ||||
-rw-r--r-- | templates/full/geofenceExit.vm | 2 | ||||
-rw-r--r-- | templates/full/ignitionOff.vm | 2 | ||||
-rw-r--r-- | templates/full/ignitionOn.vm | 2 | ||||
-rw-r--r-- | templates/full/maintenance.vm | 2 | ||||
-rw-r--r-- | templates/full/media.vm | 4 | ||||
-rw-r--r-- | templates/full/textMessage.vm | 2 |
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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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°, $position.longitude°#{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> |