diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000000..e29309cb7e --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1 @@ +enhancement_labels=enhancement, Enhancement,feature request diff --git a/CHANGELOG.md b/CHANGELOG.md index fcdb163355..128b9e1adc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,43 @@ # Change Log +## [2.10.1](https://github.com/CERT-BDF/TheHive/tree/2.10.0) (2017-03-08) +[Full Changelog](https://github.com/CERT-BDF/TheHive/compare/2.10.0...2.10.0) + +**Implemented enhancements:** + +- Remove the "Run all analyzers" option from observables list [\#141](https://github.com/CERT-BDF/TheHive/issues/141) +- Remove duplicate stream callbacks registration [\#138](https://github.com/CERT-BDF/TheHive/issues/138) +- Typo in quick filters [\#134](https://github.com/CERT-BDF/TheHive/issues/134) +- Display a warning when trying to merge an already merged case [\#129](https://github.com/CERT-BDF/TheHive/issues/129) +- Restyle avatar's upload button [\#126](https://github.com/CERT-BDF/TheHive/issues/126) +- Feature Request: Ansible build scripts [\#124](https://github.com/CERT-BDF/TheHive/issues/124) +- Add pagination component at the top of the task log [\#116](https://github.com/CERT-BDF/TheHive/issues/116) +- Disable buttons in MISP event's preview dialog [\#115](https://github.com/CERT-BDF/TheHive/issues/115) +- Make The Hive working on any URL path and not only / [\#114](https://github.com/CERT-BDF/TheHive/issues/114) +- Misleading MISP Event Date and Time [\#101](https://github.com/CERT-BDF/TheHive/issues/101) +- Upgrade to the last version of UI-Bootstrap UI library [\#79](https://github.com/CERT-BDF/TheHive/issues/79) + +**Fixed bugs:** + +- Fix OTXQuery report template [\#142](https://github.com/CERT-BDF/TheHive/issues/142) +- 401 HTTP responses don't trigger redirection to login page [\#140](https://github.com/CERT-BDF/TheHive/issues/140) +- Fix a JS issue related to inactivity dialog [\#139](https://github.com/CERT-BDF/TheHive/issues/139) +- Flow is not shown [\#127](https://github.com/CERT-BDF/TheHive/issues/127) +- Case merge does not close tasks in merged cases [\#118](https://github.com/CERT-BDF/TheHive/issues/118) +- Web UI doesn't refresh once a report template is deleted [\#113](https://github.com/CERT-BDF/TheHive/issues/113) +- Open log in new windows [\#108](https://github.com/CERT-BDF/TheHive/issues/108) +- Cannot add an observable which datatype has been added by an admin [\#106](https://github.com/CERT-BDF/TheHive/issues/106) +- Observables password hint does not reflect backend change [\#83](https://github.com/CERT-BDF/TheHive/issues/83) + ## [2.10.0](https://github.com/CERT-BDF/TheHive/tree/2.10.0) (2017-02-01) [Full Changelog](https://github.com/CERT-BDF/TheHive/compare/2.9.2...2.10.0) **Implemented enhancements:** - Improve cases listing page [\#76](https://github.com/CERT-BDF/TheHive/issues/76) +- Feature Request - Add Case Statistics by Severity [\#70](https://github.com/CERT-BDF/TheHive/issues/70) +- Use avatars in user profiles [\#69](https://github.com/CERT-BDF/TheHive/issues/69) +- Allow \(un\)set observable as IOC from the observable's page [\#68](https://github.com/CERT-BDF/TheHive/issues/68) - When closing a task, close the associated tab as well [\#66](https://github.com/CERT-BDF/TheHive/issues/66) - Load the Current Cases View when Closing a Case [\#61](https://github.com/CERT-BDF/TheHive/issues/61) - Externalize observable analysis [\#53](https://github.com/CERT-BDF/TheHive/issues/53) @@ -31,10 +63,6 @@ **Closed issues:** -- Update BuildGuide [\#102](https://github.com/CERT-BDF/TheHive/issues/102) -- Feature Request - Add Case Statistics by Severity [\#70](https://github.com/CERT-BDF/TheHive/issues/70) -- Use avatars in user profiles [\#69](https://github.com/CERT-BDF/TheHive/issues/69) -- Allow \(un\)set observable as IOC from the observable's page [\#68](https://github.com/CERT-BDF/TheHive/issues/68) - Database schema update \(v8\) [\#67](https://github.com/CERT-BDF/TheHive/issues/67) - Add support for more filetypes to PE\_info analyser [\#54](https://github.com/CERT-BDF/TheHive/issues/54) - Create an analyzer to get information about PE file [\#51](https://github.com/CERT-BDF/TheHive/issues/51) @@ -48,21 +76,25 @@ ## [2.9.2](https://github.com/CERT-BDF/TheHive/tree/2.9.2) (2017-01-19) [Full Changelog](https://github.com/CERT-BDF/TheHive/compare/2.9.1...2.9.2) -**Fixed bugs:** +**Implemented enhancements:** -- docker image: $.post\(...\).success is not a function [\#95](https://github.com/CERT-BDF/TheHive/issues/95) +- Feature Request - Add observable statistics [\#71](https://github.com/CERT-BDF/TheHive/issues/71) -**Closed issues:** +**Fixed bugs:** -- Feature Request - Add observable statistics [\#71](https://github.com/CERT-BDF/TheHive/issues/71) +- docker image: $.post\(...\).success is not a function [\#95](https://github.com/CERT-BDF/TheHive/issues/95) ## [2.9.1](https://github.com/CERT-BDF/TheHive/tree/2.9.1) (2016-11-28) **Implemented enhancements:** +- Statistics on a per case template name / prefix basis [\#31](https://github.com/CERT-BDF/TheHive/issues/31) +- Observable Viewing Page [\#17](https://github.com/CERT-BDF/TheHive/issues/17) - Update logo and favicon [\#45](https://github.com/CERT-BDF/TheHive/issues/45) - Inconsistent wording between the login and user management pages [\#44](https://github.com/CERT-BDF/TheHive/issues/44) - MaxMind Analyzer 'Short Report' has hard-coded language [\#23](https://github.com/CERT-BDF/TheHive/issues/23) - Don't update imported case from MISP if it is deleted or merged [\#22](https://github.com/CERT-BDF/TheHive/issues/22) +- Case merging [\#14](https://github.com/CERT-BDF/TheHive/issues/14) +- New analyzer to check URL categories [\#24](https://github.com/CERT-BDF/TheHive/pull/24) ([ecapuano](https://github.com/ecapuano)) **Fixed bugs:** @@ -80,18 +112,14 @@ **Closed issues:** - Statistics based on Tags [\#37](https://github.com/CERT-BDF/TheHive/issues/37) -- Statistics on a per case template name / prefix basis [\#31](https://github.com/CERT-BDF/TheHive/issues/31) -- Observable Viewing Page [\#17](https://github.com/CERT-BDF/TheHive/issues/17) - Give us something to work with! [\#2](https://github.com/CERT-BDF/TheHive/issues/2) -- Case merging [\#14](https://github.com/CERT-BDF/TheHive/issues/14) **Merged pull requests:** - Fix "Run from Docker" [\#9](https://github.com/CERT-BDF/TheHive/pull/9) ([2xyo](https://github.com/2xyo)) - Fixing a Simple Typo [\#6](https://github.com/CERT-BDF/TheHive/pull/6) ([swannysec](https://github.com/swannysec)) - Fixed broken link to Wiki [\#1](https://github.com/CERT-BDF/TheHive/pull/1) ([Neo23x0](https://github.com/Neo23x0)) -- New analyzer to check URL categories [\#24](https://github.com/CERT-BDF/TheHive/pull/24) ([ecapuano](https://github.com/ecapuano)) -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* diff --git a/contrib/report-templates/Abuse_Finder_1.0/long.html b/contrib/report-templates/Abuse_Finder_1.0/long.html index ac00ebf345..ee902b1b50 100644 --- a/contrib/report-templates/Abuse_Finder_1.0/long.html +++ b/contrib/report-templates/Abuse_Finder_1.0/long.html @@ -11,7 +11,7 @@ -
+
Abuse addresses:
@@ -21,3 +21,13 @@
+ + +
+
+ {{(artifact.data || artifact.attachment.name) | fang}} +
+
+ {{content.errorMessage}} +
+
diff --git a/contrib/report-templates/OTXQuery_1_0/long.html b/contrib/report-templates/OTXQuery_1_0/long.html index 2e25f9c36c..f1c39b6739 100644 --- a/contrib/report-templates/OTXQuery_1_0/long.html +++ b/contrib/report-templates/OTXQuery_1_0/long.html @@ -1,4 +1,14 @@ -
+
+
+ {{artifact.data | fang}} +
+
+ {{content.errorMessage}} +
+
+ + +
OTX Report
diff --git a/dockerCreation.txt b/dockerCreation.txt deleted file mode 100644 index 89432077d2..0000000000 --- a/dockerCreation.txt +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -if test -z "$DISABLE_ELASTICSEARCH"; then - echo "Starting ElasticSearch ..." - /docker-entrypoint.sh elasticsearch \ - -Des.path.data=/data \ - -Des.script.inline=on \ - -Des.cluster.name=hive \ - -Des.threadpool.index.queue_size=100000 \ - -Des.threadpool.search.queue_size=100000 \ - -Des.threadpool.bulk.queue_size=1000 & -else - echo "Skip ElasticSearch startup" -fi - -if test -z CRYPTO_SECRET; then - echo "Generating random crypto secret ..." - CRYPTO_SECRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1) -else - echo "Using provided crypto secret -fi - -if test -z "$DISABLE_CORTEX"; then - echo "Starting Cortex ..." - if test ! -e conf/cortex.conf; then - cat > conf/cortex.conf <<- _EOF_ -play.crypto.secret="$CRYPTO_SECRET" -analyzer.path=/opt/Cortex-Analyzers/analyzers -include analyzers.conf -_EOF_ - fi - bin/cortex -Dconfig.file=config/cortex.conf -Dhttp.port=9001 -Dpidfile.path=cortex.pid & -fi - -echo "Starting TheHive ..." -if test ! -e conf/thehive.conf; then - cat > conf/thehive.conf <<- _EOF_ -play.crypto.secret="$CRYPTO_SECRET" -play.modules.enabled+=connectors.cortex.CortexConnector -cortex.local.url="http://127.0.0.1:9001" - -_EOF_ -fi -bin/thehive -Dconfig.file=config/thehive.conf -Dpidfile.path=thehive.pid & diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8870a87f94..b50f9a7c51 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -29,7 +29,7 @@ object Dependencies { val reflections = "org.reflections" % "reflections" % "0.9.10" val zip4j = "net.lingala.zip4j" % "zip4j" % "1.3.2" val akkaTest = "com.typesafe.akka" %% "akka-stream-testkit" % "2.4.4" - val elastic4play = "org.cert-bdf" %% "elastic4play" % "1.1.2" + val elastic4play = "org.cert-bdf" %% "elastic4play" % "1.1.3" object Elastic4s { private val version = "2.3.0" diff --git a/thehive-backend/app/controllers/Artifact.scala b/thehive-backend/app/controllers/Artifact.scala index 59d49732ea..9a7439dc64 100644 --- a/thehive-backend/app/controllers/Artifact.scala +++ b/thehive-backend/app/controllers/Artifact.scala @@ -95,7 +95,7 @@ class ArtifactCtrl @Inject() ( val withStats = request.body.getBoolean("nstats").getOrElse(false) val (artifacts, total) = artifactSrv.find(query, range, sort) - val artifactWithCase = auxSrv(artifacts, nparent, withStats) + val artifactWithCase = auxSrv(artifacts, nparent, withStats, false) renderer.toOutput(OK, artifactWithCase, total) } @@ -106,7 +106,7 @@ class ArtifactCtrl @Inject() ( val sort = request.body.getStrings("sort").getOrElse(Nil) val (artifacts, total) = artifactSrv.findSimilar(artifact, range, sort) - val artifactWithCase = auxSrv(artifacts, 1, false) + val artifactWithCase = auxSrv(artifacts, 1, false, true) renderer.toOutput(OK, artifactWithCase, total) } } @@ -117,4 +117,4 @@ class ArtifactCtrl @Inject() ( val aggs = request.body.getValue("stats").getOrElse(throw BadRequestError("Parameter \"stats\" is missing")).as[Seq[Agg]] artifactSrv.stats(query, aggs).map(s ⇒ Ok(s)) } -} \ No newline at end of file +} diff --git a/thehive-backend/app/controllers/Case.scala b/thehive-backend/app/controllers/Case.scala index dd505acd21..ad682017f3 100644 --- a/thehive-backend/app/controllers/Case.scala +++ b/thehive-backend/app/controllers/Case.scala @@ -56,7 +56,7 @@ class CaseCtrl @Inject() ( for { caze ← caseSrv.get(id) - casesWithStats ← auxSrv.apply(caze, 0, withStats.getOrElse(false)) + casesWithStats ← auxSrv.apply(caze, 0, withStats.getOrElse(false), false) } yield renderer.toOutput(OK, casesWithStats) } @@ -96,7 +96,7 @@ class CaseCtrl @Inject() ( val withStats = request.body.getBoolean("nstats").getOrElse(false) val (cases, total) = caseSrv.find(query, range, sort) - val casesWithStats = auxSrv.apply(cases, nparent, withStats) + val casesWithStats = auxSrv.apply(cases, nparent, withStats, false) renderer.toOutput(OK, casesWithStats, total) } diff --git a/thehive-backend/app/controllers/CaseTemplate.scala b/thehive-backend/app/controllers/CaseTemplate.scala index b0ac798c06..61479559a1 100644 --- a/thehive-backend/app/controllers/CaseTemplate.scala +++ b/thehive-backend/app/controllers/CaseTemplate.scala @@ -59,7 +59,7 @@ class CaseTemplateCtrl @Inject() ( val withStats = request.body.getBoolean("nstats").getOrElse(false) val (caseTemplates, total) = caseTemplateSrv.find(query, range, sort) - val caseTemplatesWithStats = auxSrv(caseTemplates, nparent, withStats) + val caseTemplatesWithStats = auxSrv(caseTemplates, nparent, withStats, false) renderer.toOutput(OK, caseTemplatesWithStats, total) } } \ No newline at end of file diff --git a/thehive-backend/app/controllers/Search.scala b/thehive-backend/app/controllers/Search.scala index 4bcb5cec13..202e66f7eb 100644 --- a/thehive-backend/app/controllers/Search.scala +++ b/thehive-backend/app/controllers/Search.scala @@ -32,7 +32,7 @@ class SearchCtrl @Inject() ( val withStats = request.body.getBoolean("nstats").getOrElse(false) val (entities, total) = findSrv(None, and(query, "status" ~!= "Deleted", not(or(ofType("audit"), ofType("data"), ofType("user"), ofType("analyzer"), ofType("misp")))), range, sort) - val entitiesWithStats = auxSrv(entities, nparent, withStats) + val entitiesWithStats = auxSrv(entities, nparent, withStats, true) renderer.toOutput(OK, entitiesWithStats, total) } } \ No newline at end of file diff --git a/thehive-backend/app/controllers/Status.scala b/thehive-backend/app/controllers/Status.scala index ddfd6d0839..6b2c6874b4 100644 --- a/thehive-backend/app/controllers/Status.scala +++ b/thehive-backend/app/controllers/Status.scala @@ -4,6 +4,7 @@ import javax.inject.{ Inject, Singleton } import scala.collection.immutable +import play.api.Configuration import play.api.libs.json.Json import play.api.libs.json.Json.toJsFieldJsValueWrapper import play.api.mvc.{ Action, Controller } @@ -23,6 +24,7 @@ import org.elastic4play.services.AuthSrv @Singleton class StatusCtrl @Inject() ( connectors: immutable.Set[Connector], + configuration: Configuration, authSrv: AuthSrv) extends Controller { private[controllers] def getVersion(c: Class[_]) = Option(c.getPackage.getImplementationVersion).getOrElse("SNAPSHOT") @@ -38,10 +40,11 @@ class StatusCtrl @Inject() ( "ElasticSearch" → getVersion(classOf[org.elasticsearch.Build])), "connectors" → JsObject(connectors.map(c ⇒ c.name → c.status).toSeq), "config" → Json.obj( + "protectDownloadsWith" → configuration.getString("datastore.attachment.password").get, "authType" → (authSrv match { case multiAuthSrv: MultiAuthSrv ⇒ multiAuthSrv.authProviders.map { a ⇒ JsString(a.name) } case _ ⇒ JsString(authSrv.name) }), "capabilities" → authSrv.capabilities.map(c ⇒ JsString(c.toString))))) } -} \ No newline at end of file +} diff --git a/thehive-backend/app/controllers/Task.scala b/thehive-backend/app/controllers/Task.scala index 310b66043b..865a7d7d1e 100644 --- a/thehive-backend/app/controllers/Task.scala +++ b/thehive-backend/app/controllers/Task.scala @@ -71,7 +71,7 @@ class TaskCtrl @Inject() ( val withStats = request.body.getBoolean("stats").getOrElse(false) val (tasks, total) = taskSrv.find(query, range, sort) - val tasksWithStats = auxSrv.apply(tasks, nparent, withStats) + val tasksWithStats = auxSrv.apply(tasks, nparent, withStats, false) renderer.toOutput(OK, tasksWithStats, total) } diff --git a/thehive-backend/app/services/CaseMergeSrv.scala b/thehive-backend/app/services/CaseMergeSrv.scala index d91c2cff8d..08c6952683 100644 --- a/thehive-backend/app/services/CaseMergeSrv.scala +++ b/thehive-backend/app/services/CaseMergeSrv.scala @@ -264,6 +264,7 @@ class CaseMergeSrv @Inject() ( _ ← mergeTasksAndLogs(newCase, cases) _ ← mergeArtifactsAndJobs(newCase, cases) _ ← markCaseAsDuplicated(cases, newCase) + _ ← Future.traverse(cases)(caze ⇒ taskSrv.closeTasksOfCase(caze.id)) } yield newCase } } \ No newline at end of file diff --git a/thehive-backend/app/services/FlowSrv.scala b/thehive-backend/app/services/FlowSrv.scala index 70d9c172ab..b8c9ad6ab5 100644 --- a/thehive-backend/app/services/FlowSrv.scala +++ b/thehive-backend/app/services/FlowSrv.scala @@ -46,7 +46,7 @@ class FlowSrv @Inject() ( } } } - val fObj = auxSrv.apply(audit.objectType(), audit.objectId(), 10, false) + val fObj = auxSrv.apply(audit.objectType(), audit.objectId(), 10, false, true) for { summary ← fSummary diff --git a/thehive-backend/app/services/StreamMessage.scala b/thehive-backend/app/services/StreamMessage.scala index 2b87f1afd9..91b4ae0b16 100644 --- a/thehive-backend/app/services/StreamMessage.scala +++ b/thehive-backend/app/services/StreamMessage.scala @@ -66,7 +66,7 @@ object AuditOperationGroup { } .collect { case (name, value, Some(attr)) if !attr.isUnaudited ⇒ (name, value) } } - val obj = auxSrv(operation.entity, 10, false) + val obj = auxSrv(operation.entity, 10, false, true) .recover { case error ⇒ log.error("auxSrv fails", error) diff --git a/thehive-cortex/app/connectors/cortex/controllers/CortextCtrl.scala b/thehive-cortex/app/connectors/cortex/controllers/CortextCtrl.scala index acf1356fc5..99fdd324fd 100644 --- a/thehive-cortex/app/connectors/cortex/controllers/CortextCtrl.scala +++ b/thehive-cortex/app/connectors/cortex/controllers/CortextCtrl.scala @@ -14,7 +14,7 @@ import play.api.routing.sird.{ DELETE, GET, PATCH, POST, UrlContext } import org.elastic4play.{ BadRequestError, NotFoundError, Timed } import org.elastic4play.controllers.{ Authenticated, FieldsBodyParser, Renderer } import org.elastic4play.models.JsonFormat.baseModelEntityWrites -import org.elastic4play.services.{ QueryDef, QueryDSL, Role } +import org.elastic4play.services.{ AuxSrv, QueryDef, QueryDSL, Role } import org.elastic4play.services.JsonFormat.queryReads import connectors.Connector @@ -26,6 +26,7 @@ class CortextCtrl @Inject() ( reportTemplateCtrl: ReportTemplateCtrl, cortexConfig: CortexConfig, cortexSrv: CortexSrv, + auxSrv: AuxSrv, authenticated: Authenticated, fieldsBodyParser: FieldsBodyParser, renderer: Renderer, @@ -74,7 +75,8 @@ class CortextCtrl @Inject() ( val sort = request.body.getStrings("sort").getOrElse(Nil) val (jobs, total) = cortexSrv.find(query, range, sort) - renderer.toOutput(OK, jobs, total) + val jobWithoutReport = auxSrv.apply(jobs, 0, false, true) + renderer.toOutput(OK, jobWithoutReport, total) } @Timed diff --git a/thehive-cortex/app/connectors/cortex/controllers/ReportTemplate.scala b/thehive-cortex/app/connectors/cortex/controllers/ReportTemplate.scala index 879d723292..b16b566527 100644 --- a/thehive-cortex/app/connectors/cortex/controllers/ReportTemplate.scala +++ b/thehive-cortex/app/connectors/cortex/controllers/ReportTemplate.scala @@ -86,7 +86,7 @@ class ReportTemplateCtrl @Inject() ( val withStats = request.body.getBoolean("nstats").getOrElse(false) val (reportTemplates, total) = reportTemplateSrv.find(query, range, sort) - val reportTemplatesWithStats = auxSrv(reportTemplates, nparent, withStats) + val reportTemplatesWithStats = auxSrv(reportTemplates, nparent, withStats, false) renderer.toOutput(OK, reportTemplatesWithStats, total) } diff --git a/ui/app/scripts/app.js b/ui/app/scripts/app.js index b0193a48d6..86e8c132ae 100644 --- a/ui/app/scripts/app.js +++ b/ui/app/scripts/app.js @@ -212,7 +212,12 @@ angular.module('thehive', ['ngAnimate', 'ngMessages', 'ui.bootstrap', 'ui.router .state('app.case.observables-item', { url: '/observables/{itemId}', templateUrl: 'views/partials/case/case.observables.item.html', - controller: 'CaseObservablesItemCtrl' + controller: 'CaseObservablesItemCtrl', + resolve: { + appConfig: function(VersionSrv) { + return VersionSrv.get(); + } + } }) .state('app.misp-list', { url: 'misp/list', @@ -226,7 +231,7 @@ angular.module('thehive', ['ngAnimate', 'ngMessages', 'ui.bootstrap', 'ui.router $httpProvider.interceptors.push(function($rootScope, $q) { var isApiCall = function(url) { - return url && url.startsWith('/api') && !url.startsWith('/api/stream'); + return url && url.startsWith('./api') && !url.startsWith('./api/stream'); }; return { diff --git a/ui/app/scripts/controllers/AboutCtrl.js b/ui/app/scripts/controllers/AboutCtrl.js index 7d8b95dcc2..9d821ca916 100644 --- a/ui/app/scripts/controllers/AboutCtrl.js +++ b/ui/app/scripts/controllers/AboutCtrl.js @@ -5,7 +5,7 @@ 'use strict'; angular.module('theHiveControllers').controller('AboutCtrl', - function($rootScope, $scope, $modalInstance, VersionSrv, AlertSrv) { + function($rootScope, $scope, $uibModalInstance, VersionSrv, AlertSrv) { VersionSrv.get().then(function(response) { $scope.version = response.versions; }, function(data, status) { @@ -13,7 +13,7 @@ }); $scope.close = function() { - $modalInstance.close(); + $uibModalInstance.close(); }; } ); diff --git a/ui/app/scripts/controllers/AuthenticationCtrl.js b/ui/app/scripts/controllers/AuthenticationCtrl.js index 9942847d49..802f70658e 100644 --- a/ui/app/scripts/controllers/AuthenticationCtrl.js +++ b/ui/app/scripts/controllers/AuthenticationCtrl.js @@ -4,10 +4,10 @@ (function() { 'use strict'; angular.module('theHiveControllers') - .controller('AuthenticationCtrl', function($scope, $state, $modalStack, AuthenticationSrv, AlertSrv) { + .controller('AuthenticationCtrl', function($scope, $state, $uibModalStack, AuthenticationSrv, AlertSrv) { $scope.params = {}; - $modalStack.dismissAll(); + $uibModalStack.dismissAll(); $scope.login = function() { $scope.params.username = angular.lowercase($scope.params.username); diff --git a/ui/app/scripts/controllers/MainPageCtrl.js b/ui/app/scripts/controllers/MainPageCtrl.js index 53faeb4c52..dfcf36d249 100644 --- a/ui/app/scripts/controllers/MainPageCtrl.js +++ b/ui/app/scripts/controllers/MainPageCtrl.js @@ -12,54 +12,28 @@ $rootScope.title = 'My tasks'; $scope.view.data = 'mytasks'; $scope.list = PSearchSrv(undefined, 'case_task', { - 'baseFilter': { + scope: $scope, + baseFilter: { '_and': [{ 'status': 'InProgress' }, { 'owner': $scope.currentUser.id }] }, - 'sort': ['-flag', '-startDate'], - 'nparent': 1 + sort: ['-flag', '-startDate'], + nparent: 1 }); } else if ($stateParams.viewId === 'waitingtasks') { $rootScope.title = 'Waiting tasks'; $scope.view.data = 'waitingtasks'; $scope.list = PSearchSrv(undefined, 'case_task', { - 'baseFilter': { + scope: $scope, + baseFilter: { 'status': 'Waiting' }, - 'sort': '-startDate', - 'nparent': 1 - }); - } else if ($stateParams.viewId === 'closedcases') { - $rootScope.title = 'Closed cases'; - $scope.view.data = 'closedcases'; - $scope.list = PSearchSrv(undefined, 'case', { - 'baseFilter': { - '_and': [{ - 'status': 'Resolved' - }, { - '_between': { - '_field': 'endDate', - '_from': 'now-14d', - '_to': 'now' - } - }] - }, - 'sort': '-startDate', - 'nstats': true - }); - } else { - $rootScope.title = 'Current cases'; - $scope.view.data = 'currentcases'; - $scope.list = PSearchSrv(undefined, 'case', { - 'baseFilter': { - 'status': 'Open' - }, - 'sort': ['-flag', '-startDate'], - 'nstats': true + sort: '-startDate', + nparent: 1 }); } diff --git a/ui/app/scripts/controllers/MigrationCtrl.js b/ui/app/scripts/controllers/MigrationCtrl.js index 8f6e17b81d..ff1fe4c2e5 100644 --- a/ui/app/scripts/controllers/MigrationCtrl.js +++ b/ui/app/scripts/controllers/MigrationCtrl.js @@ -9,35 +9,41 @@ $scope.newUser = {}; StreamSrv.init(); - StreamSrv.listen('any', 'migration', function(events) { - angular.forEach(events, function(event) { - var tableName = event.base.tableName; - if (tableName === 'end') { - // check if there is at least one user registered - var users = UserSrv.query(function() { - if (users.length === 0) { - $scope.showUserForm = true; - } else { + StreamSrv.addListener({ + scope: $scope, + rootId: 'any', + objectType: 'migration', + callback: function(events) { + angular.forEach(events, function(event) { + var tableName = event.base.tableName; + + if (tableName === 'end') { + // check if there is at least one user registered + var users = UserSrv.query(function() { + if (users.length === 0) { + $scope.showUserForm = true; + } else { + $state.go('app.cases'); + } + }, function() { $state.go('app.cases'); - } - }, function() { - $state.go('app.cases'); - }); - } - var current = 0; - if (angular.isDefined($scope.migrationStatus[tableName])) { - current = $scope.migrationStatus[tableName].current; - } - if (event.base.current > current) { - $scope.migrationStatus[tableName] = event.base; - } - }); + }); + } + var current = 0; + if (angular.isDefined($scope.migrationStatus[tableName])) { + current = $scope.migrationStatus[tableName].current; + } + if (event.base.current > current) { + $scope.migrationStatus[tableName] = event.base; + } + }); + } }); $scope.migrate = function() { $scope.migrating = true; - $http.post('/api/maintenance/migrate', {}, { + $http.post('./api/maintenance/migrate', {}, { timeout: 10 * 60 * 60 * 1000 // 10 minutes }).success(function() { console.log('Migration started'); diff --git a/ui/app/scripts/controllers/RootCtrl.js b/ui/app/scripts/controllers/RootCtrl.js index 5c8020eb2d..0944410ee1 100644 --- a/ui/app/scripts/controllers/RootCtrl.js +++ b/ui/app/scripts/controllers/RootCtrl.js @@ -2,7 +2,7 @@ * Controller for main page */ angular.module('theHiveControllers').controller('RootCtrl', - function($scope, $modal, $location, $state, $base64, AuthenticationSrv, MispSrv, StreamSrv, StreamStatSrv, TemplateSrv, MetricsCacheSrv, AlertSrv) { + function($scope, $uibModal, $location, $state, $base64, AuthenticationSrv, MispSrv, StreamSrv, StreamStatSrv, TemplateSrv, MetricsCacheSrv, AlertSrv) { 'use strict'; $scope.querystring = ''; @@ -18,6 +18,7 @@ angular.module('theHiveControllers').controller('RootCtrl', $scope.templates = TemplateSrv.query(); $scope.myCurrentTasks = StreamStatSrv({ + scope: $scope, rootId: 'any', query: { '_and': [{ @@ -32,6 +33,7 @@ angular.module('theHiveControllers').controller('RootCtrl', }); $scope.waitingTasks = StreamStatSrv({ + scope: $scope, rootId: 'any', query: { 'status': 'Waiting' @@ -47,7 +49,7 @@ angular.module('theHiveControllers').controller('RootCtrl', }); // Get MISP counts - $scope.mispEvents = MispSrv.stats(); + $scope.mispEvents = MispSrv.stats($scope); }, function(data, status) { AlertSrv.error('RootCtrl', data, status); }); @@ -64,7 +66,7 @@ angular.module('theHiveControllers').controller('RootCtrl', }); $scope.$on('misp:event-imported', function() { - $scope.mispEvents = MispSrv.stats(); + $scope.mispEvents = MispSrv.stats($scope); }); $scope.$on('misp:status-updated', function(event, enabled) { @@ -93,7 +95,7 @@ angular.module('theHiveControllers').controller('RootCtrl', }; $scope.createNewCase = function(template) { - $modal.open({ + $uibModal.open({ templateUrl: 'views/partials/case/case.creation.html', controller: 'CaseCreationCtrl', size: 'lg', @@ -104,7 +106,7 @@ angular.module('theHiveControllers').controller('RootCtrl', }; $scope.aboutTheHive = function() { - $modal.open({ + $uibModal.open({ templateUrl: 'views/partials/about.html', controller: 'AboutCtrl', size: '' diff --git a/ui/app/scripts/controllers/admin/AdminCaseTemplatesCtrl.js b/ui/app/scripts/controllers/admin/AdminCaseTemplatesCtrl.js index 769971d528..f3f256d842 100644 --- a/ui/app/scripts/controllers/admin/AdminCaseTemplatesCtrl.js +++ b/ui/app/scripts/controllers/admin/AdminCaseTemplatesCtrl.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveControllers').controller('AdminCaseTemplatesCtrl', - function($scope, $modal, TemplateSrv, AlertSrv, UtilsSrv, ListSrv, MetricsCacheSrv) { + function($scope, $uibModal, TemplateSrv, AlertSrv, UtilsSrv, ListSrv, MetricsCacheSrv) { $scope.task = ''; $scope.tags = []; $scope.templates = []; @@ -74,7 +74,7 @@ }; $scope.openTaskDialog = function(task, action) { - $modal.open({ + $uibModal.open({ scope: $scope, templateUrl: 'views/partials/admin/case-templates.task.html', controller: 'AdminCaseTemplateTasksCtrl', @@ -106,7 +106,7 @@ }; $scope.deleteTemplate = function() { - $modal.open({ + $uibModal.open({ scope: $scope, templateUrl: 'views/partials/admin/case-templates.delete.html', controller: 'AdminCaseTemplateDeleteCtrl', @@ -152,12 +152,12 @@ }; }) - .controller('AdminCaseTemplateTasksCtrl', function($scope, $modalInstance, action, task) { + .controller('AdminCaseTemplateTasksCtrl', function($scope, $uibModalInstance, action, task) { $scope.task = task || {}; $scope.action = action; $scope.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; $scope.addTask = function() { @@ -165,12 +165,12 @@ $scope.template.tasks.push(task); } - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; }) - .controller('AdminCaseTemplateDeleteCtrl', function($scope, $modalInstance, TemplateSrv) { + .controller('AdminCaseTemplateDeleteCtrl', function($scope, $uibModalInstance, TemplateSrv) { $scope.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; $scope.confirm = function() { @@ -181,7 +181,7 @@ $scope.$emit('templates:refresh'); - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }); }; }); diff --git a/ui/app/scripts/controllers/admin/AdminReportTemplatesCtrl.js b/ui/app/scripts/controllers/admin/AdminReportTemplatesCtrl.js index 4dfb1eefe7..2a81537514 100644 --- a/ui/app/scripts/controllers/admin/AdminReportTemplatesCtrl.js +++ b/ui/app/scripts/controllers/admin/AdminReportTemplatesCtrl.js @@ -8,7 +8,7 @@ .controller('AdminReportTemplateDeleteCtrl', AdminReportTemplateDeleteCtrl); - function AdminReportTemplatesCtrl($q, $modal, AnalyzerSrv, ReportTemplateSrv) { + function AdminReportTemplatesCtrl($q, $uibModal, AnalyzerSrv, ReportTemplateSrv) { var self = this; this.templates = []; @@ -24,10 +24,19 @@ self.templates = response[0].data; self.analyzers = response[1]; + var cleared = _.mapObject(self.analyzers, function(val) { + delete val.shortReport; + delete val.longReport; + + return val; + }); + + self.analyzers = cleared; + return $q.resolve(self.analyzers); }).then(function (analyzersMap) { if(_.isEmpty(analyzersMap)) { - _.each(_.pluck(self.templates, 'analyzers'), function(item) { + _.each(_.pluck(self.templates, 'analyzerId'), function(item) { analyzersMap[item] = { id: item }; @@ -37,7 +46,7 @@ _.each(self.templates, function (tpl) { if(analyzersMap[tpl.analyzerId]) { analyzersMap[tpl.analyzerId][tpl.reportType + 'Report'] = tpl; - } + } }); self.analyzerCount = _.keys(analyzersMap).length; @@ -45,7 +54,7 @@ }; this.showTemplate = function (reportTemplate, analyzer) { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ //scope: $scope, templateUrl: 'views/partials/admin/report-template-dialog.html', controller: 'AdminReportTemplateDialogCtrl', @@ -67,7 +76,7 @@ }; this.deleteTemplate = function(template) { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ templateUrl: 'views/partials/admin/report-template-delete.html', controller: 'AdminReportTemplateDeleteCtrl', controllerAs: 'vm', @@ -85,7 +94,7 @@ }; this.import = function () { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ animation: true, templateUrl: 'views/partials/admin/report-template-import.html', controller: 'AdminReportTemplateImportCtrl', @@ -101,7 +110,7 @@ this.load(); } - function AdminReportTemplateDialogCtrl($modalInstance, reportTemplate, ReportTemplateSrv, AlertSrv, analyzer) { + function AdminReportTemplateDialogCtrl($uibModalInstance, reportTemplate, ReportTemplateSrv, AlertSrv, analyzer) { this.reportTemplate = reportTemplate; this.analyzer = analyzer; this.reportTypes = ['short', 'long']; @@ -116,49 +125,49 @@ this.formData.analyzerId = this.analyzer.id; this.cancel = function () { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; this.saveTemplate = function() { ReportTemplateSrv.save(this.formData) .then(function() { - $modalInstance.close(); + $uibModalInstance.close(); }, function(response) { AlertSrv.error('AdminReportTemplateDialogCtrl', response.data, response.status); }); }; } - function AdminReportTemplateDeleteCtrl($modalInstance, ReportTemplateSrv, AlertSrv, template) { + function AdminReportTemplateDeleteCtrl($uibModalInstance, ReportTemplateSrv, AlertSrv, template) { this.template = template; this.ok = function () { ReportTemplateSrv.delete(template.id) .then(function() { - $modalInstance.close(); + $uibModalInstance.close(); }, function(response) { AlertSrv.error('AdminReportTemplateDeleteCtrl', response.data, response.status); }); }; this.cancel = function () { - $modalInstance.dismiss('cancel'); + $uibModalInstance.dismiss('cancel'); }; } - function AdminReportTemplateImportCtrl($modalInstance, ReportTemplateSrv, AlertSrv) { + function AdminReportTemplateImportCtrl($uibModalInstance, ReportTemplateSrv, AlertSrv) { this.formData = {}; this.ok = function () { ReportTemplateSrv.import(this.formData) .then(function() { - $modalInstance.close(); + $uibModalInstance.close(); }, function(response) { AlertSrv.error('AdminReportTemplateImportCtrl', response.data, response.status); }); }; this.cancel = function () { - $modalInstance.dismiss('cancel'); + $uibModalInstance.dismiss('cancel'); }; } })(); diff --git a/ui/app/scripts/controllers/admin/AdminUsersCtrl.js b/ui/app/scripts/controllers/admin/AdminUsersCtrl.js index 070bde3b62..9db695ea3f 100644 --- a/ui/app/scripts/controllers/admin/AdminUsersCtrl.js +++ b/ui/app/scripts/controllers/admin/AdminUsersCtrl.js @@ -13,7 +13,7 @@ * users management page */ $scope.userlist = PSearchSrv(undefined, 'user', { - //'filter': {} + scope: $scope }); $scope.initNewUser = function() { $scope.apiKey = false; diff --git a/ui/app/scripts/controllers/case/CaseCloseModalCtrl.js b/ui/app/scripts/controllers/case/CaseCloseModalCtrl.js index 2ab56884f8..313bff4b6d 100644 --- a/ui/app/scripts/controllers/case/CaseCloseModalCtrl.js +++ b/ui/app/scripts/controllers/case/CaseCloseModalCtrl.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveControllers').controller('CaseCloseModalCtrl', - function($scope, $modalInstance, SearchSrv, MetricsCacheSrv, AlertSrv) { + function($scope, $uibModalInstance, SearchSrv, MetricsCacheSrv, AlertSrv) { $scope.tasksValid = false; $scope.tasks = []; @@ -71,12 +71,12 @@ AlertSrv.log('The case #' + caze.caseId + ' has been closed', 'success'); - $modalInstance.close(); + $uibModalInstance.close(); }); }; $scope.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; } ); diff --git a/ui/app/scripts/controllers/case/CaseCreationCtrl.js b/ui/app/scripts/controllers/case/CaseCreationCtrl.js index c3691013ba..770adb08b5 100644 --- a/ui/app/scripts/controllers/case/CaseCreationCtrl.js +++ b/ui/app/scripts/controllers/case/CaseCreationCtrl.js @@ -4,7 +4,7 @@ (function () { 'use strict'; angular.module('theHiveControllers').controller('CaseCreationCtrl', - function ($rootScope, $scope, $state, $modalInstance, CaseSrv, AlertSrv, MetricsCacheSrv, template) { + function ($rootScope, $scope, $state, $uibModalInstance, CaseSrv, AlertSrv, MetricsCacheSrv, template) { $rootScope.title = 'New case'; $scope.activeTlp = 'active'; @@ -98,7 +98,7 @@ $state.go('app.case.details', { caseId: data.id }); - $modalInstance.close(); + $uibModalInstance.close(); }, function (response) { $scope.pendingAsync = false; AlertSrv.error('CaseCreationCtrl', response.data, response.status); @@ -118,7 +118,7 @@ }; $scope.cancel = function () { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; } ); diff --git a/ui/app/scripts/controllers/case/CaseDetailsCtrl.js b/ui/app/scripts/controllers/case/CaseDetailsCtrl.js index 36d2ce314a..55e5b06e69 100644 --- a/ui/app/scripts/controllers/case/CaseDetailsCtrl.js +++ b/ui/app/scripts/controllers/case/CaseDetailsCtrl.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveControllers').controller('CaseDetailsCtrl', - function($scope, $state, $modal, CaseTabsSrv, UserInfoSrv, PSearchSrv) { + function($scope, $state, $uibModal, CaseTabsSrv, UserInfoSrv, PSearchSrv) { CaseTabsSrv.activateTab($state.current.data.tab); @@ -13,7 +13,8 @@ }; $scope.attachments = PSearchSrv($scope.caseId, 'case_task_log', { - 'filter': { + scope: $scope, + filter: { '_and': [{ '_not': { 'status': 'Deleted' @@ -34,8 +35,8 @@ } }] }, - 'pageSize': 100, - 'nparent': 1 + pageSize: 100, + nparent: 1 }); $scope.hasNoMetrics = function(caze) { @@ -43,7 +44,7 @@ }; $scope.addMetric = function(metric) { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ scope: $scope, templateUrl: 'views/partials/case/case.add.metric.html', controller: 'CaseAddMetricConfirmCtrl', @@ -74,15 +75,15 @@ } ); - angular.module('theHiveControllers').controller('CaseAddMetricConfirmCtrl', function($scope, $modalInstance, metric) { + angular.module('theHiveControllers').controller('CaseAddMetricConfirmCtrl', function($scope, $uibModalInstance, metric) { $scope.metric = metric; $scope.cancel = function() { - $modalInstance.dismiss(metric); + $uibModalInstance.dismiss(metric); }; $scope.confirm = function() { - $modalInstance.close(metric); + $uibModalInstance.close(metric); }; }); diff --git a/ui/app/scripts/controllers/case/CaseLinksCtrl.js b/ui/app/scripts/controllers/case/CaseLinksCtrl.js index 10d4c912c6..65c27c5382 100644 --- a/ui/app/scripts/controllers/case/CaseLinksCtrl.js +++ b/ui/app/scripts/controllers/case/CaseLinksCtrl.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveControllers').controller('CaseLinksCtrl', - function($scope, $state, $stateParams, $modal, CaseTabsSrv) { + function($scope, $state, $stateParams, $uibModal, $timeout, CaseTabsSrv) { $scope.caseId = $stateParams.caseId; var tabName = 'links-' + $scope.caseId; @@ -16,7 +16,9 @@ }); // Select tab - CaseTabsSrv.activateTab(tabName); + $timeout(function() { + CaseTabsSrv.activateTab(tabName); + }, 0); } ); })(); diff --git a/ui/app/scripts/controllers/case/CaseListCtrl.js b/ui/app/scripts/controllers/case/CaseListCtrl.js index a98bc152ce..8d4aa2f020 100644 --- a/ui/app/scripts/controllers/case/CaseListCtrl.js +++ b/ui/app/scripts/controllers/case/CaseListCtrl.js @@ -3,7 +3,7 @@ angular.module('theHiveControllers') .controller('CaseListCtrl', CaseListCtrl); - function CaseListCtrl($scope, $q, CasesUISrv, StreamStatSrv, PSearchSrv, EntitySrv, UserInfoSrv, TagSrv, UserSrv, AuthenticationSrv, CaseResolutionStatus) { + function CaseListCtrl($scope, $q, $state, $window, CasesUISrv, StreamStatSrv, PSearchSrv, EntitySrv, UserInfoSrv, TagSrv, UserSrv, AuthenticationSrv, CaseResolutionStatus) { var self = this; this.showFlow = true; @@ -18,6 +18,7 @@ }; this.list = PSearchSrv(undefined, 'case', { + scope: $scope, filter: self.searchForm.searchQuery !== '' ? { _string: self.searchForm.searchQuery } : '', @@ -28,6 +29,7 @@ }); this.caseStats = StreamStatSrv({ + scope: $scope, rootId: 'any', query: {}, result: {}, @@ -186,5 +188,10 @@ this.uiSrv.setSort(sort); }; + this.live = function() { + $window.open($state.href('live'), 'TheHiveLive', + 'width=500,height=700,menubar=no,status=no,toolbar=no,location=no,scrollbars=yes'); + }; + } })(); diff --git a/ui/app/scripts/controllers/case/CaseMainCtrl.js b/ui/app/scripts/controllers/case/CaseMainCtrl.js index 55260cc704..6d499fd39c 100644 --- a/ui/app/scripts/controllers/case/CaseMainCtrl.js +++ b/ui/app/scripts/controllers/case/CaseMainCtrl.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveControllers').controller('CaseMainCtrl', - function($scope, $rootScope, $state, $stateParams, $q, $modal, CaseTabsSrv, CaseSrv, MetricsCacheSrv, UserInfoSrv, StreamStatSrv, AlertSrv, UtilsSrv, CaseResolutionStatus, CaseImpactStatus, caze) { + function($scope, $rootScope, $state, $stateParams, $q, $uibModal, CaseTabsSrv, CaseSrv, MetricsCacheSrv, UserInfoSrv, StreamStatSrv, AlertSrv, UtilsSrv, CaseResolutionStatus, CaseImpactStatus, caze) { $scope.CaseResolutionStatus = CaseResolutionStatus; $scope.CaseImpactStatus = CaseImpactStatus; @@ -15,6 +15,7 @@ CaseTabsSrv.initTabs(); } + $scope.tabSrv = CaseTabsSrv; $scope.tabs = CaseTabsSrv.getTabs(); $scope.getUserInfo = UserInfoSrv; $scope.caseId = caseId; @@ -57,6 +58,7 @@ }); $scope.tasks = StreamStatSrv({ + scope: $scope, rootId: caseId, query: { '_and': [{ @@ -78,6 +80,7 @@ }); $scope.artifactStats = StreamStatSrv({ + scope: $scope, rootId: caseId, query: { '_and': [{ @@ -160,7 +163,7 @@ }; $scope.openCloseDialog = function() { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ scope: $scope, templateUrl: 'views/partials/case/case.close.html', controller: 'CaseCloseModalCtrl', @@ -173,7 +176,7 @@ }; $scope.reopenCase = function() { - $modal.open({ + $uibModal.open({ scope: $scope, templateUrl: 'views/partials/case/case.reopen.html', controller: 'CaseReopenModalCtrl', @@ -182,7 +185,7 @@ }; $scope.mergeCase = function() { - $modal.open({ + $uibModal.open({ templateUrl: 'views/partials/case/case.merge.html', controller: 'CaseMergeModalCtrl', controllerAs: 'dialog', diff --git a/ui/app/scripts/controllers/case/CaseMergeModalCtrl.js b/ui/app/scripts/controllers/case/CaseMergeModalCtrl.js index e19b3585e6..1f8c7806f1 100644 --- a/ui/app/scripts/controllers/case/CaseMergeModalCtrl.js +++ b/ui/app/scripts/controllers/case/CaseMergeModalCtrl.js @@ -4,7 +4,7 @@ angular.module('theHiveControllers') .controller('CaseMergeModalCtrl', CaseMergeModalCtrl); - function CaseMergeModalCtrl($state, $modalInstance, $q, SearchSrv, CaseSrv, UserInfoSrv, AlertSrv, caze, $http) { + function CaseMergeModalCtrl($state, $uibModalInstance, $q, SearchSrv, CaseSrv, UserInfoSrv, AlertSrv, caze, $http) { var me = this; this.caze = caze; @@ -70,7 +70,7 @@ caseId: merged.id }); - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); AlertSrv.log('The cases have been successfully merged into a new case #' + merged.caseId, 'success'); }, function (response) { @@ -80,7 +80,7 @@ }; this.cancel = function () { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; } })(); diff --git a/ui/app/scripts/controllers/case/CaseObservablesCtrl.js b/ui/app/scripts/controllers/case/CaseObservablesCtrl.js index f9ae34e74e..67d309c211 100644 --- a/ui/app/scripts/controllers/case/CaseObservablesCtrl.js +++ b/ui/app/scripts/controllers/case/CaseObservablesCtrl.js @@ -1,7 +1,7 @@ (function () { 'use strict'; angular.module('theHiveControllers').controller('CaseObservablesCtrl', - function ($scope, $q, $state, $stateParams, $modal, CaseTabsSrv, PSearchSrv, CaseArtifactSrv, AlertSrv, AnalyzerSrv, CortexSrv, ObservablesUISrv, VersionSrv) { + function ($scope, $q, $state, $stateParams, $uibModal, CaseTabsSrv, PSearchSrv, CaseArtifactSrv, AlertSrv, AnalyzerSrv, CortexSrv, ObservablesUISrv, VersionSrv) { CaseTabsSrv.activateTab($state.current.data.tab); @@ -17,7 +17,8 @@ $scope.selection = {}; $scope.artifacts = PSearchSrv($scope.caseId, 'case_artifact', { - 'baseFilter': { + scope: $scope, + baseFilter: { '_and': [{ '_parent': { "_type": "case", @@ -29,16 +30,16 @@ 'status': 'Ok' }] }, - 'filter': $scope.searchForm.searchQuery !== '' ? { + filter: $scope.searchForm.searchQuery !== '' ? { _string: $scope.searchForm.searchQuery } : '', - 'loadAll': true, - 'sort': '-startDate', - 'pageSize': $scope.uiSrv.context.pageSize, - 'onUpdate': function () { + loadAll: true, + sort: '-startDate', + pageSize: $scope.uiSrv.context.pageSize, + onUpdate: function () { $scope.updateSelection(); }, - 'nstats': true + nstats: true }); $scope.$watchCollection('artifacts.pageSize', function (newValue) { @@ -290,7 +291,7 @@ // actions on artifacts $scope.addArtifact = function () { - $modal.open({ + $uibModal.open({ animation: 'true', templateUrl: 'views/partials/observables/observable.creation.html', controller: 'ObservableCreationCtrl', diff --git a/ui/app/scripts/controllers/case/CaseObservablesItemCtrl.js b/ui/app/scripts/controllers/case/CaseObservablesItemCtrl.js index ce604f5dd5..546fd140bd 100644 --- a/ui/app/scripts/controllers/case/CaseObservablesItemCtrl.js +++ b/ui/app/scripts/controllers/case/CaseObservablesItemCtrl.js @@ -1,7 +1,7 @@ (function () { 'use strict'; angular.module('theHiveControllers').controller('CaseObservablesItemCtrl', - function ($scope, $state, $stateParams, $q, CaseTabsSrv, CaseArtifactSrv, CortexSrv, PSearchSrv, AnalyzerSrv, JobSrv, AlertSrv, VersionSrv) { + function ($scope, $state, $stateParams, $q, $timeout, CaseTabsSrv, CaseArtifactSrv, CortexSrv, PSearchSrv, AnalyzerSrv, AlertSrv, VersionSrv, appConfig) { var observableId = $stateParams.itemId, observableName = 'observable-' + observableId; @@ -20,6 +20,7 @@ $scope.artifact = {}; $scope.artifact.tlp = $scope.artifact.tlp || -1; $scope.analysisEnabled = VersionSrv.hasCortex(); + $scope.protectDownloadsWith = appConfig.config.protectDownloadsWith; $scope.editorOptions = { lineNumbers: true, @@ -45,7 +46,10 @@ }); // Select tab - CaseTabsSrv.activateTab(observableName); + $timeout(function() { + CaseTabsSrv.activateTab(observableName); + }, 0); + // Prepare the scope data $scope.initScope(observable); @@ -66,12 +70,12 @@ $scope.analyzers = []; }) .finally(function () { - $scope.jobs = CortexSrv.list($scope.caseId, observableId, $scope.onJobsChange); + $scope.jobs = CortexSrv.list($scope, $scope.caseId, observableId, $scope.onJobsChange); }); }; - $scope.onJobsChange = function () { + $scope.onJobsChange = function (updates) { $scope.analyzerJobs = {}; angular.forEach($scope.analyzers, function (analyzer, analyzerId) { @@ -95,16 +99,43 @@ */ } }); + + // Check it a job completed successfully and update the observableId + if(updates && updates.length > 0) { + + var statuses = _.pluck(_.map(updates, function(item) { + return item.base.details; + }), 'status'); + + console.log(statuses); + if(statuses.indexOf('Success') > -1) { + CaseArtifactSrv.api().get({ + 'artifactId': observableId + }, function (observable) { + $scope.artifact = observable; + }, function (response) { + AlertSrv.error('artifactDetails', response.data, response.status); + CaseTabsSrv.activateTab('observables'); + }); + } + } }; - $scope.showReport = function (job) { - $scope.report = { - template: job.analyzerId, - content: job.report, - status: job.status, - startDate: job.startDate, - endDate: job.endDate - }; + $scope.showReport = function (jobId) { + $scope.report = {}; + + CortexSrv.getJob(jobId).then(function(response) { + var job = response.data; + $scope.report = { + template: job.analyzerId, + content: job.report, + status: job.status, + startDate: job.startDate, + endDate: job.endDate + }; + }, function(/*err*/) { + AlertSrv.log('An expected error occured while fetching the job report'); + }); }; $scope.similarArtifacts = CaseArtifactSrv.api().similar({ @@ -135,7 +166,7 @@ return CaseArtifactSrv.api().update({ artifactId: $scope.artifact.id - }, field, function (response) { + }, field, function (response) { $scope.artifact = response.toJSON(); }, function (response) { AlertSrv.error('artifactDetails', response.data, response.status); diff --git a/ui/app/scripts/controllers/case/CaseReopenModalCtrl.js b/ui/app/scripts/controllers/case/CaseReopenModalCtrl.js index 3a1b493fd4..58d30b84c5 100644 --- a/ui/app/scripts/controllers/case/CaseReopenModalCtrl.js +++ b/ui/app/scripts/controllers/case/CaseReopenModalCtrl.js @@ -2,10 +2,10 @@ 'use strict'; angular.module('theHiveControllers') - .controller('CaseReopenModalCtrl', function($scope, $modalInstance, AlertSrv) { + .controller('CaseReopenModalCtrl', function($scope, $uibModalInstance, AlertSrv) { $scope.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; $scope.confirm = function() { @@ -15,7 +15,7 @@ AlertSrv.log('The case #' + caze.caseId + ' has been reopened', 'success'); }); - $modalInstance.close(); + $uibModalInstance.close(); }; }); })(); diff --git a/ui/app/scripts/controllers/case/CaseStatsCtrl.js b/ui/app/scripts/controllers/case/CaseStatsCtrl.js index d23899f021..a3e1be5968 100644 --- a/ui/app/scripts/controllers/case/CaseStatsCtrl.js +++ b/ui/app/scripts/controllers/case/CaseStatsCtrl.js @@ -5,7 +5,7 @@ 'use strict'; angular.module('theHiveControllers').controller('CaseStatsCtrl', - function($rootScope, $stateParams, $timeout, StatSrv, StreamStatSrv, CasesUISrv) { + function($rootScope, $scope, $stateParams, $timeout, StatSrv, StreamStatSrv, CasesUISrv) { var self = this; this.uiSrv = CasesUISrv; @@ -16,6 +16,7 @@ // Get stats by tags StreamStatSrv({ + scope: $scope, rootId: 'any', query: {}, objectType: 'case', @@ -30,6 +31,7 @@ // Get stats by type StreamStatSrv({ + scope: $scope, rootId: 'any', query: {}, objectType: 'case', @@ -42,6 +44,7 @@ // Get stats by ioc StreamStatSrv({ + scope: $scope, rootId: 'any', query: {}, objectType: 'case', diff --git a/ui/app/scripts/controllers/case/CaseTasksCtrl.js b/ui/app/scripts/controllers/case/CaseTasksCtrl.js index 8dab80be60..e4bb3e8909 100644 --- a/ui/app/scripts/controllers/case/CaseTasksCtrl.js +++ b/ui/app/scripts/controllers/case/CaseTasksCtrl.js @@ -4,7 +4,7 @@ .controller('CaseTaskDeleteCtrl', CaseTaskDeleteCtrl) .controller('CaseTasksCtrl', CaseTasksCtrl); - function CaseTasksCtrl($scope, $state, $stateParams, $modal, CaseTabsSrv, PSearchSrv, CaseTaskSrv, UserInfoSrv, AlertSrv) { + function CaseTasksCtrl($scope, $state, $stateParams, $uibModal, CaseTabsSrv, PSearchSrv, CaseTaskSrv, UserInfoSrv, AlertSrv) { CaseTabsSrv.activateTab($state.current.data.tab); @@ -17,7 +17,8 @@ }; $scope.tasks = PSearchSrv($scope.caseId, 'case_task', { - 'baseFilter': { + scope: $scope, + baseFilter: { '_and': [{ '_parent': { '_type': 'case', @@ -31,7 +32,7 @@ } }] }, - 'sort': ['-flag', '+startDate', '+title'] + sort: ['-flag', '+startDate', '+title'] }); $scope.showTask = function(task) { @@ -54,7 +55,7 @@ $scope.removeTask = function(task) { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ animation: true, templateUrl: 'views/partials/case/case.task.delete.html', controller: 'CaseTaskDeleteCtrl', @@ -99,15 +100,15 @@ } - function CaseTaskDeleteCtrl($modalInstance, title) { + function CaseTaskDeleteCtrl($uibModalInstance, title) { this.title = title; this.ok = function() { - $modalInstance.close(); + $uibModalInstance.close(); }; this.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; } }()); diff --git a/ui/app/scripts/controllers/case/CaseTasksItemCtrl.js b/ui/app/scripts/controllers/case/CaseTasksItemCtrl.js index 5d8053affc..f6c454f544 100644 --- a/ui/app/scripts/controllers/case/CaseTasksItemCtrl.js +++ b/ui/app/scripts/controllers/case/CaseTasksItemCtrl.js @@ -1,7 +1,7 @@ (function () { 'use strict'; angular.module('theHiveControllers').controller('CaseTasksItemCtrl', - function ($scope, $rootScope, $state, $stateParams, CaseTabsSrv, CaseTaskSrv, PSearchSrv, TaskLogSrv, AlertSrv, task) { + function ($scope, $rootScope, $state, $stateParams, $timeout, CaseTabsSrv, CaseTaskSrv, PSearchSrv, TaskLogSrv, AlertSrv, task) { var caseId = $stateParams.caseId, taskId = $stateParams.itemId; @@ -30,6 +30,7 @@ $scope.initScope = function () { $scope.logs = PSearchSrv(caseId, 'case_task_log', { + scope: $scope, 'filter': { '_and': [{ '_parent': { @@ -129,7 +130,10 @@ }); // Select tab - CaseTabsSrv.activateTab($scope.tabName); + $timeout(function() { + CaseTabsSrv.activateTab($scope.tabName); + }, 0); + // Prepare the scope data $scope.initScope(task); diff --git a/ui/app/scripts/controllers/case/ObservableCreationCtrl.js b/ui/app/scripts/controllers/case/ObservableCreationCtrl.js index 48a3c028e6..ca23f398c0 100644 --- a/ui/app/scripts/controllers/case/ObservableCreationCtrl.js +++ b/ui/app/scripts/controllers/case/ObservableCreationCtrl.js @@ -5,7 +5,7 @@ 'use strict'; angular.module('theHiveControllers').controller('ObservableCreationCtrl', - function($scope, $stateParams, $modalInstance, clipboard, CaseArtifactSrv, ListSrv, AlertSrv) { + function($scope, $stateParams, $uibModalInstance, clipboard, CaseArtifactSrv, ListSrv, AlertSrv) { $scope.activeTlp = 'active'; $scope.pendingAsync = false; @@ -130,7 +130,7 @@ AlertSrv.log('Observables have been successfully created', 'success'); - $modalInstance.close(response); + $uibModalInstance.close(response); } }; @@ -145,7 +145,7 @@ } else { AlertSrv.error('ObservableCreationCtrl', 'An unexpected error occurred while creating the observables', response.status); - $modalInstance.close(response); + $uibModalInstance.close(response); } }; @@ -157,7 +157,7 @@ }; $scope.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; $scope.isFile = function() { diff --git a/ui/app/scripts/controllers/case/ObservablesStatsCtrl.js b/ui/app/scripts/controllers/case/ObservablesStatsCtrl.js index 871399a082..e13fb87c7f 100644 --- a/ui/app/scripts/controllers/case/ObservablesStatsCtrl.js +++ b/ui/app/scripts/controllers/case/ObservablesStatsCtrl.js @@ -5,7 +5,7 @@ 'use strict'; angular.module('theHiveControllers').controller('ObservablesStatsCtrl', - function($rootScope, $stateParams, $timeout, StatSrv, StreamStatSrv, ObservablesUISrv) { + function($rootScope, $scope, $stateParams, $timeout, StatSrv, StreamStatSrv, ObservablesUISrv) { var self = this; this.uiSrv = ObservablesUISrv; @@ -29,6 +29,7 @@ // Get stats by tags StreamStatSrv({ + scope: $scope, rootId: $stateParams.caseId, query: defaultQuery, objectType: 'case_artifact', @@ -43,6 +44,7 @@ // Get stats by type StreamStatSrv({ + scope: $scope, rootId: $stateParams.caseId, query: defaultQuery, objectType: 'case_artifact', @@ -55,6 +57,7 @@ // Get stats by ioc StreamStatSrv({ + scope: $scope, rootId: $stateParams.caseId, query: defaultQuery, objectType: 'case_artifact', @@ -87,63 +90,6 @@ this.filterBy = function(field, value) { this.uiSrv.addFilter(field, value); }; - - /* - $scope.observableByType = { - title: 'Observables by Type', - type: 'case_artifact', - field: 'dataType', - dateField: 'startDate', - tagsField: 'tags' - }; - - $scope.observableByTags = { - title: 'Top 10 tags', - type: 'case_artifact', - field: 'tags', - dateField: 'startDate', - tagsField: 'tags', - limit: 10, - sort: ['-count'] - }; - - $scope.observableByIoc = { - title: 'IOCs', - type: 'case_artifact', - field: 'ioc', - dateField: 'startDate', - tagsField: 'tags', - colors: { - '0': '#5cb85c', - '1': '#d9534f' - }, - names: { - '0': 'Not IOC', - '1': 'IOC' - } - }; - - // Prepare the global query - $scope.prepareGlobalQuery = function() { - return function(options) { - return { - _and: [{ - _parent: $stateParams.caseId - }] - }; - }; - }; - - $scope.filter = function() { - $rootScope.$broadcast('refresh-charts', $scope.prepareGlobalQuery()); - }; - - $scope.filter(); - - $timeout(function() { - $scope.filter(); - }, 1000); - */ } ); })(); diff --git a/ui/app/scripts/controllers/cortex/CortexInstanceDialogCtrl.js b/ui/app/scripts/controllers/cortex/CortexInstanceDialogCtrl.js index 480ba6fd7a..860b757af1 100644 --- a/ui/app/scripts/controllers/cortex/CortexInstanceDialogCtrl.js +++ b/ui/app/scripts/controllers/cortex/CortexInstanceDialogCtrl.js @@ -3,18 +3,18 @@ angular.module('theHiveControllers') .controller('CortexInstanceDialogCtrl', CortexInstanceDialogCtrl); - function CortexInstanceDialogCtrl($modalInstance, servers) { + function CortexInstanceDialogCtrl($uibModalInstance, servers) { var self = this; this.servers = servers; this.selected = null; this.ok = function() { - $modalInstance.close(this.selected); + $uibModalInstance.close(this.selected); }; this.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; } })(); diff --git a/ui/app/scripts/controllers/misp/MispBulkImportCtrl.js b/ui/app/scripts/controllers/misp/MispBulkImportCtrl.js index c260da200d..3d468af6a9 100644 --- a/ui/app/scripts/controllers/misp/MispBulkImportCtrl.js +++ b/ui/app/scripts/controllers/misp/MispBulkImportCtrl.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveControllers') - .controller('MispBulkImportCtrl', function($rootScope, $q, $modalInstance, MispSrv, AlertSrv, events) { + .controller('MispBulkImportCtrl', function($rootScope, $q, $uibModalInstance, MispSrv, AlertSrv, events) { var self = this; self.events = events; self.disableButtons = false; @@ -20,7 +20,7 @@ $rootScope.$broadcast('misp:event-imported'); - $modalInstance.close(_.pluck(response, 'data')); + $uibModalInstance.close(_.pluck(response, 'data')); }, function(response) { self.disableButtons = false; AlertSrv.error('MispBulkImportCtrl', response.data, response.status); @@ -28,7 +28,7 @@ }; self.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; }); })(); diff --git a/ui/app/scripts/controllers/misp/MispEventCtrl.js b/ui/app/scripts/controllers/misp/MispEventCtrl.js index a698d4a5d1..c6f110952c 100644 --- a/ui/app/scripts/controllers/misp/MispEventCtrl.js +++ b/ui/app/scripts/controllers/misp/MispEventCtrl.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveControllers') - .controller('MispEventCtrl', function($rootScope, $state, $modalInstance, MispSrv, AlertSrv, event) { + .controller('MispEventCtrl', function($rootScope, $state, $uibModalInstance, MispSrv, AlertSrv, event) { var self = this; var eventId = event.id; @@ -38,14 +38,14 @@ }, function(response) { self.loading = false; AlertSrv.error('MispEventCtrl', response.data, response.status); - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }); }; self.import = function() { self.loading = true; MispSrv.create(self.event.id).then(function(response) { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); $rootScope.$broadcast('misp:event-imported'); @@ -60,7 +60,7 @@ self.ignore = function(){ MispSrv.ignore(self.event.id).then(function( /*data*/ ) { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }); }; @@ -81,7 +81,7 @@ }; self.cancel = function() { - $modalInstance.dismiss(); + $uibModalInstance.dismiss(); }; self.load(); diff --git a/ui/app/scripts/controllers/misp/MispListCtrl.js b/ui/app/scripts/controllers/misp/MispListCtrl.js index 27e05cde96..e8e522d61e 100644 --- a/ui/app/scripts/controllers/misp/MispListCtrl.js +++ b/ui/app/scripts/controllers/misp/MispListCtrl.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveControllers') - .controller('MispListCtrl', function($q, $state, $modal, MispSrv, AlertSrv) { + .controller('MispListCtrl', function($scope, $q, $state, $uibModal, MispSrv, AlertSrv) { var self = this; self.list = []; @@ -52,7 +52,7 @@ }; self.import = function(event) { - $modal.open({ + $uibModal.open({ templateUrl: 'views/partials/misp/event.dialog.html', controller: 'MispEventCtrl', controllerAs: 'dialog', @@ -64,7 +64,7 @@ }; self.bulkImport = function() { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ templateUrl: 'views/partials/misp/bulk.import.dialog.html', controller: 'MispBulkImportCtrl', controllerAs: 'dialog', @@ -120,7 +120,7 @@ }; self.load = function() { - self.list = MispSrv.list(self.resetSelection); + self.list = MispSrv.list($scope, self.resetSelection); }; self.cancel = function() { diff --git a/ui/app/scripts/directives/charts/donut-chart.js b/ui/app/scripts/directives/charts/donut-chart.js index b94d6569c9..f61888a0df 100644 --- a/ui/app/scripts/directives/charts/donut-chart.js +++ b/ui/app/scripts/directives/charts/donut-chart.js @@ -1,6 +1,6 @@ (function() { 'use strict'; - angular.module('theHiveDirectives').directive('donutChart', function(StatSrv, $state, $base64) { + angular.module('theHiveDirectives').directive('donutChart', function(StatSrv, $state, $base64, AlertSrv) { return { restrict: 'E', scope: { @@ -74,6 +74,8 @@ } }; + }, function(err) { + AlertSrv.error('donutChart', err.data, err.status); }); }; diff --git a/ui/app/scripts/directives/charts/duration-over-time-chart.js b/ui/app/scripts/directives/charts/duration-over-time-chart.js index ee531fd5f8..5d26d7fc24 100644 --- a/ui/app/scripts/directives/charts/duration-over-time-chart.js +++ b/ui/app/scripts/directives/charts/duration-over-time-chart.js @@ -1,6 +1,6 @@ (function() { 'use strict'; - angular.module('theHiveDirectives').directive('durationOverTimeChart', function($http, $interpolate, ChartSrv) { + angular.module('theHiveDirectives').directive('durationOverTimeChart', function($http, $interpolate, ChartSrv, AlertSrv) { return { restrict: 'E', scope: { @@ -33,7 +33,7 @@ var computedFieldName = 'computed.handlingDuration'; - $http.post('/api/case/_stats', { + $http.post('./api/case/_stats', { query: options.params.q, stats: [{ _agg: 'time', @@ -127,8 +127,8 @@ } }; - }, function(response) { - console.error(response); + }, function(err) { + AlertSrv.error('durationOverTimeChart', err.data, err.status); }); }; diff --git a/ui/app/scripts/directives/charts/histo-chart.js b/ui/app/scripts/directives/charts/histo-chart.js index fa737a5dfb..cf7aa536eb 100644 --- a/ui/app/scripts/directives/charts/histo-chart.js +++ b/ui/app/scripts/directives/charts/histo-chart.js @@ -1,6 +1,6 @@ (function() { 'use strict'; - angular.module('theHiveDirectives').directive('histoChart', function($http, ChartSrv) { + angular.module('theHiveDirectives').directive('histoChart', function($http, ChartSrv, AlertSrv) { return { restrict: 'E', scope: { @@ -37,7 +37,7 @@ } }; - $http.post('/api/' + options.params.entity + '/_stats', { + $http.post('./api/' + options.params.entity + '/_stats', { "query": options.params.q, "stats": [{ "_agg": "time", @@ -88,6 +88,8 @@ enabled: scope.options.zoom || false } }; + }, function(err) { + AlertSrv.error('histoChart', err.data, err.status); }); }; diff --git a/ui/app/scripts/directives/charts/metric-histo-chart.js b/ui/app/scripts/directives/charts/metric-histo-chart.js index 6567e6d06f..f835b621a0 100644 --- a/ui/app/scripts/directives/charts/metric-histo-chart.js +++ b/ui/app/scripts/directives/charts/metric-histo-chart.js @@ -1,6 +1,6 @@ (function() { 'use strict'; - angular.module('theHiveDirectives').directive('metricHistoChart', function($http, $interpolate, MetricsCacheSrv, ChartSrv) { + angular.module('theHiveDirectives').directive('metricHistoChart', function($http, $interpolate, MetricsCacheSrv, ChartSrv, AlertSrv) { return { restrict: 'E', scope: { @@ -54,7 +54,7 @@ scope.columnKeys = []; - $http.post('/api/' + options.params.entity + '/_stats', { + $http.post('./api/' + options.params.entity + '/_stats', { "query": options.params.q, "stats": [{ "_agg": "time", @@ -123,6 +123,8 @@ scope.chart = chart; + }, function(err) { + AlertSrv.error('metricHistoChart', err.data, err.status); }); }; diff --git a/ui/app/scripts/directives/entityLink.js b/ui/app/scripts/directives/entityLink.js index 7c25716c6d..35dba95b0a 100644 --- a/ui/app/scripts/directives/entityLink.js +++ b/ui/app/scripts/directives/entityLink.js @@ -26,7 +26,7 @@ } // Call the link function to link the given scope and // a Clone Attach Function, - // http://docs.angularjs.org/api/ng.$compile : + // http://docs.angularjs.org./api/ng.$compile : // "Calling the linking function returns the element of the // template. // It is either the original element passed in, diff --git a/ui/app/scripts/directives/fileChooser.js b/ui/app/scripts/directives/fileChooser.js index c9483bdb03..3f33d904c0 100644 --- a/ui/app/scripts/directives/fileChooser.js +++ b/ui/app/scripts/directives/fileChooser.js @@ -37,7 +37,6 @@ this.removeFile(file); }); if (angular.isDefined(scope.control)) { - console.log('Attach removeAllFiles function in control object'); scope.control.removeAllFiles = function() { dropzone.removeAllFiles(); }; diff --git a/ui/app/scripts/directives/flow/flow-item.js b/ui/app/scripts/directives/flow/flow-item.js index 7f9d375bc2..94c748a1ff 100644 --- a/ui/app/scripts/directives/flow/flow-item.js +++ b/ui/app/scripts/directives/flow/flow-item.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveDirectives') - .directive('flowItem', function($modal, $state, $window, UserInfoSrv) { + .directive('flowItem', function($uibModal, $state, $window, UserInfoSrv) { return { restrict: 'E', replace: true, @@ -26,8 +26,8 @@ return angular.isString(contentType) && contentType.indexOf('image') === 0; }; scope.showImage = function(attachmentId, attachmentName) { - $modal.open({ - template: '' + attachmentName + '', + $uibModal.open({ + template: '' + attachmentName + '', size: 'lg' }); }; diff --git a/ui/app/scripts/directives/flow/flow.js b/ui/app/scripts/directives/flow/flow.js index d21717dcbf..bb375777df 100644 --- a/ui/app/scripts/directives/flow/flow.js +++ b/ui/app/scripts/directives/flow/flow.js @@ -19,7 +19,7 @@ } scope.getAnalyzerInfo = AnalyzerInfoSrv; scope.getUserInfo = UserInfoSrv; - scope.values = AuditSrv(rootId, parseInt(scope.max)); + scope.values = AuditSrv(rootId, parseInt(scope.max), scope); if ($window.opener) { scope.targetWindow = $window.opener; diff --git a/ui/app/scripts/directives/logEntry.js b/ui/app/scripts/directives/logEntry.js index 7da40337ab..2bfb3ef8a0 100644 --- a/ui/app/scripts/directives/logEntry.js +++ b/ui/app/scripts/directives/logEntry.js @@ -1,14 +1,14 @@ (function() { 'use strict'; angular.module('theHiveDirectives') - .directive('logEntry', function($modal, TaskLogSrv, UserInfoSrv, AlertSrv) { + .directive('logEntry', function($uibModal, TaskLogSrv, UserInfoSrv, AlertSrv) { return { templateUrl: 'views/directives/log-entry.html', link: function(scope) { // drop log scope.dropLog = function() { - scope.deleteModal = $modal.open({ + scope.deleteModal = $uibModal.open({ scope: scope, templateUrl: 'views/directives/log-entry-delete.html', size: '' @@ -39,8 +39,8 @@ return angular.isString(contentType) && contentType.indexOf('image') === 0; }; scope.showImage = function() { - $modal.open({ - template: '' + scope.log.attachment.name + '', + $uibModal.open({ + template: '' + scope.log.attachment.name + '', size: 'lg' }); }; diff --git a/ui/app/scripts/directives/report.js b/ui/app/scripts/directives/report.js index d5185f3010..3bbd53054e 100644 --- a/ui/app/scripts/directives/report.js +++ b/ui/app/scripts/directives/report.js @@ -8,7 +8,7 @@ return; } - var reportUrl = '/api/connector/cortex/report/template/content/' + scope.name + '/' + scope.reportType; + var reportUrl = './api/connector/cortex/report/template/content/' + scope.name + '/' + scope.reportType; // find report template $templateRequest(reportUrl, true) diff --git a/ui/app/scripts/directives/search/search-item.js b/ui/app/scripts/directives/search/search-item.js index 323e220194..c48c18decf 100644 --- a/ui/app/scripts/directives/search/search-item.js +++ b/ui/app/scripts/directives/search/search-item.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveDirectives') - .directive('searchItem', function($modal, UserInfoSrv) { + .directive('searchItem', function($uibModal, UserInfoSrv) { return { restrict: 'E', replace: true, @@ -19,8 +19,8 @@ return angular.isString(contentType) && contentType.indexOf('image') === 0; }; scope.showImage = function(attachmentId, attachmentName) { - $modal.open({ - template: '' + attachmentName + '', + $uibModal.open({ + template: '' + attachmentName + '', size: 'lg' }); }; diff --git a/ui/app/scripts/directives/updatableUser.js b/ui/app/scripts/directives/updatableUser.js index f09774afa4..2db514ea94 100644 --- a/ui/app/scripts/directives/updatableUser.js +++ b/ui/app/scripts/directives/updatableUser.js @@ -7,6 +7,7 @@ 'link': function(scope, element, attrs, ctrl, transclude) { UtilsSrv.updatableLink(scope, element, attrs, ctrl, transclude); scope.userList = PSearchSrv(undefined, 'user', { + scope: scope, baseFilter: { 'status': 'Ok' }, diff --git a/ui/app/scripts/services/AfkSrv.js b/ui/app/scripts/services/AfkSrv.js index b8e5800815..141ee12d18 100644 --- a/ui/app/scripts/services/AfkSrv.js +++ b/ui/app/scripts/services/AfkSrv.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveServices') - .factory('AfkSrv', function($rootScope, $q, $modal, $http) { + .factory('AfkSrv', function($rootScope, $q, $uibModal, $http) { var current = null; return { @@ -13,7 +13,7 @@ prompt: function() { var defer = $q.defer(); - $http.get('/api/stream/status').then(function(response) { + $http.get('./api/stream/status').then(function(response) { if(response.data.warning === true) { if(current !== null) { @@ -27,7 +27,7 @@ current = null; }; - current = $modal.open({ + current = $uibModal.open({ scope: scope, templateUrl: 'views/partials/afk-modal.html', size: '' diff --git a/ui/app/scripts/services/AnalyzerSrv.js b/ui/app/scripts/services/AnalyzerSrv.js index 5877140e4e..31c9954b1d 100644 --- a/ui/app/scripts/services/AnalyzerSrv.js +++ b/ui/app/scripts/services/AnalyzerSrv.js @@ -3,10 +3,10 @@ angular.module('theHiveServices') .factory('AnalyzerSrv', function ($resource, $q) { var analyzers = null, - resource = $resource('/api/connector/cortex/analyzer/:analyzerId', {}, { + resource = $resource('./api/connector/cortex/analyzer/:analyzerId', {}, { query: { method: 'GET', - url: '/api/connector/cortex/analyzer', + url: './api/connector/cortex/analyzer', isArray: true }, get: { @@ -29,7 +29,10 @@ resource.query({ range: 'all' }, {}, function (response) { - analyzers = _.indexBy(response, 'id'); + + analyzers = _.indexBy(_.map(response, function(item) { + return item.toJSON(); + }), 'id'); deferred.resolve(analyzers); }, function (/*rejection*/) { diff --git a/ui/app/scripts/services/AuditSrv.js b/ui/app/scripts/services/AuditSrv.js index 6ee7c6a102..769b760bb6 100644 --- a/ui/app/scripts/services/AuditSrv.js +++ b/ui/app/scripts/services/AuditSrv.js @@ -2,13 +2,13 @@ 'use strict'; angular.module('theHiveServices') .factory('AuditSrv', function($http, StreamSrv, AlertSrv) { - return function(rootId, max) { + return function(rootId, max, scope) { var ret = []; if (!isFinite(max)) { max = 10; } - $http.get('/api/flow', { + $http.get('./api/flow', { 'params': { 'rootId': rootId, 'count': max @@ -22,23 +22,31 @@ return m.base.requestId === message.base.requestId; }; }; - StreamSrv.listen(rootId, 'any', function(messages) { - for (var i = messages.length - 1, messageAdded = 0; i >= 0 && messageAdded < max; i--) { - var message = messages[i]; - var alreadyInFlow = _.find(ret, fnSameRequestId(message)) !== undefined; - if (!alreadyInFlow && message.base.objectType !== 'user') { - var index = messageAdded; - ret.splice(index, 0, message); - if (ret.length > max) { - ret.pop(); + + var eventConfig = { + rootId: rootId, + objectType: 'any', + scope: scope, + callback: function(messages) { + for (var i = messages.length - 1, messageAdded = 0; i >= 0 && messageAdded < max; i--) { + var message = messages[i]; + var alreadyInFlow = _.find(ret, fnSameRequestId(message)) !== undefined; + if (!alreadyInFlow && message.base.objectType !== 'user') { + var index = messageAdded; + ret.splice(index, 0, message); + if (ret.length > max) { + ret.pop(); + } + messageAdded += 1; + } else if(alreadyInFlow && message.base.objectType === 'case_artifact_job') { + ret[messageAdded] = message; } - messageAdded += 1; - } else if(alreadyInFlow && message.base.objectType === 'case_artifact_job') { - ret[messageAdded] = message; - } + } } - }); + }; + + StreamSrv.addListener(eventConfig); }).error(function(data, status) { AlertSrv.error('AuditSrv', data, status); }); diff --git a/ui/app/scripts/services/AuthenticationSrv.js b/ui/app/scripts/services/AuthenticationSrv.js index c90069248c..9fdbb2c5c4 100644 --- a/ui/app/scripts/services/AuthenticationSrv.js +++ b/ui/app/scripts/services/AuthenticationSrv.js @@ -4,7 +4,7 @@ var self = { currentUser: null, login: function(username, password, success, failure) { - $http.post('/api/login', { + $http.post('./api/login', { 'user': username, 'password': password }).success(function(data, status, headers, config) { @@ -18,7 +18,7 @@ }); }, logout: function(success, failure) { - $http.get('/api/logout').success(function(data, status, headers, config) { + $http.get('./api/logout').success(function(data, status, headers, config) { self.currentUser = null; if (angular.isFunction(success)) { @@ -32,7 +32,7 @@ }, current: function(success, failure) { var result = {}; - $http.get('/api/user/current').success(function(data, status, headers, config) { + $http.get('./api/user/current').success(function(data, status, headers, config) { self.currentUser = data; UtilsSrv.shallowClearAndCopy(data, result); diff --git a/ui/app/scripts/services/CaseArtifactSrv.js b/ui/app/scripts/services/CaseArtifactSrv.js index 59783ba212..d14863d047 100644 --- a/ui/app/scripts/services/CaseArtifactSrv.js +++ b/ui/app/scripts/services/CaseArtifactSrv.js @@ -8,12 +8,12 @@ var factory = { api: function() { if(api === null) { - return FileResource('/api/case/:caseId/artifact/:artifactId', {}, { + return FileResource('./api/case/:caseId/artifact/:artifactId', {}, { update: { method: 'PATCH' }, similar: { - url: '/api/case/artifact/:artifactId/similar', + url: './api/case/artifact/:artifactId/similar', isArray: true } }); diff --git a/ui/app/scripts/services/CaseSrv.js b/ui/app/scripts/services/CaseSrv.js index 6b7288a6a8..b47fbe6bc7 100644 --- a/ui/app/scripts/services/CaseSrv.js +++ b/ui/app/scripts/services/CaseSrv.js @@ -2,18 +2,18 @@ 'use strict'; angular.module('theHiveServices') .factory('CaseSrv', function($resource) { - return $resource('/api/case/:caseId', {}, { + return $resource('./api/case/:caseId', {}, { update: { method: 'PATCH' }, links: { method: 'GET', - url: '/api/case/:caseId/links', + url: './api/case/:caseId/links', isArray: true }, merge: { method: 'POST', - url: '/api/case/:caseId/_merge/:mergedCaseId', + url: './api/case/:caseId/_merge/:mergedCaseId', params: { caseId: '@caseId', mergedCaseId: '@mergedCaseId', diff --git a/ui/app/scripts/services/CaseTabsSrv.js b/ui/app/scripts/services/CaseTabsSrv.js index 17ca824830..20eb9f9db5 100644 --- a/ui/app/scripts/services/CaseTabsSrv.js +++ b/ui/app/scripts/services/CaseTabsSrv.js @@ -1,6 +1,7 @@ (function() { 'use strict'; - angular.module('theHiveServices').factory('CaseTabsSrv', function() { + angular.module('theHiveServices').service('CaseTabsSrv', function() { + var tabs = { 'details': { name: 'details', @@ -22,60 +23,63 @@ } }; - return { - - initTabs: function() { - angular.forEach(tabs, function(tab, key) { - if (tab.closable === true) { - delete tabs[key]; - } - }); - }, + this.activeIndex = 0; - getTabs: function() { - return tabs; - }, + this.initTabs = function() { + angular.forEach(tabs, function(tab, key) { + if (tab.closable === true) { + delete tabs[key]; + } + }); + }; - getTab: function(name) { - return tabs[name]; - }, + this.getTabs = function() { + return tabs; + }; - activateTab: function(tab) { - angular.forEach(tabs, function(tab) { - tab.active = false; - }); + this.getTab = function(name) { + return tabs[name]; + }; - if (tabs[tab]) { - tabs[tab].active = true; - } else { - tabs.details.active = true; - } - }, + this.activateTab = function(tab) { + angular.forEach(tabs, function(tab) { + tab.active = false; + }); - addTab: function(tab, options) { - options.closable = true; + if (tabs[tab]) { + tabs[tab].active = true; + this.activeIndex = Object.keys(tabs).indexOf(tab); + } else { + tabs.details.active = true; + this.activeIndex = 0; + } + }; - tabs[tab] = options; - }, + this.addTab = function(tab, options) { + options.closable = true; - removeTab: function(tab) { - var tabItem = tabs[tab]; + tabs[tab] = options; + this.activeIndex = Object.keys(tabs).length - 1; + }; - if(!tabItem) { - return; - } + this.removeTab = function(tab) { + var tabItem = tabs[tab]; - var currentIsActive = tabItem.active; + if (!tabItem) { + return; + } - delete tabs[tab]; + var currentIsActive = tabItem.active; - if (currentIsActive) { - return true; - } else { - return false; - } + delete tabs[tab]; + if (currentIsActive) { + return true; + } else { + return false; } + }; + }); })(); diff --git a/ui/app/scripts/services/CaseTaskSrv.js b/ui/app/scripts/services/CaseTaskSrv.js index 745015d7e1..5a85bd3ffe 100644 --- a/ui/app/scripts/services/CaseTaskSrv.js +++ b/ui/app/scripts/services/CaseTaskSrv.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveServices') .factory('CaseTaskSrv', function($resource) { - return $resource('/api/case/:caseId/task/:taskId', {}, { + return $resource('./api/case/:caseId/task/:taskId', {}, { update: { method: 'PATCH' } diff --git a/ui/app/scripts/services/CortexSrv.js b/ui/app/scripts/services/CortexSrv.js index 11cb07589a..073bf95da0 100644 --- a/ui/app/scripts/services/CortexSrv.js +++ b/ui/app/scripts/services/CortexSrv.js @@ -1,13 +1,14 @@ (function () { 'use strict'; angular.module('theHiveServices') - .factory('CortexSrv', function ($q, $http, $rootScope, $modal, StatSrv, StreamSrv, AnalyzerSrv, PSearchSrv) { + .factory('CortexSrv', function ($q, $http, $rootScope, $uibModal, StatSrv, StreamSrv, AnalyzerSrv, PSearchSrv) { - var baseUrl = '/api/connector/cortex'; + var baseUrl = './api/connector/cortex'; var factory = { - list: function (caseId, observableId, callback) { + list: function (scope, caseId, observableId, callback) { return PSearchSrv(undefined, 'connector/cortex/job', { + scope: scope, sort: '-startDate', loadAll: false, pageSize: 200, @@ -44,7 +45,7 @@ }, promptForInstance: function (servers) { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ templateUrl: 'views/partials/cortex/choose-instance-dialog.html', controller: 'CortexInstanceDialogCtrl', controllerAs: 'vm', diff --git a/ui/app/scripts/services/JobSrv.js b/ui/app/scripts/services/JobSrv.js index d645383bce..10f78dd227 100644 --- a/ui/app/scripts/services/JobSrv.js +++ b/ui/app/scripts/services/JobSrv.js @@ -2,6 +2,6 @@ 'use strict'; angular.module('theHiveServices') .factory('JobSrv', function($resource) { - return $resource('/api/case/artifact/:artifactId/job/:analyzerId', {}, {}, {}); + return $resource('./api/case/artifact/:artifactId/job/:analyzerId', {}, {}, {}); }); })(); diff --git a/ui/app/scripts/services/ListSrv.js b/ui/app/scripts/services/ListSrv.js index dbd684e440..9479faf890 100644 --- a/ui/app/scripts/services/ListSrv.js +++ b/ui/app/scripts/services/ListSrv.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveServices').factory('ListSrv', function($resource) { - return $resource('/api/list/:listId', {}, { + return $resource('./api/list/:listId', {}, { query: { method: 'GET', isArray: false diff --git a/ui/app/scripts/services/MetricsCacheSrv.js b/ui/app/scripts/services/MetricsCacheSrv.js index 437d470a01..0f3c3c4e43 100644 --- a/ui/app/scripts/services/MetricsCacheSrv.js +++ b/ui/app/scripts/services/MetricsCacheSrv.js @@ -3,7 +3,7 @@ angular.module('theHiveServices').factory('MetricsCacheSrv', function($resource, $q) { var metrics = null, - resource = $resource('/api/list/:listId', {}, { + resource = $resource('./api/list/:listId', {}, { query: { method: 'GET', isArray: false diff --git a/ui/app/scripts/services/MispSrv.js b/ui/app/scripts/services/MispSrv.js index 9099921b58..14dac0cd34 100644 --- a/ui/app/scripts/services/MispSrv.js +++ b/ui/app/scripts/services/MispSrv.js @@ -3,11 +3,12 @@ angular.module('theHiveServices') .factory('MispSrv', function($q, $http, $rootScope, StatSrv, StreamSrv, PSearchSrv) { - var baseUrl = '/api/connector/misp'; + var baseUrl = './api/connector/misp'; var factory = { - list: function(callback) { + list: function(scope, callback) { return PSearchSrv(undefined, 'connector/misp', { + scope: scope, sort: '-publishDate', loadAll: false, pageSize: 10, @@ -44,7 +45,7 @@ $rootScope.$broadcast('misp:status-updated', false); }, - stats: function() { + stats: function(scope) { var field = 'eventStatus', mispStatQuery = { _not: { @@ -65,8 +66,14 @@ }; - StreamSrv.listen('any', 'misp', function() { - StatSrv.get(statConfig); + + StreamSrv.addListener({ + rootId: 'any', + objectType: 'misp', + scope: scope, + callback: function() { + StatSrv.get(statConfig); + } }); return StatSrv.get(statConfig); diff --git a/ui/app/scripts/services/PSearchSrv.js b/ui/app/scripts/services/PSearchSrv.js index 3035c765b5..a103a64669 100644 --- a/ui/app/scripts/services/PSearchSrv.js +++ b/ui/app/scripts/services/PSearchSrv.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveServices') .factory('PSearchSrv', function(SearchSrv, StreamSrv) { - function update(objectType, control) { + function update(objectType, control, updates) { var range = ''; if (control.loadAll) { range = 'all'; @@ -27,18 +27,12 @@ } SearchSrv(function(data, total) { if (control.loadAll) { - control.allValues.length = 0; - angular.forEach(data, function(d) { - control.allValues.push(d); - }); + control.allValues = data; changePage(control); } else { - control.values.length = 0; - angular.forEach(data, function(d) { - control.values.push(d); - }); + control.values = data; if (angular.isFunction(control.onUpdate)) { - control.onUpdate(); + control.onUpdate(updates); } } control.total = total; @@ -93,9 +87,16 @@ } if (control.skipStream !== true) { - StreamSrv.listen(root, control.streamObjectType || objectType, function() { - update(objectType, control); - }); + var streamCfg = { + scope: control.scope, + rootId: root, + objectType: control.streamObjectType || objectType, + callback: function(updates) { + update(objectType, control, updates); + } + }; + + StreamSrv.addListener(streamCfg); } update(objectType, control); diff --git a/ui/app/scripts/services/ReportTemplateSrv.js b/ui/app/scripts/services/ReportTemplateSrv.js index ab9e1a318e..26dd25cbd0 100644 --- a/ui/app/scripts/services/ReportTemplateSrv.js +++ b/ui/app/scripts/services/ReportTemplateSrv.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveServices') .factory('ReportTemplateSrv', function($resource, $http) { - var baseUrl = '/api/connector/cortex/report/template'; + var baseUrl = './api/connector/cortex/report/template'; var resource = $resource(baseUrl, {}, { query: { method: 'POST', diff --git a/ui/app/scripts/services/SearchSrv.js b/ui/app/scripts/services/SearchSrv.js index c314cc441e..2922a4a360 100644 --- a/ui/app/scripts/services/SearchSrv.js +++ b/ui/app/scripts/services/SearchSrv.js @@ -5,9 +5,9 @@ return function(cb, filter, objectType, range, sort, nparent, nstats) { var url; if (!angular.isString(objectType) || objectType === 'any') { - url = '/api/_search'; + url = './api/_search'; } else { - url = '/api/' + objectType.replace(/_/g, '/') + '/_search'; + url = './api/' + objectType.replace(/_/g, '/') + '/_search'; } var params = ''; diff --git a/ui/app/scripts/services/StatSrv.js b/ui/app/scripts/services/StatSrv.js index dbad2932cf..0202c1feb3 100644 --- a/ui/app/scripts/services/StatSrv.js +++ b/ui/app/scripts/services/StatSrv.js @@ -29,7 +29,7 @@ _agg: 'count' }); - return $http.post('/api/' + config.objectType.replace(/_/g, '/') + '/_stats', { + return $http.post('./api/' + config.objectType.replace(/_/g, '/') + '/_stats', { query: config.query, stats: stats }) diff --git a/ui/app/scripts/services/StreamSrv.js b/ui/app/scripts/services/StreamSrv.js index a96fb46c7f..40e1e13c9f 100644 --- a/ui/app/scripts/services/StreamSrv.js +++ b/ui/app/scripts/services/StreamSrv.js @@ -1,7 +1,6 @@ (function() { 'use strict'; - angular.module('theHiveServices').factory('StreamSrv', function($http, $timeout, UserSrv, AuthenticationSrv, AfkSrv, AlertSrv) { - var callbacks = { /* id: { objectType: [ cb ] } */ }; + angular.module('theHiveServices').factory('StreamSrv', function($rootScope, $http, $timeout, UserSrv, AuthenticationSrv, AfkSrv, AlertSrv) { var self = { isPolling: false, @@ -13,15 +12,14 @@ }, runCallbacks: function(id, objectType, message) { - var cbs = callbacks[id]; - if (angular.isDefined(cbs)) { - angular.forEach(cbs[objectType], function(cb) { - cb(message); - }); - } + $rootScope.$broadcast('stream:' + id + '-' + objectType, message); }, handleStreamResponse: function(data) { + if(!data || data.length === 0) { + return; + } + var byRootIds = {}; var byObjectTypes = {}; var byRootIdsWithObjectTypes = {}; @@ -76,7 +74,7 @@ self.isPolling = true; // Poll stream changes - $http.get('/api/stream/' + self.streamId).success(function(data, status) { + $http.get('./api/stream/' + self.streamId).success(function(data, status) { // Flag polling end self.isPolling = false; @@ -86,7 +84,7 @@ // Check if the session will expire soon if (status === 220) { AfkSrv.prompt().then(function() { - UserSrv.getUserInfo.get(AuthenticationSrv.currentUser.id) + UserSrv.getUserInfo(AuthenticationSrv.currentUser.id) .then(function() { }, function(response) { @@ -118,7 +116,7 @@ return; } - $http.post('/api/stream').success(function(streamId) { + $http.post('./api/stream').success(function(streamId) { self.streamId = streamId; self.poll(self.streamId); }).error(function(data, status) { @@ -126,17 +124,25 @@ }); }, - listen: function(rootId, objectType, cb) { - if (angular.isDefined(callbacks[rootId])) { - if (angular.isDefined(callbacks[rootId][objectType])) { - callbacks[rootId][objectType].push(cb); - } else { - callbacks[rootId][objectType] = [cb]; - } - } else { - callbacks[rootId] = {}; - callbacks[rootId][objectType] = [cb]; + /** + * @param config {Object} This configuration object has the following attributes + *
  • rootId
  • + *
  • objectType {String}
  • + *
  • scope {Object}
  • + *
  • callback {Function}
  • + */ + addListener: function(config) { + if(!config.scope) { + console.error('No scope provided, use the old listen method', config); + self.listen(config.rootId, config.objectType, config.callback); + return; } + + var eventName = 'stream:' + config.rootId + '-' + config.objectType; + config.scope.$on(eventName, function(event, data) { + config.callback(data); + }); + } }; diff --git a/ui/app/scripts/services/StreamStatSrv.js b/ui/app/scripts/services/StreamStatSrv.js index e1aa51abab..148263a199 100644 --- a/ui/app/scripts/services/StreamStatSrv.js +++ b/ui/app/scripts/services/StreamStatSrv.js @@ -13,8 +13,13 @@ *
  • error {Function}
  • */ return function(config) { - StreamSrv.listen(config.rootId, config.objectType, function() { - StatSrv.get(config); + StreamSrv.addListener({ + rootId: config.rootId, + objectType: config.objectType, + scope: config.scope, + callback:function() { + StatSrv.get(config); + } }); return StatSrv.get(config); diff --git a/ui/app/scripts/services/TaskLogSrv.js b/ui/app/scripts/services/TaskLogSrv.js index e5f97433bd..ed555ba737 100644 --- a/ui/app/scripts/services/TaskLogSrv.js +++ b/ui/app/scripts/services/TaskLogSrv.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveServices').factory('TaskLogSrv', function(FileResource) { - return FileResource('/api/case/task/:taskId/log/:logId', {}, { + return FileResource('./api/case/task/:taskId/log/:logId', {}, { update: { method: 'PATCH' } diff --git a/ui/app/scripts/services/TemplateSrv.js b/ui/app/scripts/services/TemplateSrv.js index 803987ebfb..b47888a608 100644 --- a/ui/app/scripts/services/TemplateSrv.js +++ b/ui/app/scripts/services/TemplateSrv.js @@ -2,13 +2,13 @@ 'use strict'; angular.module('theHiveServices') .factory('TemplateSrv', function($resource) { - return $resource('/api/case/template/:templateId', {}, { + return $resource('./api/case/template/:templateId', {}, { update: { method: 'PATCH', }, query: { method: 'POST', - url: '/api/case/template/_search', + url: './api/case/template/_search', isArray: true, params: { range: 'all' diff --git a/ui/app/scripts/services/UserSrv.js b/ui/app/scripts/services/UserSrv.js index a11c1d7a32..502fea1c7c 100644 --- a/ui/app/scripts/services/UserSrv.js +++ b/ui/app/scripts/services/UserSrv.js @@ -1,10 +1,10 @@ angular.module('theHiveServices') .factory('UserSrv', function($resource, $http, $q, AlertSrv, UtilsSrv) { 'use strict'; - var res = $resource('/api/user/:userId', {}, { + var res = $resource('./api/user/:userId', {}, { query: { method: 'POST', - url: '/api/user/_search', + url: './api/user/_search', isArray: true }, update: { @@ -12,11 +12,11 @@ angular.module('theHiveServices') }, changePass: { method: 'POST', - url: '/api/user/:userId/password/change' + url: './api/user/:userId/password/change' }, setPass: { method: 'POST', - url: '/api/user/:userId/password/set' + url: './api/user/:userId/password/set' } }); /** @@ -78,7 +78,7 @@ angular.module('theHiveServices') query: query }; - $http.post('/api/user/_search', post) + $http.post('./api/user/_search', post) .then(function(response) { defer.resolve(response.data); }); diff --git a/ui/app/scripts/services/VersionSrv.js b/ui/app/scripts/services/VersionSrv.js index 2aeab0eda1..c5c0390a96 100644 --- a/ui/app/scripts/services/VersionSrv.js +++ b/ui/app/scripts/services/VersionSrv.js @@ -11,7 +11,7 @@ if(cache !== null) { deferred.resolve(cache); } else { - $http.get('/api/status').then(function(response) { + $http.get('./api/status').then(function(response) { cache = response.data; deferred.resolve(cache); }, function(rejection) { diff --git a/ui/app/styles/directives/user.css b/ui/app/styles/directives/user.css index 54f3b3c645..2cd5bcec75 100644 --- a/ui/app/styles/directives/user.css +++ b/ui/app/styles/directives/user.css @@ -46,3 +46,12 @@ .avatar.avatar-m .avatar-name { margin-left:45px; } + +.avatar-input { + width: 0.1px; + height: 0.1px; + opacity: 0; + overflow: hidden; + position: absolute; + z-index: -1; +} diff --git a/ui/app/views/app.case.html b/ui/app/views/app.case.html index 80b9bbfd59..18718f3a93 100644 --- a/ui/app/views/app.case.html +++ b/ui/app/views/app.case.html @@ -4,9 +4,9 @@
    - - - + + +    {{tab.label}} @@ -39,9 +39,9 @@ - - - + + +
    diff --git a/ui/app/views/app.html b/ui/app/views/app.html index 36e57dec69..c889275e2b 100644 --- a/ui/app/views/app.html +++ b/ui/app/views/app.html @@ -14,13 +14,13 @@