{{ tags.length + labels.length }}{{ tags.length + labels.length }}
diff --git a/timesketch/frontend-ng/src/components/LeftPanel/ThreatIntel.vue b/timesketch/frontend-ng/src/components/LeftPanel/ThreatIntel.vue
index 3afbe32716..b8d4fc7603 100644
--- a/timesketch/frontend-ng/src/components/LeftPanel/ThreatIntel.vue
+++ b/timesketch/frontend-ng/src/components/LeftPanel/ThreatIntel.vue
@@ -187,7 +187,7 @@ export default {
return this.$store.state.meta
},
intelligenceAttribute() {
- if (this.meta.attributes.intelligence === undefined) {
+ if (!this.meta.attributes || this.meta.attributes.intelligence === undefined) {
return { ontology: 'intelligence', value: { data: [] }, name: 'intelligence' }
}
return this.meta.attributes.intelligence
diff --git a/timesketch/frontend-ng/src/views/Sketch.vue b/timesketch/frontend-ng/src/views/Sketch.vue
index 96c04d8cd9..b5fbe49b26 100644
--- a/timesketch/frontend-ng/src/views/Sketch.vue
+++ b/timesketch/frontend-ng/src/views/Sketch.vue
@@ -14,341 +14,345 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
+
-
-
-
-
-
- It's empty around here
-
-
-
-
-
+
+
+
+
+
+
+ It's empty around here
+
+
+
+
+
-
-
-
-
-
- This sketch is archived
- Bring it back
-
-
-
-
+
+
+
+
+
+ This sketch is archived
+ Bring it back
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
- mdi-menu
-
+
+
+
+ mdi-menu
+
-
-
-
-
-
+
+
+
+
+
-
-
-
- {{ sketch.name }}
-
-
-
mdi-pencil
+
+
+
+ {{ sketch.name }}
+
+
+ mdi-pencil
+
-
-
-
-
Use the old UI
-
-
-
-
-
- mdi-account-multiple-plus
- Share
-
-
-
-
+
+
+
Use the old UI
-
- {{ currentUser | initialLetter }}
-
-
-
-
-
- mdi-dots-vertical
+
+
+
+
+ mdi-account-multiple-plus
+ Share
-
-
-
-
-
-
-
- Created: {{ sketch.created_at | shortDateTime }}
-
-
- {{ sketch.created_at | timeSince }} by {{ sketch.user.username }}
-
-
-
+
+
+
-
-
-
- Access:
- Public
- Restricted
-
-
- Visible to all users on this server
- Only people with access can open
-
-
-
-
-
-
-
-
-
- mdi-brightness-6
-
+
+ {{ currentUser | initialLetter }}
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
- Toggle theme
+
+ Created: {{ sketch.created_at | shortDateTime }}
+
+
+ {{ sketch.created_at | timeSince }} by {{ sketch.user.username }}
+
-
-
- mdi-pencil
-
+
- Rename sketch
+
+ Access:
+ Public
+ Restricted
+
+
+ Visible to all users on this server
+ Only people with access can open
+
+
-
-
- mdi-archive
-
-
- Archive sketch
-
-
+
+
+
+
+ mdi-brightness-6
+
+
+ Toggle theme
+
+
-
-
- mdi-trash-can-outline
-
-
- Delete sketch
-
-
+
+
+ mdi-pencil
+
+
+ Rename sketch
+
+
-
-
+
- mdi-logout
+ mdi-archive
+
+ Archive sketch
+
+
+
+
+ mdi-trash-can-outline
+
- Logout
+ Delete sketch
-
-
-
-
-
-
-
-
-
-
-
-
-
Investigative Scenarios
-
-
-
-
-
- Cancel
-
- Add
-
-
-
-
+
+
+
+ Cancel
+
+ Add
+
+
+
+
-
- {{ item }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- No scenarios available yet. Contact your server admin to add scenarios to this server.
- mdi-plus Add Scenario
-
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No scenarios available yet. Contact your server admin to add scenarios to this server.
+ mdi-plus Add Scenario
+
+
+
+
+ HideShow hidden scenarios ({{
+ hiddenScenarios.length
+ }})
+
+
+
-
+
+
+
+
+
+
+
+
+
+ (this.title = title)"
+ >
+
+
+
+
+
+
+ Context search
+
- HideShow hidden scenarios ({{
- hiddenScenarios.length
- }})
+ {{ duration | formatSeconds }}
-
-
-
-
-
-
-
-
-
+
+
Replace search
-
-
- (this.title = title)"
- >
-
+
-
-
-
-
- Context search
-
-
- {{ duration | formatSeconds }}
+
+ mdi-chevron-up
-
- Replace search
-
-
-
-
- mdi-chevron-up
-
-
- mdi-chevron-down
-
-
- mdi-close
-
-
-
-
-
-
-
-
-
-
+
+ mdi-chevron-down
+
+
+ mdi-close
+
+
+
+
+
+
+
+
+
+
+
diff --git a/timesketch/lib/utils.py b/timesketch/lib/utils.py
index 6ac665ae04..eb7d00453b 100644
--- a/timesketch/lib/utils.py
+++ b/timesketch/lib/utils.py
@@ -598,6 +598,10 @@ def send_email(subject, body, to_username, use_html=False):
email_smtp_server = current_app.config.get("EMAIL_SMTP_SERVER")
email_from_user = current_app.config.get("EMAIL_FROM_ADDRESS", "timesketch")
email_user_whitelist = current_app.config.get("EMAIL_USER_WHITELIST", [])
+ email_login_username = current_app.config.get("EMAIL_AUTH_USERNAME")
+ email_login_password = current_app.config.get("EMAIL_AUTH_PASSWORD")
+ email_ssl = current_app.config.get("EMAIL_SSL")
+ email_tls = current_app.config.get("EMAIL_TLS")
if not email_enabled:
raise RuntimeError("Email notifications are not enabled, aborting.")
@@ -626,6 +630,28 @@ def send_email(subject, body, to_username, use_html=False):
msg.add_header("Content-Type", email_content_type)
msg.set_payload(body)
+ # EMAIL_SSL in timesketch.conf must be set to True
+ if email_ssl:
+ smtp = smtplib.SMTP_SSL(email_smtp_server)
+ if email_login_username and email_login_password:
+ smtp.login(email_login_username, email_login_password)
+ smtp.sendmail(msg["From"], [msg["To"]], msg.as_string())
+ smtp.quit()
+ return
+ # EMAIL_TLS in timesketch.conf must be set to True
+ if email_tls:
+ smtp = smtplib.SMTP(email_smtp_server)
+ smtp.ehlo()
+ smtp.starttls()
+ if email_login_username and email_login_password:
+ smtp.login(email_login_username, email_login_password)
+ smtp.sendmail(msg["From"], [msg["To"]], msg.as_string())
+ smtp.quit()
+ return
+
+ # default - no SSL/TLS configured
smtp = smtplib.SMTP(email_smtp_server)
+ if email_login_username and email_login_password:
+ smtp.login(email_login_username, email_login_password)
smtp.sendmail(msg["From"], [msg["To"]], msg.as_string())
smtp.quit()
diff --git a/timesketch/lib/utils_test.py b/timesketch/lib/utils_test.py
index 871f420486..8e7ca0e219 100644
--- a/timesketch/lib/utils_test.py
+++ b/timesketch/lib/utils_test.py
@@ -180,6 +180,7 @@ def test_missing_timestamp_csv_file(self):
"""Test for parsing datetime values in CSV file"""
# Test that a timestamp is generated if missing.
+
expected_output = {
"message": "No timestamp",
"datetime": "2022-07-24T19:01:01+00:00",
@@ -196,6 +197,41 @@ def test_missing_timestamp_csv_file(self):
expected_output,
)
+ def test_timestamp_is_ISOformat(self):
+ """Test that timestamp values in CSV file are not altered"""
+
+ # Make sure timestamp is processed correctly, and the format is not altered
+ expected_outputs = [
+ {
+ "message": "Checking timestamp conversion",
+ "timestamp": 1331698658000000,
+ "datetime": "2012-03-14T04:17:38+00:00",
+ "timestamp_desc": "Time Logged",
+ "data_type": "This event has timestamp",
+ },
+ {
+ "message": "Checking timestamp conversion",
+ "timestamp": 1658689261000000,
+ "datetime": "2022-07-24T19:01:01+00:00",
+ "timestamp_desc": "Time Logged",
+ "data_type": "This event has timestamp",
+ },
+ {
+ "message": "Make sure message is same",
+ "timestamp": 1437789661000000,
+ "datetime": "2015-07-25T02:01:01+00:00",
+ "timestamp_desc": "Logging",
+ "data_type": "This data_type should stay the same",
+ },
+ ]
+ results = iter(
+ read_and_validate_csv(
+ "test_tools/test_events/validate_timestamp_conversion.csv"
+ )
+ )
+ for output in expected_outputs:
+ self.assertDictEqual(next(results), output)
+
def test_invalid_JSONL_file(self):
"""Test for JSONL with missing keys in the dictionary wrt headers mapping"""
linedict = {"DT": "2011-11-11", "MSG": "this is a test"}