Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions android/build.gradle

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High Software Management Finding - Software License

Code library with Restrictive license

More Details

Code library net.sf.proguard:proguard-gradle version 6.0.3 has GPL-2.0-only license, categorized as Restrictive, its use may cause a supply chain licensing issue.

Remediation guidance

  • Review the license terms to understand its specific rules.
  • If needed, Replace this component immediately with an alternative using a permissive license (e.g., MIT, Apache 2.0).
  • Consult your legal team if the component is business-critical or the terms are unclear.

To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High Software Management Finding - Software License

Code library with Restrictive license

More Details

Code library javax.xml.bind:jaxb-api version 2.3.1 has GPL-2.0-with-classpath-exception license, categorized as Restrictive, its use may cause a supply chain licensing issue.

Remediation guidance

  • Review the license terms to understand its specific rules.
  • If needed, Replace this component immediately with an alternative using a permissive license (e.g., MIT, Apache 2.0).
  • Consult your legal team if the component is business-critical or the terms are unclear.

To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High Software Management Finding - Software License

Code library with Restrictive license

More Details

Code library com.sun.istack:istack-commons-runtime version 3.0.7 has GPL-2.0-with-classpath-exception license, categorized as Restrictive, its use may cause a supply chain licensing issue.

Remediation guidance

  • Review the license terms to understand its specific rules.
  • If needed, Replace this component immediately with an alternative using a permissive license (e.g., MIT, Apache 2.0).
  • Consult your legal team if the component is business-critical or the terms are unclear.

To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High Software Management Finding - Software License

Code library with Restrictive license

More Details

Code library net.sf.proguard:proguard-base version 6.0.3 has GPL-2.0-only license, categorized as Restrictive, its use may cause a supply chain licensing issue.

Remediation guidance

  • Review the license terms to understand its specific rules.
  • If needed, Replace this component immediately with an alternative using a permissive license (e.g., MIT, Apache 2.0).
  • Consult your legal team if the component is business-critical or the terms are unclear.

To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate

Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ android {

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
test.java.srcDirs += 'src/test/kotlin'
}

defaultConfig {
Expand All @@ -52,4 +53,6 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.snowplowanalytics:snowplow-android-tracker:6.2.+"
testImplementation 'junit:junit:4.13.2'
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,16 @@ object SnowplowTrackerController {
trackEvent(pageView, eventReader)
}

fun trackDeepLinkReceived(eventReader: EventMessageReader) {
val event = eventReader.toDeepLinkReceivedWithContexts()
trackEvent(event, eventReader)
}

fun trackMessageNotification(eventReader: EventMessageReader) {
val event = eventReader.toMessageNotificationWithContexts()
trackEvent(event, eventReader)
}

private fun trackEvent(event: Event, messageReader: EventMessageReader) {
val trackerController = Snowplow.getTracker(messageReader.tracker)
val mediaTrackingId = messageReader.mediaTrackingId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class SnowplowTrackerPlugin: FlutterPlugin, MethodCallHandler {
"trackMediaVolumeChangeEvent" -> onTrackMediaVolumeChangeEvent(call, result)
"trackWebViewReader" -> onTrackWebViewReaderEvent(call, result)
"trackPageView" -> onTrackPageView(call, result)
"trackDeepLinkReceived" -> onTrackDeepLinkReceived(call, result)
"trackMessageNotification" -> onTrackMessageNotification(call, result)
else -> result.notImplemented()
}
}
Expand Down Expand Up @@ -434,4 +436,18 @@ class SnowplowTrackerPlugin: FlutterPlugin, MethodCallHandler {
result.success(null)
}

private fun onTrackDeepLinkReceived(call: MethodCall, result: MethodChannel.Result) {
(call.arguments as? Map<String, Any>)?.let {
SnowplowTrackerController.trackDeepLinkReceived(EventMessageReader(it))
}
result.success(null)
}

private fun onTrackMessageNotification(call: MethodCall, result: MethodChannel.Result) {
(call.arguments as? Map<String, Any>)?.let {
SnowplowTrackerController.trackMessageNotification(EventMessageReader(it))
}
result.success(null)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2022-present Snowplow Analytics Ltd. All rights reserved.
//
// This program is licensed to you under the Apache License Version 2.0,
// and you may not use this file except in compliance with the Apache License Version 2.0.
// You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the Apache License Version 2.0 is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.

package com.snowplowanalytics.snowplow_tracker.readers.events

import com.snowplowanalytics.snowplow.event.DeepLinkReceived

class DeepLinkReceivedReader(val values: Map<String, Any>) {
private val valuesDefault = values.withDefault { null }

val url: String by values
val referrer: String? by valuesDefault

fun toDeepLinkReceived(): DeepLinkReceived {
val event = DeepLinkReceived(url)
referrer?.let { event.referrer(it) }
return event
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2022-present Snowplow Analytics Ltd. All rights reserved.
//
// This program is licensed to you under the Apache License Version 2.0,
// and you may not use this file except in compliance with the Apache License Version 2.0.
// You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the Apache License Version 2.0 is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.

package com.snowplowanalytics.snowplow_tracker.readers.events

import com.snowplowanalytics.snowplow.event.MessageNotification
import com.snowplowanalytics.snowplow.event.MessageNotificationAttachment
import com.snowplowanalytics.snowplow.event.MessageNotificationTrigger

class MessageNotificationReader(val values: Map<String, Any>) {
private val valuesDefault = values.withDefault { null }

val title: String by values
val body: String by values
private val trigger: String by values
val action: String? by valuesDefault
val badge: Int? by lazy { (values["badge"] as? Number)?.toInt() }
val categoryIdentifier: String? by valuesDefault
val launchImageName: String? by valuesDefault
val notificationTimestamp: String? by valuesDefault
val sound: String? by valuesDefault
val subtitle: String? by valuesDefault
val threadIdentifier: String? by valuesDefault
private val attachmentsRaw: List<Map<String, Any>>? by valuesDefault
private val processedAttachments: List<MessageNotificationAttachment>? by lazy {
attachmentsRaw?.map { map ->
MessageNotificationAttachment(
map["identifier"] as String,
map["type"] as String,
map["url"] as String
)
}
}

private fun toTrigger(): MessageNotificationTrigger {
return when (trigger) {
"push" -> MessageNotificationTrigger.push
"calendar" -> MessageNotificationTrigger.calendar
"timeInterval" -> MessageNotificationTrigger.timeInterval
"location" -> MessageNotificationTrigger.location
else -> MessageNotificationTrigger.push
}
}

fun toMessageNotification(): MessageNotification {
val event = MessageNotification(title, body, toTrigger())
action?.let { event.action(it) }
badge?.let { event.badge(it) }
categoryIdentifier?.let { event.categoryIdentifier(it) }
launchImageName?.let { event.launchImageName(it) }
notificationTimestamp?.let { event.notificationTimestamp(it) }
sound?.let { event.sound(it) }
subtitle?.let { event.subtitle(it) }
threadIdentifier?.let { event.thread(it) }
processedAttachments?.let { event.attachments(it) }
return event
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,18 @@ class EventMessageReader(val values: Map<String, Any>) {
return pageView
}

fun toDeepLinkReceivedWithContexts(): DeepLinkReceived {
val event = DeepLinkReceivedReader(eventData).toDeepLinkReceived()
addContext(event)
return event
}

fun toMessageNotificationWithContexts(): MessageNotification {
val event = MessageNotificationReader(eventData).toMessageNotification()
addContext(event)
return event
}

private fun addContext(event: Event) {
contextsJsons?.let { event.entities.addAll(it) }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2022-present Snowplow Analytics Ltd. All rights reserved.
//
// This program is licensed to you under the Apache License Version 2.0,
// and you may not use this file except in compliance with the Apache License Version 2.0.
// You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the Apache License Version 2.0 is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.

package com.snowplowanalytics.snowplow_tracker.readers.events

import org.junit.Assert.*
import org.junit.Test

class DeepLinkReceivedReaderTest {

@Test
fun `reader extracts required url`() {
val map = mapOf("url" to "https://example.com/path")
val reader = DeepLinkReceivedReader(map)

assertEquals("https://example.com/path", reader.url)
assertNull(reader.referrer)
}

@Test
fun `reader extracts optional referrer`() {
val map = mapOf(
"url" to "https://example.com/path",
"referrer" to "https://referrer.example.com"
)
val reader = DeepLinkReceivedReader(map)

assertEquals("https://example.com/path", reader.url)
assertEquals("https://referrer.example.com", reader.referrer)
}

@Test
fun `toDeepLinkReceived produces event with url`() {
val map = mapOf("url" to "https://example.com/path")
val reader = DeepLinkReceivedReader(map)
val event = reader.toDeepLinkReceived()

assertNotNull(event)
}

@Test
fun `toDeepLinkReceived produces event with referrer`() {
val map = mapOf(
"url" to "https://example.com/path",
"referrer" to "https://referrer.example.com"
)
val reader = DeepLinkReceivedReader(map)
val event = reader.toDeepLinkReceived()

assertNotNull(event)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright (c) 2022-present Snowplow Analytics Ltd. All rights reserved.
//
// This program is licensed to you under the Apache License Version 2.0,
// and you may not use this file except in compliance with the Apache License Version 2.0.
// You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the Apache License Version 2.0 is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.

package com.snowplowanalytics.snowplow_tracker.readers.events

import org.junit.Assert.*
import org.junit.Test

class MessageNotificationReaderTest {

@Test
fun `reader extracts required fields`() {
val map = mapOf(
"title" to "Test Title",
"body" to "Test Body",
"trigger" to "push"
)
val reader = MessageNotificationReader(map)

assertEquals("Test Title", reader.title)
assertEquals("Test Body", reader.body)
}

@Test
fun `reader extracts optional fields`() {
val map = mapOf(
"title" to "Title",
"body" to "Body",
"trigger" to "calendar",
"action" to "Open",
"badge" to 3,
"categoryIdentifier" to "cat1",
"launchImageName" to "launch",
"notificationTimestamp" to "2023-01-01T00:00:00Z",
"sound" to "default",
"subtitle" to "Subtitle",
"threadIdentifier" to "thread1"
)
val reader = MessageNotificationReader(map)

assertEquals("Open", reader.action)
assertEquals(3, reader.badge)
assertEquals("cat1", reader.categoryIdentifier)
assertEquals("launch", reader.launchImageName)
assertEquals("2023-01-01T00:00:00Z", reader.notificationTimestamp)
assertEquals("default", reader.sound)
assertEquals("Subtitle", reader.subtitle)
assertEquals("thread1", reader.threadIdentifier)
}

@Test
fun `reader nulls optional fields when absent`() {
val map = mapOf(
"title" to "Title",
"body" to "Body",
"trigger" to "push"
)
val reader = MessageNotificationReader(map)

assertNull(reader.action)
assertNull(reader.badge)
assertNull(reader.categoryIdentifier)
assertNull(reader.launchImageName)
assertNull(reader.notificationTimestamp)
assertNull(reader.sound)
assertNull(reader.subtitle)
assertNull(reader.threadIdentifier)
}

@Test
fun `toMessageNotification produces event with required fields`() {
val map = mapOf(
"title" to "Title",
"body" to "Body",
"trigger" to "push"
)
val reader = MessageNotificationReader(map)
val event = reader.toMessageNotification()

assertNotNull(event)
}

@Test
fun `toMessageNotification produces event with all optional fields`() {
val attachmentMap = mapOf(
"identifier" to "att1",
"type" to "image/png",
"url" to "https://example.com/image.png"
)
val map = mapOf(
"title" to "Title",
"body" to "Body",
"trigger" to "timeInterval",
"action" to "Open",
"badge" to 2,
"categoryIdentifier" to "cat1",
"launchImageName" to "launch",
"notificationTimestamp" to "2023-01-01T00:00:00Z",
"sound" to "default",
"subtitle" to "Subtitle",
"threadIdentifier" to "thread1",
"attachments" to listOf(attachmentMap)
)
val reader = MessageNotificationReader(map)
val event = reader.toMessageNotification()

assertNotNull(event)
}

@Test
fun `reader handles all trigger values`() {
listOf("push", "calendar", "timeInterval", "location").forEach { triggerStr ->
val map = mapOf(
"title" to "Title",
"body" to "Body",
"trigger" to triggerStr
)
val reader = MessageNotificationReader(map)
val event = reader.toMessageNotification()
assertNotNull("Event should not be null for trigger: $triggerStr", event)
}
}
}
Loading
Loading