[Cases] RBAC (#95058)

* Adding feature flag for auth

* Hiding SOs and adding consumer field

* First pass at adding security changes

* Consumer as the app's plugin ID

* Create addConsumerToSO migration helper

* Fix mapping's SO consumer

* Add test for CasesActions

* Declare hidden types on SO client

* Restructure integration tests

* Init spaces_only integration tests

* Implementing the cases security string

* Adding security plugin tests for cases

* Rough concept for authorization class

* Adding comments

* Fix merge

* Get requiredPrivileges for classes

* Check privillages

* Ensure that all classes are available

* Success if hasAllRequested is true

* Failure if hasAllRequested is false

* Adding schema updates for feature plugin

* Seperate basic from trial

* Enable SIR on integration tests

* Starting the plumbing for authorization in plugin

* Unit tests working

* Move find route logic to case client

* Create integration test helper functions

* Adding auth to create call

* Create getClassFilter helper

* Add class attribute to find request

* Create getFindAuthorizationFilter

* Ensure savedObject is authorized in find method

* Include fields for authorization

* Combine authorization filter with cases & subcases filter

* Fix isAuthorized flag

* Fix merge issue

* Create/delete spaces & users before and after tests

* Add more user and roles

* [Cases] Convert filters from strings to KueryNode (#95288)

* [Cases] RBAC: Rename class to scope (#95535)

* [Cases][RBAC] Rename scope to owner (#96035)

* [Cases] RBAC: Create & Find integration tests (#95511)

* [Cases] Cases client enchantment (#95923)

* [Cases] Authorization and Client Audit Logger (#95477)

* Starting audit logger

* Finishing auth audit logger

* Fixing tests and types

* Adding audit event creator

* Renaming class to scope

* Adding audit logger messages to create and find

* Adding comments and fixing import issue

* Fixing type errors

* Fixing tests and adding username to message

* Addressing PR feedback

* Removing unneccessary log and generating id

* Fixing module issue and remove expect.anything

* [Cases] Migrate sub cases routes to a client (#96461)

* Adding sub cases client

* Move sub case routes to case client

* Throw when attempting to access the sub cases client

* Fixing throw and removing user ans soclients

* [Cases] RBAC: Migrate routes' unit tests to integration tests (#96374)

Co-authored-by: Jonathan Buttner <jonathan.buttner@elastic.co>

* [Cases] Move remaining HTTP functionality to client (#96507)

* Moving deletes and find for attachments

* Moving rest of comment apis

* Migrating configuration routes to client

* Finished moving routes, starting utils refactor

* Refactoring utilites and fixing integration tests

* Addressing PR feedback

* Fixing mocks and types

* Fixing integration tests

* Renaming status_stats

* Fixing test type errors

* Adding plugins to kibana.json

* Adding cases to required plugin

* [Cases] Refactoring authorization (#97483)

* Refactoring authorization

* Wrapping auth calls in helper for try catch

* Reverting name change

* Hardcoding the saved object types

* Switching ensure to owner array

* [Cases] Add authorization to configuration & cases routes (#97228)

* [Cases] Attachments RBAC (#97756)

* Starting rbac for comments

* Adding authorization to rest of comment apis

* Starting the comment rbac tests

* Fixing some of the rbac tests

* Adding some integration tests

* Starting patch tests

* Working tests for comments

* Working tests

* Fixing some tests

* Fixing type issues from pulling in master

* Fixing connector tests that only work in trial license

* Attempting to fix cypress

* Mock return of array for configure

* Fixing cypress test

* Cleaning up

* Addressing PR comments

* Reducing operations

* [Cases] Add RBAC to remaining Cases APIs (#98762)

* Starting rbac for comments

* Adding authorization to rest of comment apis

* Starting the comment rbac tests

* Fixing some of the rbac tests

* Adding some integration tests

* Starting patch tests

* Working tests for comments

* Working tests

* Fixing some tests

* Fixing type issues from pulling in master

* Fixing connector tests that only work in trial license

* Attempting to fix cypress

* Mock return of array for configure

* Fixing cypress test

* Cleaning up

* Working case update tests

* Addressing PR comments

* Reducing operations

* Working rbac push case tests

* Starting stats apis

* Working status tests

* User action tests and fixing migration errors

* Fixing type errors

* including error in message

* Addressing pr feedback

* Fixing some type errors

* [Cases] Add space only tests (#99409)

* Starting spaces tests

* Finishing space only tests

* Refactoring createCaseWithConnector

* Fixing spelling

* Addressing PR feedback and creating alert tests

* Fixing mocks

* [Cases] Add security only tests (#99679)

* Starting spaces tests

* Finishing space only tests

* Refactoring createCaseWithConnector

* Fixing spelling

* Addressing PR feedback and creating alert tests

* Fixing mocks

* Starting security only tests

* Adding remainder security only tests

* Using helper objects

* Fixing type error for null space

* Renaming utility variables

* Refactoring users and roles for security only tests

* Adding sub feature

* [Cases] Cleaning up the services and TODOs (#99723)

* Cleaning up the service intialization

* Fixing type errors

* Adding comments for the api

* Working test for cases client

* Fix type error

* Adding generated docs

* Adding more docs and cleaning up types

* Cleaning up readme

* More clean up and links

* Changing some file names

* Renaming docs

* Integration tests for cases privs and fixes (#100038)

* [Cases] RBAC on UI (#99478)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

* Fixing case ids by alert id route call

* [Cases] Fixing UI feature permissions and adding UI tests (#100074)

* Integration tests for cases privs and fixes

* Fixing ui cases permissions and adding tests

* Adding test for collection failure and fixing jest

* Renaming variables

* Fixing type error

* Adding some comments

* Validate cases features

* Fix new schema

* Adding owner param for the status stats

* Fix get case status tests

* Adjusting permissions text and fixing status

* Address PR feedback

* Adding top level feature back

* Fixing feature privileges

* Renaming

* Removing uneeded else

* Fixing tests and adding cases merge tests

* [Cases][Security Solution] Basic license security solution API tests (#100925)

* Cleaning up the fixture plugins

* Adding basic feature test

* renaming to unsecuredSavedObjectsClient (#101215)

* [Cases] RBAC Refactoring audit logging (#100952)

* Refactoring audit logging

* Adding unit tests for authorization classes

* Addressing feedback and adding util tests

* return undefined on empty array

* fixing eslint

* [Cases] Cleaning up RBAC integration tests (#101324)

* Adding tests for space permissions

* Adding tests for testing a disable feature

Co-authored-by: Christos Nasikas <christos.nasikas@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Jonathan Buttner 2021-06-07 09:37:11 -04:00 committed by GitHub
parent 999faecd2c
commit b6c982c3b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
487 changed files with 33107 additions and 17281 deletions

View file

@ -14,6 +14,7 @@ Case management in Kibana
## Table of Contents
- [Cases API](#cases-api)
- [Cases Client API](#cases-client-api)
- [Cases UI](#cases-ui)
- [Case Action Type](#case-action-type) _feature in development, disabled by default_
@ -21,6 +22,9 @@ Case management in Kibana
## Cases API
[**Explore the API docs »**](https://www.elastic.co/guide/en/security/current/cases-api-overview.html)
## Cases Client API
[**Cases Client API docs**][cases-client-api-docs]
## Cases UI
#### Embed Cases UI components in any Kibana plugin
@ -263,4 +267,4 @@ For IBM Resilient connectors:
[all-cases-modal-img]: images/all_cases_selector_modal.png
[recent-cases-img]: images/recent_cases.png
[case-view-img]: images/case_view.png
[cases-client-api-docs]: docs/cases_client/cases_client_api.md

View file

@ -31,13 +31,38 @@ const SettingsRt = rt.type({
});
const CaseBasicRt = rt.type({
/**
* The description of the case
*/
description: rt.string,
/**
* The current status of the case (open, closed, in-progress)
*/
status: CaseStatusRt,
/**
* The identifying strings for filter a case
*/
tags: rt.array(rt.string),
/**
* The title of a case
*/
title: rt.string,
/**
* The type of a case (individual or collection)
*/
[caseTypeField]: CaseTypeRt,
/**
* The external system that the case can be synced with
*/
connector: CaseConnectorRt,
/**
* The alert sync settings
*/
settings: SettingsRt,
/**
* The plugin owner of the case
*/
owner: rt.string,
});
const CaseExternalServiceBasicRt = rt.type({
@ -73,11 +98,31 @@ export const CaseAttributesRt = rt.intersection([
]);
const CasePostRequestNoTypeRt = rt.type({
/**
* Description of the case
*/
description: rt.string,
/**
* Identifiers for the case.
*/
tags: rt.array(rt.string),
/**
* Title of the case
*/
title: rt.string,
/**
* The external configuration for the case
*/
connector: CaseConnectorRt,
/**
* Sync settings for alerts
*/
settings: SettingsRt,
/**
* The owner here must match the string used when a plugin registers a feature with access to the cases plugin. The user
* creating this case must also be granted access to that plugin's feature.
*/
owner: rt.string,
});
/**
@ -95,23 +140,78 @@ export const CasesClientPostRequestRt = rt.type({
* has all the necessary fields. CasesClientPostRequestRt is used for validation.
*/
export const CasePostRequestRt = rt.intersection([
rt.partial({ type: CaseTypeRt }),
/**
* The case type: an individual case (one without children) or a collection case (one with children)
*/
rt.partial({ [caseTypeField]: CaseTypeRt }),
CasePostRequestNoTypeRt,
]);
export const CasesFindRequestRt = rt.partial({
/**
* Type of a case (individual, or collection)
*/
type: CaseTypeRt,
/**
* Tags to filter by
*/
tags: rt.union([rt.array(rt.string), rt.string]),
/**
* The status of the case (open, closed, in-progress)
*/
status: CaseStatusRt,
/**
* The reporters to filter by
*/
reporters: rt.union([rt.array(rt.string), rt.string]),
/**
* Operator to use for the `search` field
*/
defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
/**
* The fields in the entity to return in the response
*/
fields: rt.array(rt.string),
/**
* The page of objects to return
*/
page: NumberFromString,
/**
* The number of objects to include in each page
*/
perPage: NumberFromString,
/**
* An Elasticsearch simple_query_string
*/
search: rt.string,
searchFields: rt.array(rt.string),
/**
* The fields to perform the simple_query_string parsed query against
*/
searchFields: rt.union([rt.array(rt.string), rt.string]),
/**
* The field to use for sorting the found objects.
*
* This only supports, `create_at`, `closed_at`, and `status`
*/
sortField: rt.string,
/**
* The order to sort by
*/
sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]),
/**
* The owner(s) to filter by. The user making the request must have privileges to retrieve cases of that
* ownership or they will be ignored. If no owner is included, then all ownership types will be included in the response
* that the user has access to.
*/
owner: rt.union([rt.array(rt.string), rt.string]),
});
export const CasesByAlertIDRequestRt = rt.partial({
/**
* The type of cases to retrieve given an alert ID. If no owner is provided, all cases
* that the user has access to will be returned.
*/
owner: rt.union([rt.array(rt.string), rt.string]),
});
export const CaseResponseRt = rt.intersection([
@ -141,6 +241,9 @@ export const CasesFindResponseRt = rt.intersection([
export const CasePatchRequestRt = rt.intersection([
rt.partial(CaseBasicRt.props),
/**
* The saved object ID and version
*/
rt.type({ id: rt.string, version: rt.string }),
]);
@ -172,6 +275,16 @@ export const ExternalServiceResponseRt = rt.intersection([
}),
]);
export const AllTagsFindRequestRt = rt.partial({
/**
* The owner of the cases to retrieve the tags from. If no owner is provided the tags from all cases
* that the user has access to will be returned.
*/
owner: rt.union([rt.array(rt.string), rt.string]),
});
export const AllReportersFindRequestRt = AllTagsFindRequestRt;
export type CaseAttributes = rt.TypeOf<typeof CaseAttributesRt>;
/**
* This field differs from the CasePostRequest in that the post request's type field can be optional. This type requires
@ -183,6 +296,7 @@ export type CasePostRequest = rt.TypeOf<typeof CasePostRequestRt>;
export type CaseResponse = rt.TypeOf<typeof CaseResponseRt>;
export type CasesResponse = rt.TypeOf<typeof CasesResponseRt>;
export type CasesFindRequest = rt.TypeOf<typeof CasesFindRequestRt>;
export type CasesByAlertIDRequest = rt.TypeOf<typeof CasesByAlertIDRequestRt>;
export type CasesFindResponse = rt.TypeOf<typeof CasesFindResponseRt>;
export type CasePatchRequest = rt.TypeOf<typeof CasePatchRequestRt>;
export type CasesPatchRequest = rt.TypeOf<typeof CasesPatchRequestRt>;
@ -194,3 +308,6 @@ export type ESCaseAttributes = Omit<CaseAttributes, 'connector'> & { connector:
export type ESCasePatchRequest = Omit<CasePatchRequest, 'connector'> & {
connector?: ESCaseConnector;
};
export type AllTagsFindRequest = rt.TypeOf<typeof AllTagsFindRequestRt>;
export type AllReportersFindRequest = AllTagsFindRequest;

View file

@ -6,6 +6,7 @@
*/
import * as rt from 'io-ts';
import { SavedObjectFindOptionsRt } from '../saved_object';
import { UserRT } from '../user';
@ -42,6 +43,7 @@ export const CommentAttributesBasicRt = rt.type({
]),
created_at: rt.string,
created_by: UserRT,
owner: rt.string,
pushed_at: rt.union([rt.string, rt.null]),
pushed_by: rt.union([UserRT, rt.null]),
updated_at: rt.union([rt.string, rt.null]),
@ -57,6 +59,7 @@ export enum CommentType {
export const ContextTypeUserRt = rt.type({
comment: rt.string,
type: rt.literal(CommentType.user),
owner: rt.string,
});
/**
@ -72,6 +75,7 @@ export const AlertCommentRequestRt = rt.type({
id: rt.union([rt.string, rt.null]),
name: rt.union([rt.string, rt.null]),
}),
owner: rt.string,
});
const AttributesTypeUserRt = rt.intersection([ContextTypeUserRt, CommentAttributesBasicRt]);
@ -127,7 +131,17 @@ export const CommentsResponseRt = rt.type({
export const AllCommentsResponseRt = rt.array(CommentResponseRt);
export const FindQueryParamsRt = rt.partial({
...SavedObjectFindOptionsRt.props,
/**
* If specified the attachments found will be associated to a sub case instead of a case object
*/
subCaseId: rt.string,
});
export type FindQueryParams = rt.TypeOf<typeof FindQueryParamsRt>;
export type AttributesTypeAlerts = rt.TypeOf<typeof AttributesTypeAlertsRt>;
export type AttributesTypeUser = rt.TypeOf<typeof AttributesTypeUserRt>;
export type CommentAttributes = rt.TypeOf<typeof CommentAttributesRt>;
export type CommentRequest = rt.TypeOf<typeof CommentRequestRt>;
export type CommentResponse = rt.TypeOf<typeof CommentResponseRt>;

View file

@ -9,18 +9,34 @@ import * as rt from 'io-ts';
import { UserRT } from '../user';
import { CaseConnectorRt, ConnectorMappingsRt, ESCaseConnector } from '../connectors';
import { OmitProp } from '../runtime_types';
import { OWNER_FIELD } from './constants';
// TODO: we will need to add this type rt.literal('close-by-third-party')
const ClosureTypeRT = rt.union([rt.literal('close-by-user'), rt.literal('close-by-pushing')]);
const CasesConfigureBasicRt = rt.type({
/**
* The external connector
*/
connector: CaseConnectorRt,
/**
* Whether to close the case after it has been synced with the external system
*/
closure_type: ClosureTypeRT,
/**
* The plugin owner that manages this configuration
*/
owner: rt.string,
});
const CasesConfigureBasicWithoutOwnerRt = rt.type(
OmitProp(CasesConfigureBasicRt.props, OWNER_FIELD)
);
export const CasesConfigureRequestRt = CasesConfigureBasicRt;
export const CasesConfigurePatchRt = rt.intersection([
rt.partial(CasesConfigureBasicRt.props),
rt.partial(CasesConfigureBasicWithoutOwnerRt.props),
rt.type({ version: rt.string }),
]);
@ -38,18 +54,37 @@ export const CaseConfigureResponseRt = rt.intersection([
CaseConfigureAttributesRt,
ConnectorMappingsRt,
rt.type({
id: rt.string,
version: rt.string,
error: rt.union([rt.string, rt.null]),
owner: rt.string,
}),
]);
export const GetConfigureFindRequestRt = rt.partial({
/**
* The configuration plugin owner to filter the search by. If this is left empty the results will include all configurations
* that the user has permissions to access
*/
owner: rt.union([rt.array(rt.string), rt.string]),
});
export const CaseConfigureRequestParamsRt = rt.type({
configuration_id: rt.string,
});
export const CaseConfigurationsResponseRt = rt.array(CaseConfigureResponseRt);
export type ClosureType = rt.TypeOf<typeof ClosureTypeRT>;
export type CasesConfigure = rt.TypeOf<typeof CasesConfigureBasicRt>;
export type CasesConfigureRequest = rt.TypeOf<typeof CasesConfigureRequestRt>;
export type CasesConfigurePatch = rt.TypeOf<typeof CasesConfigurePatchRt>;
export type CasesConfigureAttributes = rt.TypeOf<typeof CaseConfigureAttributesRt>;
export type CasesConfigureResponse = rt.TypeOf<typeof CaseConfigureResponseRt>;
export type CasesConfigurationsResponse = rt.TypeOf<typeof CaseConfigurationsResponseRt>;
export type ESCasesConfigureAttributes = Omit<CasesConfigureAttributes, 'connector'> & {
connector: ESCaseConnector;
};
export type GetConfigureFindRequest = rt.TypeOf<typeof GetConfigureFindRequestRt>;

View file

@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
/**
* This field is used for authorization of the entities within the cases plugin. Each entity within Cases will have the owner field
* set to a string that represents the plugin that "owns" (i.e. the plugin that originally issued the POST request to
* create the entity) the entity.
*
* The Authorization class constructs a string composed of the operation being performed (createCase, getComment, etc),
* and the owner of the entity being acted upon or created. This string is then given to the Security plugin which
* checks to see if the user making the request has that particular string stored within it's privileges. If it does,
* then the operation succeeds, otherwise the operation fails.
*
* APIs that create/update an entity require that the owner field be passed in the body of the request.
* APIs that search for entities typically require that the owner be passed as a query parameter.
* APIs that specify an ID of an entity directly generally don't need to specify the owner field.
*
* For APIs that create/update an entity, the RBAC implementation checks to see if the user making the request has the
* correct privileges for performing that action (a create/update) for the specified owner.
* This check is done through the Security plugin's API.
*
* For APIs that search for entities, the RBAC implementation creates a filter for the saved objects query that limits
* the search to only owners that the user has access to. We also check that the objects returned by the saved objects
* API have the limited owner scope. If we find one that the user does not have permissions for, we throw a 403 error.
* The owner field that is passed in as a query parameter can be used to further limit the results. If a user attempts
* to pass an owner that they do not have access to, the owner is ignored.
*
* For APIs that retrieve/delete entities directly using their ID, the RBAC implementation requests the object first,
* and then checks to see if the user making the request has access to that operation and owner. If the user does, the
* operation continues, otherwise we throw a 403.
*/
export const OWNER_FIELD = 'owner';

View file

@ -11,3 +11,4 @@ export * from './comment';
export * from './status';
export * from './user_actions';
export * from './sub_case';
export * from './constants';

View file

@ -27,4 +27,13 @@ export const CasesStatusResponseRt = rt.type({
count_closed_cases: rt.number,
});
export const CasesStatusRequestRt = rt.partial({
/**
* The owner of the cases to retrieve the status stats from. If no owner is provided the stats for all cases
* that the user has access to will be returned.
*/
owner: rt.union([rt.array(rt.string), rt.string]),
});
export type CasesStatusResponse = rt.TypeOf<typeof CasesStatusResponseRt>;
export type CasesStatusRequest = rt.TypeOf<typeof CasesStatusRequestRt>;

View file

@ -14,6 +14,9 @@ import { CasesStatusResponseRt } from './status';
import { CaseStatusRt } from './status';
const SubCaseBasicRt = rt.type({
/**
* The status of the sub case (open, closed, in-progress)
*/
status: CaseStatusRt,
});
@ -26,19 +29,48 @@ export const SubCaseAttributesRt = rt.intersection([
created_by: rt.union([UserRT, rt.null]),
updated_at: rt.union([rt.string, rt.null]),
updated_by: rt.union([UserRT, rt.null]),
owner: rt.string,
}),
]);
export const SubCasesFindRequestRt = rt.partial({
/**
* The status of the sub case (open, closed, in-progress)
*/
status: CaseStatusRt,
/**
* Operator to use for the `search` field
*/
defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
/**
* The fields in the entity to return in the response
*/
fields: rt.array(rt.string),
/**
* The page of objects to return
*/
page: NumberFromString,
/**
* The number of objects to include in each page
*/
perPage: NumberFromString,
/**
* An Elasticsearch simple_query_string
*/
search: rt.string,
/**
* The fields to perform the simple_query_string parsed query against
*/
searchFields: rt.array(rt.string),
/**
* The field to use for sorting the found objects.
*/
sortField: rt.string,
/**
* The order to sort by
*/
sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]),
owner: rt.string,
});
export const SubCaseResponseRt = rt.intersection([
@ -78,3 +110,4 @@ export type SubCasesResponse = rt.TypeOf<typeof SubCasesResponseRt>;
export type SubCasesFindResponse = rt.TypeOf<typeof SubCasesFindResponseRt>;
export type SubCasePatchRequest = rt.TypeOf<typeof SubCasePatchRequestRt>;
export type SubCasesPatchRequest = rt.TypeOf<typeof SubCasesPatchRequestRt>;
export type SubCasesFindRequest = rt.TypeOf<typeof SubCasesFindRequestRt>;

View file

@ -6,6 +6,7 @@
*/
import * as rt from 'io-ts';
import { OWNER_FIELD } from './constants';
import { UserRT } from '../user';
@ -22,6 +23,7 @@ const UserActionFieldTypeRt = rt.union([
rt.literal('status'),
rt.literal('settings'),
rt.literal('sub_case'),
rt.literal(OWNER_FIELD),
]);
const UserActionFieldRt = rt.array(UserActionFieldTypeRt);
const UserActionRt = rt.union([
@ -40,6 +42,7 @@ const CaseUserActionBasicRT = rt.type({
action_by: UserRT,
new_value: rt.union([rt.string, rt.null]),
old_value: rt.union([rt.string, rt.null]),
owner: rt.string,
});
const CaseUserActionResponseRT = rt.intersection([
@ -58,6 +61,7 @@ export const CaseUserActionsResponseRt = rt.array(CaseUserActionResponseRT);
export type CaseUserActionAttributes = rt.TypeOf<typeof CaseUserActionAttributesRt>;
export type CaseUserActionsResponse = rt.TypeOf<typeof CaseUserActionsResponseRt>;
export type CaseUserActionResponse = rt.TypeOf<typeof CaseUserActionResponseRT>;
export type UserAction = rt.TypeOf<typeof UserActionRt>;
export type UserActionField = rt.TypeOf<typeof UserActionFieldRt>;

View file

@ -31,6 +31,7 @@ export const ConnectorMappingsAttributesRT = rt.type({
export const ConnectorMappingsRt = rt.type({
mappings: rt.array(ConnectorMappingsAttributesRT),
owner: rt.string,
});
export type ConnectorMappingsAttributes = rt.TypeOf<typeof ConnectorMappingsAttributesRT>;

View file

@ -14,6 +14,7 @@ import {
SUB_CASES_URL,
CASE_PUSH_URL,
SUB_CASE_USER_ACTIONS_URL,
CASE_CONFIGURE_DETAILS_URL,
CASE_ALERTS_URL,
} from '../constants';
@ -49,6 +50,10 @@ export const getCasePushUrl = (caseId: string, connectorId: string): string => {
return CASE_PUSH_URL.replace('{case_id}', caseId).replace('{connector_id}', connectorId);
};
export const getCaseConfigurationDetailsUrl = (configureID: string): string => {
return CASE_CONFIGURE_DETAILS_URL.replace('{configuration_id}', configureID);
};
export const getCasesFromAlertsUrl = (alertId: string): string => {
return CASE_ALERTS_URL.replace('{alert_id}', alertId);
};

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import { omit } from 'lodash';
import { either, fold } from 'fp-ts/lib/Either';
import { identity } from 'fp-ts/lib/function';
import { pipe } from 'fp-ts/lib/pipeable';
@ -13,6 +14,9 @@ import { isObject } from 'lodash/fp';
type ErrorFactory = (message: string) => Error;
export const OmitProp = <O extends rt.Props, K extends keyof O>(o: O, k: K): Omit<O, K> =>
omit(o, k);
/**
* @deprecated Use packages/kbn-securitysolution-io-ts-utils/src/format_errors/index.ts
* Bug fix for the TODO is in the format_errors package
@ -68,7 +72,9 @@ const getExcessProps = (props: rt.Props, r: Record<string, unknown>): string[] =
return ex;
};
export function excess<C extends rt.InterfaceType<rt.Props>>(codec: C): C {
export function excess<C extends rt.InterfaceType<rt.Props> | rt.PartialType<rt.Props>>(
codec: C
): C {
const r = new rt.InterfaceType(
codec.name,
codec.is,

View file

@ -23,16 +23,49 @@ export const NumberFromString = new rt.Type<number, string, unknown>(
const ReferenceRt = rt.type({ id: rt.string, type: rt.string });
export const SavedObjectFindOptionsRt = rt.partial({
/**
* The default operator to use for the simple_query_string
*/
defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
/**
* The operator for controlling the logic of the `hasReference` field
*/
hasReferenceOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
/**
* Filter by objects that have an association to another object
*/
hasReference: rt.union([rt.array(ReferenceRt), ReferenceRt]),
/**
* The fields to return in the attributes key of the response
*/
fields: rt.array(rt.string),
/**
* The filter is a KQL string with the caveat that if you filter with an attribute from your saved object type, it should look like that: savedObjectType.attributes.title: "myTitle". However, If you use a root attribute of a saved object such as updated_at, you will have to define your filter like that: savedObjectType.updated_at > 2018-12-22
*/
filter: rt.string,
/**
* The page of objects to return
*/
page: NumberFromString,
/**
* The number of objects to return for a page
*/
perPage: NumberFromString,
/**
* An Elasticsearch simple_query_string query that filters the objects in the response
*/
search: rt.string,
/**
* The fields to perform the simple_query_string parsed query against
*/
searchFields: rt.array(rt.string),
/**
* Sorts the response. Includes "root" and "type" fields. "root" fields exist for all saved objects, such as "updated_at". "type" fields are specific to an object type, such as fields returned in the attributes key of the response. When a single type is defined in the type parameter, the "root" and "type" fields are allowed, and validity checks are made in that order. When multiple types are defined in the type parameter, only "root" fields are allowed
*/
sortField: rt.string,
/**
* Order to sort the response
*/
sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]),
});

View file

@ -9,6 +9,24 @@ export const DEFAULT_DATE_FORMAT_TZ = 'dateFormat:tz';
export const APP_ID = 'cases';
export const CASE_SAVED_OBJECT = 'cases';
export const CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT = 'cases-connector-mappings';
export const SUB_CASE_SAVED_OBJECT = 'cases-sub-case';
export const CASE_USER_ACTION_SAVED_OBJECT = 'cases-user-actions';
export const CASE_COMMENT_SAVED_OBJECT = 'cases-comments';
export const CASE_CONFIGURE_SAVED_OBJECT = 'cases-configure';
/**
* If more values are added here please also add them here: x-pack/test/case_api_integration/common/fixtures/plugins
*/
export const SAVED_OBJECT_TYPES = [
CASE_SAVED_OBJECT,
CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT,
CASE_USER_ACTION_SAVED_OBJECT,
CASE_COMMENT_SAVED_OBJECT,
CASE_CONFIGURE_SAVED_OBJECT,
];
/**
* Case routes
*/
@ -16,6 +34,7 @@ export const APP_ID = 'cases';
export const CASES_URL = '/api/cases';
export const CASE_DETAILS_URL = `${CASES_URL}/{case_id}`;
export const CASE_CONFIGURE_URL = `${CASES_URL}/configure`;
export const CASE_CONFIGURE_DETAILS_URL = `${CASES_URL}/configure/{configuration_id}`;
export const CASE_CONFIGURE_CONNECTORS_URL = `${CASE_CONFIGURE_URL}/connectors`;
export const SUB_CASES_PATCH_DEL_URL = `${CASES_URL}/sub_cases`;
@ -57,7 +76,19 @@ export const SUPPORTED_CONNECTORS = [
export const MAX_ALERTS_PER_SUB_CASE = 5000;
export const MAX_GENERATED_ALERTS_PER_SUB_CASE = 50;
/**
* This must be the same value that the security solution plugin uses to define the case kind when it registers the
* feature for the 7.13 migration only.
*
* This variable is being also used by test files and mocks.
*/
export const SECURITY_SOLUTION_OWNER = 'securitySolution';
/**
* This flag governs enabling the case as a connector feature. It is disabled by default as the feature is not complete.
*/
export const ENABLE_CASE_CONNECTOR = false;
if (ENABLE_CASE_CONNECTOR) {
SAVED_OBJECT_TYPES.push(SUB_CASE_SAVED_OBJECT);
}

View file

@ -58,6 +58,7 @@ export interface CaseExternalService {
interface BasicCase {
id: string;
owner: string;
closedAt: string | null;
closedBy: ElasticUser | null;
comments: Comment[];
@ -129,7 +130,7 @@ export interface ElasticUser {
export interface FetchCasesProps extends ApiProps {
queryParams?: QueryParams;
filterOptions?: FilterOptions;
filterOptions?: FilterOptions & { owner: string[] };
}
export interface ApiProps {

View file

@ -0,0 +1,37 @@
# Cases Client API Docs
This directory contains generated docs using `typedoc` for the cases client API that can be called from other server
plugins. This README will describe how to generate a new version of these markdown docs in the event that new methods
or parameters are added.
## TypeDoc Info
See more info at: <https://typedoc.org/>
and: <https://www.npmjs.com/package/typedoc-plugin-markdown> for the markdown plugin
## Install dependencies
```bash
yarn global add typedoc typedoc-plugin-markdown
```
## Generate the docs
```bash
cd x-pack/plugins/cases/docs
npx typedoc --options cases_client_typedoc.json
```
After running the above commands the files in the `server` directory will be updated to match the new tsdocs.
If additional markdown directory should be created we can create a new typedoc configuration file and adjust the `out`
directory accordingly.
## Troubleshooting
If you run into tsc errors that seem unrelated to the cases plugin try executing these commands before running `typedoc`
```bash
cd <kibana root dir>
npx yarn kbn bootstrap
node scripts/build_ts_refs.js --clean --no-cache
```

View file

@ -0,0 +1,22 @@
Cases Client API Interface
# Cases Client API Interface
## Table of contents
### Modules
- [attachments/add](modules/attachments_add.md)
- [attachments/client](modules/attachments_client.md)
- [attachments/delete](modules/attachments_delete.md)
- [attachments/get](modules/attachments_get.md)
- [attachments/update](modules/attachments_update.md)
- [cases/client](modules/cases_client.md)
- [cases/get](modules/cases_get.md)
- [cases/push](modules/cases_push.md)
- [client](modules/client.md)
- [configure/client](modules/configure_client.md)
- [stats/client](modules/stats_client.md)
- [sub\_cases/client](modules/sub_cases_client.md)
- [typedoc\_interfaces](modules/typedoc_interfaces.md)
- [user\_actions/client](modules/user_actions_client.md)

View file

@ -0,0 +1,178 @@
[Cases Client API Interface](../cases_client_api.md) / [client](../modules/client.md) / CasesClient
# Class: CasesClient
[client](../modules/client.md).CasesClient
Client wrapper that contains accessor methods for individual entities within the cases system.
## Table of contents
### Constructors
- [constructor](client.casesclient.md#constructor)
### Properties
- [\_attachments](client.casesclient.md#_attachments)
- [\_cases](client.casesclient.md#_cases)
- [\_casesClientInternal](client.casesclient.md#_casesclientinternal)
- [\_configure](client.casesclient.md#_configure)
- [\_stats](client.casesclient.md#_stats)
- [\_subCases](client.casesclient.md#_subcases)
- [\_userActions](client.casesclient.md#_useractions)
### Accessors
- [attachments](client.casesclient.md#attachments)
- [cases](client.casesclient.md#cases)
- [configure](client.casesclient.md#configure)
- [stats](client.casesclient.md#stats)
- [subCases](client.casesclient.md#subcases)
- [userActions](client.casesclient.md#useractions)
## Constructors
### constructor
\+ **new CasesClient**(`args`: CasesClientArgs): [*CasesClient*](client.casesclient.md)
#### Parameters
| Name | Type |
| :------ | :------ |
| `args` | CasesClientArgs |
**Returns:** [*CasesClient*](client.casesclient.md)
Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L28)
## Properties
### \_attachments
`Private` `Readonly` **\_attachments**: [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
Defined in: [client.ts:24](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L24)
___
### \_cases
`Private` `Readonly` **\_cases**: [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
Defined in: [client.ts:23](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L23)
___
### \_casesClientInternal
`Private` `Readonly` **\_casesClientInternal**: *CasesClientInternal*
Defined in: [client.ts:22](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L22)
___
### \_configure
`Private` `Readonly` **\_configure**: [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
Defined in: [client.ts:27](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L27)
___
### \_stats
`Private` `Readonly` **\_stats**: [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L28)
___
### \_subCases
`Private` `Readonly` **\_subCases**: [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
Defined in: [client.ts:26](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L26)
___
### \_userActions
`Private` `Readonly` **\_userActions**: [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
Defined in: [client.ts:25](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L25)
## Accessors
### attachments
• get **attachments**(): [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
Retrieves an interface for interacting with attachments (comments) entities.
**Returns:** [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
Defined in: [client.ts:50](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L50)
___
### cases
• get **cases**(): [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
Retrieves an interface for interacting with cases entities.
**Returns:** [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
Defined in: [client.ts:43](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L43)
___
### configure
• get **configure**(): [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
Retrieves an interface for interacting with the configuration of external connectors for the plugin entities.
**Returns:** [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
Defined in: [client.ts:76](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L76)
___
### stats
• get **stats**(): [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
Retrieves an interface for retrieving statistics related to the cases entities.
**Returns:** [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
Defined in: [client.ts:83](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L83)
___
### subCases
• get **subCases**(): [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
Retrieves an interface for interacting with the case as a connector entities.
Currently this functionality is disabled and will throw an error if this function is called.
**Returns:** [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
Defined in: [client.ts:66](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L66)
___
### userActions
• get **userActions**(): [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
Retrieves an interface for interacting with the user actions associated with the plugin entities.
**Returns:** [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
Defined in: [client.ts:57](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L57)

View file

@ -0,0 +1,34 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/add](../modules/attachments_add.md) / AddArgs
# Interface: AddArgs
[attachments/add](../modules/attachments_add.md).AddArgs
The arguments needed for creating a new attachment to a case.
## Table of contents
### Properties
- [caseId](attachments_add.addargs.md#caseid)
- [comment](attachments_add.addargs.md#comment)
## Properties
### caseId
**caseId**: *string*
The case ID that this attachment will be associated with
Defined in: [attachments/add.ts:308](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/add.ts#L308)
___
### comment
**comment**: { `comment`: *string* ; `owner`: *string* ; `type`: user } \| { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert }
The attachment values.
Defined in: [attachments/add.ts:312](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/add.ts#L312)

View file

@ -0,0 +1,147 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/client](../modules/attachments_client.md) / AttachmentsSubClient
# Interface: AttachmentsSubClient
[attachments/client](../modules/attachments_client.md).AttachmentsSubClient
API for interacting with the attachments to a case.
## Table of contents
### Methods
- [add](attachments_client.attachmentssubclient.md#add)
- [delete](attachments_client.attachmentssubclient.md#delete)
- [deleteAll](attachments_client.attachmentssubclient.md#deleteall)
- [find](attachments_client.attachmentssubclient.md#find)
- [get](attachments_client.attachmentssubclient.md#get)
- [getAll](attachments_client.attachmentssubclient.md#getall)
- [update](attachments_client.attachmentssubclient.md#update)
## Methods
### add
**add**(`params`: [*AddArgs*](attachments_add.addargs.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Adds an attachment to a case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | [*AddArgs*](attachments_add.addargs.md) |
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [attachments/client.ts:25](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L25)
___
### delete
**delete**(`deleteArgs`: [*DeleteArgs*](attachments_delete.deleteargs.md)): *Promise*<void\>
Deletes a single attachment for a specific case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `deleteArgs` | [*DeleteArgs*](attachments_delete.deleteargs.md) |
**Returns:** *Promise*<void\>
Defined in: [attachments/client.ts:33](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L33)
___
### deleteAll
**deleteAll**(`deleteAllArgs`: [*DeleteAllArgs*](attachments_delete.deleteallargs.md)): *Promise*<void\>
Deletes all attachments associated with a single case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `deleteAllArgs` | [*DeleteAllArgs*](attachments_delete.deleteallargs.md) |
**Returns:** *Promise*<void\>
Defined in: [attachments/client.ts:29](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L29)
___
### find
**find**(`findArgs`: [*FindArgs*](attachments_get.findargs.md)): *Promise*<[*ICommentsResponse*](typedoc_interfaces.icommentsresponse.md)\>
Retrieves all comments matching the search criteria.
#### Parameters
| Name | Type |
| :------ | :------ |
| `findArgs` | [*FindArgs*](attachments_get.findargs.md) |
**Returns:** *Promise*<[*ICommentsResponse*](typedoc_interfaces.icommentsresponse.md)\>
Defined in: [attachments/client.ts:37](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L37)
___
### get
**get**(`getArgs`: [*GetArgs*](attachments_get.getargs.md)): *Promise*<{ `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }\>
Retrieves a single attachment for a case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `getArgs` | [*GetArgs*](attachments_get.getargs.md) |
**Returns:** *Promise*<{ `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }\>
Defined in: [attachments/client.ts:45](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L45)
___
### getAll
**getAll**(`getAllArgs`: [*GetAllArgs*](attachments_get.getallargs.md)): *Promise*<[*IAllCommentsResponse*](typedoc_interfaces.iallcommentsresponse.md)\>
Gets all attachments for a single case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `getAllArgs` | [*GetAllArgs*](attachments_get.getallargs.md) |
**Returns:** *Promise*<[*IAllCommentsResponse*](typedoc_interfaces.iallcommentsresponse.md)\>
Defined in: [attachments/client.ts:41](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L41)
___
### update
**update**(`updateArgs`: [*UpdateArgs*](attachments_update.updateargs.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Updates a specific attachment.
The request must include all fields for the attachment. Even the fields that are not changing.
#### Parameters
| Name | Type |
| :------ | :------ |
| `updateArgs` | [*UpdateArgs*](attachments_update.updateargs.md) |
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [attachments/client.ts:51](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L51)

View file

@ -0,0 +1,34 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/delete](../modules/attachments_delete.md) / DeleteAllArgs
# Interface: DeleteAllArgs
[attachments/delete](../modules/attachments_delete.md).DeleteAllArgs
Parameters for deleting all comments of a case or sub case.
## Table of contents
### Properties
- [caseID](attachments_delete.deleteallargs.md#caseid)
- [subCaseID](attachments_delete.deleteallargs.md#subcaseid)
## Properties
### caseID
**caseID**: *string*
The case ID to delete all attachments for
Defined in: [attachments/delete.ts:26](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L26)
___
### subCaseID
`Optional` **subCaseID**: *string*
If specified the caseID will be ignored and this value will be used to find a sub case for deleting all the attachments
Defined in: [attachments/delete.ts:30](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L30)

View file

@ -0,0 +1,45 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/delete](../modules/attachments_delete.md) / DeleteArgs
# Interface: DeleteArgs
[attachments/delete](../modules/attachments_delete.md).DeleteArgs
Parameters for deleting a single attachment of a case or sub case.
## Table of contents
### Properties
- [attachmentID](attachments_delete.deleteargs.md#attachmentid)
- [caseID](attachments_delete.deleteargs.md#caseid)
- [subCaseID](attachments_delete.deleteargs.md#subcaseid)
## Properties
### attachmentID
**attachmentID**: *string*
The attachment ID to delete
Defined in: [attachments/delete.ts:44](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L44)
___
### caseID
**caseID**: *string*
The case ID to delete an attachment from
Defined in: [attachments/delete.ts:40](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L40)
___
### subCaseID
`Optional` **subCaseID**: *string*
If specified the caseID will be ignored and this value will be used to find a sub case for deleting the attachment
Defined in: [attachments/delete.ts:48](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L48)

View file

@ -0,0 +1,51 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/get](../modules/attachments_get.md) / FindArgs
# Interface: FindArgs
[attachments/get](../modules/attachments_get.md).FindArgs
Parameters for finding attachments of a case
## Table of contents
### Properties
- [caseID](attachments_get.findargs.md#caseid)
- [queryParams](attachments_get.findargs.md#queryparams)
## Properties
### caseID
**caseID**: *string*
The case ID for finding associated attachments
Defined in: [attachments/get.ts:48](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L48)
___
### queryParams
`Optional` **queryParams**: *object*
Optional parameters for filtering the returned attachments
#### Type declaration
| Name | Type |
| :------ | :------ |
| `defaultSearchOperator` | *undefined* \| ``"AND"`` \| ``"OR"`` |
| `fields` | *undefined* \| *string*[] |
| `filter` | *undefined* \| *string* |
| `hasReference` | *undefined* \| { `id`: *string* ; `type`: *string* } \| { `id`: *string* ; `type`: *string* }[] |
| `hasReferenceOperator` | *undefined* \| ``"AND"`` \| ``"OR"`` |
| `page` | *undefined* \| *number* |
| `perPage` | *undefined* \| *number* |
| `search` | *undefined* \| *string* |
| `searchFields` | *undefined* \| *string*[] |
| `sortField` | *undefined* \| *string* |
| `sortOrder` | *undefined* \| ``"desc"`` \| ``"asc"`` |
| `subCaseId` | *undefined* \| *string* |
Defined in: [attachments/get.ts:52](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L52)

View file

@ -0,0 +1,45 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/get](../modules/attachments_get.md) / GetAllArgs
# Interface: GetAllArgs
[attachments/get](../modules/attachments_get.md).GetAllArgs
Parameters for retrieving all attachments of a case
## Table of contents
### Properties
- [caseID](attachments_get.getallargs.md#caseid)
- [includeSubCaseComments](attachments_get.getallargs.md#includesubcasecomments)
- [subCaseID](attachments_get.getallargs.md#subcaseid)
## Properties
### caseID
**caseID**: *string*
The case ID to retrieve all attachments for
Defined in: [attachments/get.ts:62](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L62)
___
### includeSubCaseComments
`Optional` **includeSubCaseComments**: *boolean*
Optionally include the attachments associated with a sub case
Defined in: [attachments/get.ts:66](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L66)
___
### subCaseID
`Optional` **subCaseID**: *string*
If included the case ID will be ignored and the attachments will be retrieved from the specified ID of the sub case
Defined in: [attachments/get.ts:70](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L70)

View file

@ -0,0 +1,32 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/get](../modules/attachments_get.md) / GetArgs
# Interface: GetArgs
[attachments/get](../modules/attachments_get.md).GetArgs
## Table of contents
### Properties
- [attachmentID](attachments_get.getargs.md#attachmentid)
- [caseID](attachments_get.getargs.md#caseid)
## Properties
### attachmentID
**attachmentID**: *string*
The ID of the attachment to retrieve
Defined in: [attachments/get.ts:81](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L81)
___
### caseID
**caseID**: *string*
The ID of the case to retrieve an attachment from
Defined in: [attachments/get.ts:77](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L77)

View file

@ -0,0 +1,45 @@
[Cases Client API Interface](../cases_client_api.md) / [attachments/update](../modules/attachments_update.md) / UpdateArgs
# Interface: UpdateArgs
[attachments/update](../modules/attachments_update.md).UpdateArgs
Parameters for updating a single attachment
## Table of contents
### Properties
- [caseID](attachments_update.updateargs.md#caseid)
- [subCaseID](attachments_update.updateargs.md#subcaseid)
- [updateRequest](attachments_update.updateargs.md#updaterequest)
## Properties
### caseID
**caseID**: *string*
The ID of the case that is associated with this attachment
Defined in: [attachments/update.ts:29](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/update.ts#L29)
___
### subCaseID
`Optional` **subCaseID**: *string*
The ID of a sub case, if specified a sub case will be searched for to perform the attachment update instead of on a case
Defined in: [attachments/update.ts:37](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/update.ts#L37)
___
### updateRequest
**updateRequest**: { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `id`: *string* ; `version`: *string* }
The full attachment request with the fields updated with appropriate values
Defined in: [attachments/update.ts:33](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/update.ts#L33)

View file

@ -0,0 +1,189 @@
[Cases Client API Interface](../cases_client_api.md) / [cases/client](../modules/cases_client.md) / CasesSubClient
# Interface: CasesSubClient
[cases/client](../modules/cases_client.md).CasesSubClient
API for interacting with the cases entities.
## Table of contents
### Methods
- [create](cases_client.casessubclient.md#create)
- [delete](cases_client.casessubclient.md#delete)
- [find](cases_client.casessubclient.md#find)
- [get](cases_client.casessubclient.md#get)
- [getCaseIDsByAlertID](cases_client.casessubclient.md#getcaseidsbyalertid)
- [getReporters](cases_client.casessubclient.md#getreporters)
- [getTags](cases_client.casessubclient.md#gettags)
- [push](cases_client.casessubclient.md#push)
- [update](cases_client.casessubclient.md#update)
## Methods
### create
**create**(`data`: [*ICasePostRequest*](typedoc_interfaces.icasepostrequest.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Creates a case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `data` | [*ICasePostRequest*](typedoc_interfaces.icasepostrequest.md) |
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [cases/client.ts:48](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L48)
___
### delete
**delete**(`ids`: *string*[]): *Promise*<void\>
Delete a case and all its comments.
**`params`** ids an array of case IDs to delete
#### Parameters
| Name | Type |
| :------ | :------ |
| `ids` | *string*[] |
**Returns:** *Promise*<void\>
Defined in: [cases/client.ts:72](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L72)
___
### find
**find**(`params`: [*ICasesFindRequest*](typedoc_interfaces.icasesfindrequest.md)): *Promise*<[*ICasesFindResponse*](typedoc_interfaces.icasesfindresponse.md)\>
Returns cases that match the search criteria.
If the `owner` field is left empty then all the cases that the user has access to will be returned.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | [*ICasesFindRequest*](typedoc_interfaces.icasesfindrequest.md) |
**Returns:** *Promise*<[*ICasesFindResponse*](typedoc_interfaces.icasesfindresponse.md)\>
Defined in: [cases/client.ts:54](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L54)
___
### get
**get**(`params`: [*GetParams*](cases_get.getparams.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Retrieves a single case with the specified ID.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | [*GetParams*](cases_get.getparams.md) |
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [cases/client.ts:58](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L58)
___
### getCaseIDsByAlertID
**getCaseIDsByAlertID**(`params`: [*CaseIDsByAlertIDParams*](cases_get.caseidsbyalertidparams.md)): *Promise*<string[]\>
Retrieves the case IDs given a single alert ID
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | [*CaseIDsByAlertIDParams*](cases_get.caseidsbyalertidparams.md) |
**Returns:** *Promise*<string[]\>
Defined in: [cases/client.ts:84](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L84)
___
### getReporters
**getReporters**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*<{ `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }[]\>
Retrieves all the reporters across all accessible cases.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | *object* |
| `params.owner` | *undefined* \| *string* \| *string*[] |
**Returns:** *Promise*<{ `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }[]\>
Defined in: [cases/client.ts:80](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L80)
___
### getTags
**getTags**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*<string[]\>
Retrieves all the tags across all cases the user making the request has access to.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | *object* |
| `params.owner` | *undefined* \| *string* \| *string*[] |
**Returns:** *Promise*<string[]\>
Defined in: [cases/client.ts:76](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L76)
___
### push
**push**(`args`: [*PushParams*](cases_push.pushparams.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Pushes a specific case to an external system.
#### Parameters
| Name | Type |
| :------ | :------ |
| `args` | [*PushParams*](cases_push.pushparams.md) |
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [cases/client.ts:62](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L62)
___
### update
**update**(`cases`: [*ICasesPatchRequest*](typedoc_interfaces.icasespatchrequest.md)): *Promise*<[*ICasesResponse*](typedoc_interfaces.icasesresponse.md)\>
Update the specified cases with the passed in values.
#### Parameters
| Name | Type |
| :------ | :------ |
| `cases` | [*ICasesPatchRequest*](typedoc_interfaces.icasespatchrequest.md) |
**Returns:** *Promise*<[*ICasesResponse*](typedoc_interfaces.icasesresponse.md)\>
Defined in: [cases/client.ts:66](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L66)

View file

@ -0,0 +1,40 @@
[Cases Client API Interface](../cases_client_api.md) / [cases/get](../modules/cases_get.md) / CaseIDsByAlertIDParams
# Interface: CaseIDsByAlertIDParams
[cases/get](../modules/cases_get.md).CaseIDsByAlertIDParams
Parameters for finding cases IDs using an alert ID
## Table of contents
### Properties
- [alertID](cases_get.caseidsbyalertidparams.md#alertid)
- [options](cases_get.caseidsbyalertidparams.md#options)
## Properties
### alertID
**alertID**: *string*
The alert ID to search for
Defined in: [cases/get.ts:47](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L47)
___
### options
**options**: *object*
The filtering options when searching for associated cases.
#### Type declaration
| Name | Type |
| :------ | :------ |
| `owner` | *undefined* \| *string* \| *string*[] |
Defined in: [cases/get.ts:51](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L51)

View file

@ -0,0 +1,45 @@
[Cases Client API Interface](../cases_client_api.md) / [cases/get](../modules/cases_get.md) / GetParams
# Interface: GetParams
[cases/get](../modules/cases_get.md).GetParams
The parameters for retrieving a case
## Table of contents
### Properties
- [id](cases_get.getparams.md#id)
- [includeComments](cases_get.getparams.md#includecomments)
- [includeSubCaseComments](cases_get.getparams.md#includesubcasecomments)
## Properties
### id
**id**: *string*
Case ID
Defined in: [cases/get.ts:122](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L122)
___
### includeComments
`Optional` **includeComments**: *boolean*
Whether to include the attachments for a case in the response
Defined in: [cases/get.ts:126](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L126)
___
### includeSubCaseComments
`Optional` **includeSubCaseComments**: *boolean*
Whether to include the attachments for all children of a case in the response
Defined in: [cases/get.ts:130](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L130)

View file

@ -0,0 +1,34 @@
[Cases Client API Interface](../cases_client_api.md) / [cases/push](../modules/cases_push.md) / PushParams
# Interface: PushParams
[cases/push](../modules/cases_push.md).PushParams
Parameters for pushing a case to an external system
## Table of contents
### Properties
- [caseId](cases_push.pushparams.md#caseid)
- [connectorId](cases_push.pushparams.md#connectorid)
## Properties
### caseId
**caseId**: *string*
The ID of a case
Defined in: [cases/push.ts:53](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/push.ts#L53)
___
### connectorId
**connectorId**: *string*
The ID of an external system to push to
Defined in: [cases/push.ts:57](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/push.ts#L57)

View file

@ -0,0 +1,84 @@
[Cases Client API Interface](../cases_client_api.md) / [configure/client](../modules/configure_client.md) / ConfigureSubClient
# Interface: ConfigureSubClient
[configure/client](../modules/configure_client.md).ConfigureSubClient
This is the public API for interacting with the connector configuration for cases.
## Table of contents
### Methods
- [create](configure_client.configuresubclient.md#create)
- [get](configure_client.configuresubclient.md#get)
- [getConnectors](configure_client.configuresubclient.md#getconnectors)
- [update](configure_client.configuresubclient.md#update)
## Methods
### create
**create**(`configuration`: [*ICasesConfigureRequest*](typedoc_interfaces.icasesconfigurerequest.md)): *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Creates a configuration if one does not already exist. If one exists it is deleted and a new one is created.
#### Parameters
| Name | Type |
| :------ | :------ |
| `configuration` | [*ICasesConfigureRequest*](typedoc_interfaces.icasesconfigurerequest.md) |
**Returns:** *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Defined in: [configure/client.ts:102](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L102)
___
### get
**get**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*<{} \| [*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Retrieves the external connector configuration for a particular case owner.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | *object* |
| `params.owner` | *undefined* \| *string* \| *string*[] |
**Returns:** *Promise*<{} \| [*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Defined in: [configure/client.ts:84](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L84)
___
### getConnectors
**getConnectors**(): *Promise*<FindActionResult[]\>
Retrieves the valid external connectors supported by the cases plugin.
**Returns:** *Promise*<FindActionResult[]\>
Defined in: [configure/client.ts:88](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L88)
___
### update
**update**(`configurationId`: *string*, `configurations`: [*ICasesConfigurePatch*](typedoc_interfaces.icasesconfigurepatch.md)): *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Updates a particular configuration with new values.
#### Parameters
| Name | Type | Description |
| :------ | :------ | :------ |
| `configurationId` | *string* | the ID of the configuration to update |
| `configurations` | [*ICasesConfigurePatch*](typedoc_interfaces.icasesconfigurepatch.md) | the new configuration parameters |
**Returns:** *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Defined in: [configure/client.ts:95](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L95)

View file

@ -0,0 +1,32 @@
[Cases Client API Interface](../cases_client_api.md) / [stats/client](../modules/stats_client.md) / StatsSubClient
# Interface: StatsSubClient
[stats/client](../modules/stats_client.md).StatsSubClient
Statistics API contract.
## Table of contents
### Methods
- [getStatusTotalsByType](stats_client.statssubclient.md#getstatustotalsbytype)
## Methods
### getStatusTotalsByType
**getStatusTotalsByType**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*<{ `count_closed_cases`: *number* ; `count_in_progress_cases`: *number* ; `count_open_cases`: *number* }\>
Retrieves the total number of open, closed, and in-progress cases.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | *object* |
| `params.owner` | *undefined* \| *string* \| *string*[] |
**Returns:** *Promise*<{ `count_closed_cases`: *number* ; `count_in_progress_cases`: *number* ; `count_open_cases`: *number* }\>
Defined in: [stats/client.ts:34](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/stats/client.ts#L34)

View file

@ -0,0 +1,89 @@
[Cases Client API Interface](../cases_client_api.md) / [sub_cases/client](../modules/sub_cases_client.md) / SubCasesClient
# Interface: SubCasesClient
[sub_cases/client](../modules/sub_cases_client.md).SubCasesClient
The API routes for interacting with sub cases.
## Table of contents
### Methods
- [delete](sub_cases_client.subcasesclient.md#delete)
- [find](sub_cases_client.subcasesclient.md#find)
- [get](sub_cases_client.subcasesclient.md#get)
- [update](sub_cases_client.subcasesclient.md#update)
## Methods
### delete
**delete**(`ids`: *string*[]): *Promise*<void\>
Deletes the specified entities and their attachments.
#### Parameters
| Name | Type |
| :------ | :------ |
| `ids` | *string*[] |
**Returns:** *Promise*<void\>
Defined in: [sub_cases/client.ts:60](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L60)
___
### find
**find**(`findArgs`: FindArgs): *Promise*<[*ISubCasesFindResponse*](typedoc_interfaces.isubcasesfindresponse.md)\>
Retrieves the sub cases matching the search criteria.
#### Parameters
| Name | Type |
| :------ | :------ |
| `findArgs` | FindArgs |
**Returns:** *Promise*<[*ISubCasesFindResponse*](typedoc_interfaces.isubcasesfindresponse.md)\>
Defined in: [sub_cases/client.ts:64](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L64)
___
### get
**get**(`getArgs`: GetArgs): *Promise*<[*ISubCaseResponse*](typedoc_interfaces.isubcaseresponse.md)\>
Retrieves a single sub case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `getArgs` | GetArgs |
**Returns:** *Promise*<[*ISubCaseResponse*](typedoc_interfaces.isubcaseresponse.md)\>
Defined in: [sub_cases/client.ts:68](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L68)
___
### update
**update**(`subCases`: { `subCases`: { `status`: *undefined* \| open \| *any*[*any*] \| closed } & { id: string; version: string; }[] }): *Promise*<[*ISubCasesResponse*](typedoc_interfaces.isubcasesresponse.md)\>
Updates the specified sub cases to the new values included in the request.
#### Parameters
| Name | Type |
| :------ | :------ |
| `subCases` | *object* |
| `subCases.subCases` | { `status`: *undefined* \| open \| *any*[*any*] \| closed } & { id: string; version: string; }[] |
**Returns:** *Promise*<[*ISubCasesResponse*](typedoc_interfaces.isubcasesresponse.md)\>
Defined in: [sub_cases/client.ts:72](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L72)

View file

@ -0,0 +1,11 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / IAllCommentsResponse
# Interface: IAllCommentsResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).IAllCommentsResponse
## Hierarchy
- *AllCommentsResponse*
↳ **IAllCommentsResponse**

View file

@ -0,0 +1,88 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasePostRequest
# Interface: ICasePostRequest
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasePostRequest
These are simply to make typedoc not attempt to expand the type aliases. If it attempts to expand them
the docs are huge.
## Hierarchy
- *CasePostRequest*
↳ **ICasePostRequest**
## Table of contents
### Properties
- [connector](typedoc_interfaces.icasepostrequest.md#connector)
- [description](typedoc_interfaces.icasepostrequest.md#description)
- [owner](typedoc_interfaces.icasepostrequest.md#owner)
- [settings](typedoc_interfaces.icasepostrequest.md#settings)
- [tags](typedoc_interfaces.icasepostrequest.md#tags)
- [title](typedoc_interfaces.icasepostrequest.md#title)
- [type](typedoc_interfaces.icasepostrequest.md#type)
## Properties
### connector
**connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
Inherited from: CasePostRequest.connector
___
### description
**description**: *string*
Inherited from: CasePostRequest.description
___
### owner
**owner**: *string*
Inherited from: CasePostRequest.owner
___
### settings
**settings**: *object*
#### Type declaration
| Name | Type |
| :------ | :------ |
| `syncAlerts` | *boolean* |
Inherited from: CasePostRequest.settings
___
### tags
**tags**: *string*[]
Inherited from: CasePostRequest.tags
___
### title
**title**: *string*
Inherited from: CasePostRequest.title
___
### type
**type**: *undefined* \| collection \| individual
Inherited from: CasePostRequest.type

View file

@ -0,0 +1,228 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICaseResponse
# Interface: ICaseResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICaseResponse
## Hierarchy
- *CaseResponse*
↳ **ICaseResponse**
## Table of contents
### Properties
- [closed\_at](typedoc_interfaces.icaseresponse.md#closed_at)
- [closed\_by](typedoc_interfaces.icaseresponse.md#closed_by)
- [comments](typedoc_interfaces.icaseresponse.md#comments)
- [connector](typedoc_interfaces.icaseresponse.md#connector)
- [created\_at](typedoc_interfaces.icaseresponse.md#created_at)
- [created\_by](typedoc_interfaces.icaseresponse.md#created_by)
- [description](typedoc_interfaces.icaseresponse.md#description)
- [external\_service](typedoc_interfaces.icaseresponse.md#external_service)
- [id](typedoc_interfaces.icaseresponse.md#id)
- [owner](typedoc_interfaces.icaseresponse.md#owner)
- [settings](typedoc_interfaces.icaseresponse.md#settings)
- [status](typedoc_interfaces.icaseresponse.md#status)
- [subCaseIds](typedoc_interfaces.icaseresponse.md#subcaseids)
- [subCases](typedoc_interfaces.icaseresponse.md#subcases)
- [tags](typedoc_interfaces.icaseresponse.md#tags)
- [title](typedoc_interfaces.icaseresponse.md#title)
- [totalAlerts](typedoc_interfaces.icaseresponse.md#totalalerts)
- [totalComment](typedoc_interfaces.icaseresponse.md#totalcomment)
- [type](typedoc_interfaces.icaseresponse.md#type)
- [updated\_at](typedoc_interfaces.icaseresponse.md#updated_at)
- [updated\_by](typedoc_interfaces.icaseresponse.md#updated_by)
- [version](typedoc_interfaces.icaseresponse.md#version)
## Properties
### closed\_at
**closed\_at**: ``null`` \| *string*
Inherited from: CaseResponse.closed\_at
___
### closed\_by
**closed\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
Inherited from: CaseResponse.closed\_by
___
### comments
**comments**: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[]
Inherited from: CaseResponse.comments
___
### connector
**connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
Inherited from: CaseResponse.connector
___
### created\_at
**created\_at**: *string*
Inherited from: CaseResponse.created\_at
___
### created\_by
**created\_by**: *object*
#### Type declaration
| Name | Type |
| :------ | :------ |
| `email` | *undefined* \| ``null`` \| *string* |
| `full_name` | *undefined* \| ``null`` \| *string* |
| `username` | *undefined* \| ``null`` \| *string* |
Inherited from: CaseResponse.created\_by
___
### description
**description**: *string*
Inherited from: CaseResponse.description
___
### external\_service
**external\_service**: ``null`` \| { `connector_id`: *string* ; `connector_name`: *string* ; `external_id`: *string* ; `external_title`: *string* ; `external_url`: *string* } & { `pushed_at`: *string* ; `pushed_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } }
Inherited from: CaseResponse.external\_service
___
### id
**id**: *string*
Inherited from: CaseResponse.id
___
### owner
**owner**: *string*
Inherited from: CaseResponse.owner
___
### settings
**settings**: *object*
#### Type declaration
| Name | Type |
| :------ | :------ |
| `syncAlerts` | *boolean* |
Inherited from: CaseResponse.settings
___
### status
**status**: CaseStatuses
Inherited from: CaseResponse.status
___
### subCaseIds
**subCaseIds**: *undefined* \| *string*[]
Inherited from: CaseResponse.subCaseIds
___
### subCases
**subCases**: *undefined* \| { `status`: CaseStatuses } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { `comments`: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[] }[]
Inherited from: CaseResponse.subCases
___
### tags
**tags**: *string*[]
Inherited from: CaseResponse.tags
___
### title
**title**: *string*
Inherited from: CaseResponse.title
___
### totalAlerts
**totalAlerts**: *number*
Inherited from: CaseResponse.totalAlerts
___
### totalComment
**totalComment**: *number*
Inherited from: CaseResponse.totalComment
___
### type
**type**: CaseType
Inherited from: CaseResponse.type
___
### updated\_at
**updated\_at**: ``null`` \| *string*
Inherited from: CaseResponse.updated\_at
___
### updated\_by
**updated\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
Inherited from: CaseResponse.updated\_by
___
### version
**version**: *string*
Inherited from: CaseResponse.version

View file

@ -0,0 +1,43 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesConfigurePatch
# Interface: ICasesConfigurePatch
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesConfigurePatch
## Hierarchy
- *CasesConfigurePatch*
↳ **ICasesConfigurePatch**
## Table of contents
### Properties
- [closure\_type](typedoc_interfaces.icasesconfigurepatch.md#closure_type)
- [connector](typedoc_interfaces.icasesconfigurepatch.md#connector)
- [version](typedoc_interfaces.icasesconfigurepatch.md#version)
## Properties
### closure\_type
**closure\_type**: *undefined* \| ``"close-by-user"`` \| ``"close-by-pushing"``
Inherited from: CasesConfigurePatch.closure\_type
___
### connector
**connector**: *undefined* \| { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
Inherited from: CasesConfigurePatch.connector
___
### version
**version**: *string*
Inherited from: CasesConfigurePatch.version

View file

@ -0,0 +1,43 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesConfigureRequest
# Interface: ICasesConfigureRequest
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesConfigureRequest
## Hierarchy
- *CasesConfigureRequest*
↳ **ICasesConfigureRequest**
## Table of contents
### Properties
- [closure\_type](typedoc_interfaces.icasesconfigurerequest.md#closure_type)
- [connector](typedoc_interfaces.icasesconfigurerequest.md#connector)
- [owner](typedoc_interfaces.icasesconfigurerequest.md#owner)
## Properties
### closure\_type
**closure\_type**: ``"close-by-user"`` \| ``"close-by-pushing"``
Inherited from: CasesConfigureRequest.closure\_type
___
### connector
**connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
Inherited from: CasesConfigureRequest.connector
___
### owner
**owner**: *string*
Inherited from: CasesConfigureRequest.owner

View file

@ -0,0 +1,123 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesConfigureResponse
# Interface: ICasesConfigureResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesConfigureResponse
## Hierarchy
- *CasesConfigureResponse*
↳ **ICasesConfigureResponse**
## Table of contents
### Properties
- [closure\_type](typedoc_interfaces.icasesconfigureresponse.md#closure_type)
- [connector](typedoc_interfaces.icasesconfigureresponse.md#connector)
- [created\_at](typedoc_interfaces.icasesconfigureresponse.md#created_at)
- [created\_by](typedoc_interfaces.icasesconfigureresponse.md#created_by)
- [error](typedoc_interfaces.icasesconfigureresponse.md#error)
- [id](typedoc_interfaces.icasesconfigureresponse.md#id)
- [mappings](typedoc_interfaces.icasesconfigureresponse.md#mappings)
- [owner](typedoc_interfaces.icasesconfigureresponse.md#owner)
- [updated\_at](typedoc_interfaces.icasesconfigureresponse.md#updated_at)
- [updated\_by](typedoc_interfaces.icasesconfigureresponse.md#updated_by)
- [version](typedoc_interfaces.icasesconfigureresponse.md#version)
## Properties
### closure\_type
**closure\_type**: ``"close-by-user"`` \| ``"close-by-pushing"``
Inherited from: CasesConfigureResponse.closure\_type
___
### connector
**connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
Inherited from: CasesConfigureResponse.connector
___
### created\_at
**created\_at**: *string*
Inherited from: CasesConfigureResponse.created\_at
___
### created\_by
**created\_by**: *object*
#### Type declaration
| Name | Type |
| :------ | :------ |
| `email` | *undefined* \| ``null`` \| *string* |
| `full_name` | *undefined* \| ``null`` \| *string* |
| `username` | *undefined* \| ``null`` \| *string* |
Inherited from: CasesConfigureResponse.created\_by
___
### error
**error**: ``null`` \| *string*
Inherited from: CasesConfigureResponse.error
___
### id
**id**: *string*
Inherited from: CasesConfigureResponse.id
___
### mappings
**mappings**: { `action_type`: ``"append"`` \| ``"nothing"`` \| ``"overwrite"`` ; `source`: ``"description"`` \| ``"title"`` \| ``"comments"`` ; `target`: *string* }[]
Inherited from: CasesConfigureResponse.mappings
___
### owner
**owner**: *string*
Inherited from: CasesConfigureResponse.owner
___
### updated\_at
**updated\_at**: ``null`` \| *string*
Inherited from: CasesConfigureResponse.updated\_at
___
### updated\_by
**updated\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
Inherited from: CasesConfigureResponse.updated\_by
___
### version
**version**: *string*
Inherited from: CasesConfigureResponse.version

View file

@ -0,0 +1,133 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesFindRequest
# Interface: ICasesFindRequest
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesFindRequest
## Hierarchy
- *CasesFindRequest*
↳ **ICasesFindRequest**
## Table of contents
### Properties
- [defaultSearchOperator](typedoc_interfaces.icasesfindrequest.md#defaultsearchoperator)
- [fields](typedoc_interfaces.icasesfindrequest.md#fields)
- [owner](typedoc_interfaces.icasesfindrequest.md#owner)
- [page](typedoc_interfaces.icasesfindrequest.md#page)
- [perPage](typedoc_interfaces.icasesfindrequest.md#perpage)
- [reporters](typedoc_interfaces.icasesfindrequest.md#reporters)
- [search](typedoc_interfaces.icasesfindrequest.md#search)
- [searchFields](typedoc_interfaces.icasesfindrequest.md#searchfields)
- [sortField](typedoc_interfaces.icasesfindrequest.md#sortfield)
- [sortOrder](typedoc_interfaces.icasesfindrequest.md#sortorder)
- [status](typedoc_interfaces.icasesfindrequest.md#status)
- [tags](typedoc_interfaces.icasesfindrequest.md#tags)
- [type](typedoc_interfaces.icasesfindrequest.md#type)
## Properties
### defaultSearchOperator
**defaultSearchOperator**: *undefined* \| ``"AND"`` \| ``"OR"``
Inherited from: CasesFindRequest.defaultSearchOperator
___
### fields
**fields**: *undefined* \| *string*[]
Inherited from: CasesFindRequest.fields
___
### owner
**owner**: *undefined* \| *string* \| *string*[]
Inherited from: CasesFindRequest.owner
___
### page
**page**: *undefined* \| *number*
Inherited from: CasesFindRequest.page
___
### perPage
**perPage**: *undefined* \| *number*
Inherited from: CasesFindRequest.perPage
___
### reporters
**reporters**: *undefined* \| *string* \| *string*[]
Inherited from: CasesFindRequest.reporters
___
### search
**search**: *undefined* \| *string*
Inherited from: CasesFindRequest.search
___
### searchFields
**searchFields**: *undefined* \| *string* \| *string*[]
Inherited from: CasesFindRequest.searchFields
___
### sortField
**sortField**: *undefined* \| *string*
Inherited from: CasesFindRequest.sortField
___
### sortOrder
**sortOrder**: *undefined* \| ``"desc"`` \| ``"asc"``
Inherited from: CasesFindRequest.sortOrder
___
### status
**status**: *undefined* \| open \| *any*[*any*] \| closed
Inherited from: CasesFindRequest.status
___
### tags
**tags**: *undefined* \| *string* \| *string*[]
Inherited from: CasesFindRequest.tags
___
### type
**type**: *undefined* \| collection \| individual
Inherited from: CasesFindRequest.type

View file

@ -0,0 +1,79 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesFindResponse
# Interface: ICasesFindResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesFindResponse
## Hierarchy
- *CasesFindResponse*
↳ **ICasesFindResponse**
## Table of contents
### Properties
- [cases](typedoc_interfaces.icasesfindresponse.md#cases)
- [count\_closed\_cases](typedoc_interfaces.icasesfindresponse.md#count_closed_cases)
- [count\_in\_progress\_cases](typedoc_interfaces.icasesfindresponse.md#count_in_progress_cases)
- [count\_open\_cases](typedoc_interfaces.icasesfindresponse.md#count_open_cases)
- [page](typedoc_interfaces.icasesfindresponse.md#page)
- [per\_page](typedoc_interfaces.icasesfindresponse.md#per_page)
- [total](typedoc_interfaces.icasesfindresponse.md#total)
## Properties
### cases
**cases**: { `connector`: { id: string; name: string; } & { type: ConnectorTypes.jira; fields: { issueType: string \| null; priority: string \| null; parent: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.resilient; fields: { incidentTypes: string[] \| null; severityCode: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.serviceNowITSM; fields: { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.serviceNowSIR; fields: { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.none; fields: null; } ; `description`: *string* ; `owner`: *string* ; `settings`: { syncAlerts: boolean; } ; `status`: CaseStatuses ; `tags`: *string*[] ; `title`: *string* ; `type`: CaseType } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `external_service`: ``null`` \| { connector\_id: string; connector\_name: string; external\_id: string; external\_title: string; external\_url: string; } & { pushed\_at: string; pushed\_by: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; }; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { `comments`: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[] ; `subCaseIds`: *undefined* \| *string*[] ; `subCases`: *undefined* \| { `status`: CaseStatuses } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { comments?: ((({ comment: string; type: CommentType.user; owner: string; } & { associationType: AssociationType; created\_at: string; created\_by: { email: string \| null \| undefined; full\_name: string \| ... 1 more ... \| undefined; username: string \| ... 1 more ... \| undefined; }; ... 4 more ...; updated\_by: { ...; } ...[] }[]
Inherited from: CasesFindResponse.cases
___
### count\_closed\_cases
**count\_closed\_cases**: *number*
Inherited from: CasesFindResponse.count\_closed\_cases
___
### count\_in\_progress\_cases
**count\_in\_progress\_cases**: *number*
Inherited from: CasesFindResponse.count\_in\_progress\_cases
___
### count\_open\_cases
**count\_open\_cases**: *number*
Inherited from: CasesFindResponse.count\_open\_cases
___
### page
**page**: *number*
Inherited from: CasesFindResponse.page
___
### per\_page
**per\_page**: *number*
Inherited from: CasesFindResponse.per\_page
___
### total
**total**: *number*
Inherited from: CasesFindResponse.total

View file

@ -0,0 +1,25 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesPatchRequest
# Interface: ICasesPatchRequest
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesPatchRequest
## Hierarchy
- *CasesPatchRequest*
↳ **ICasesPatchRequest**
## Table of contents
### Properties
- [cases](typedoc_interfaces.icasespatchrequest.md#cases)
## Properties
### cases
**cases**: { `connector`: *undefined* \| { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none } ; `description`: *undefined* \| *string* ; `owner`: *undefined* \| *string* ; `settings`: *undefined* \| { `syncAlerts`: *boolean* } ; `status`: *undefined* \| open \| *any*[*any*] \| closed ; `tags`: *undefined* \| *string*[] ; `title`: *undefined* \| *string* ; `type`: *undefined* \| collection \| individual } & { `id`: *string* ; `version`: *string* }[]
Inherited from: CasesPatchRequest.cases

View file

@ -0,0 +1,11 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesResponse
# Interface: ICasesResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesResponse
## Hierarchy
- *CasesResponse*
↳ **ICasesResponse**

View file

@ -0,0 +1,11 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICaseUserActionsResponse
# Interface: ICaseUserActionsResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICaseUserActionsResponse
## Hierarchy
- *CaseUserActionsResponse*
↳ **ICaseUserActionsResponse**

View file

@ -0,0 +1,52 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICommentsResponse
# Interface: ICommentsResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ICommentsResponse
## Hierarchy
- *CommentsResponse*
↳ **ICommentsResponse**
## Table of contents
### Properties
- [comments](typedoc_interfaces.icommentsresponse.md#comments)
- [page](typedoc_interfaces.icommentsresponse.md#page)
- [per\_page](typedoc_interfaces.icommentsresponse.md#per_page)
- [total](typedoc_interfaces.icommentsresponse.md#total)
## Properties
### comments
**comments**: { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[]
Inherited from: CommentsResponse.comments
___
### page
**page**: *number*
Inherited from: CommentsResponse.page
___
### per\_page
**per\_page**: *number*
Inherited from: CommentsResponse.per\_page
___
### total
**total**: *number*
Inherited from: CommentsResponse.total

View file

@ -0,0 +1,133 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ISubCaseResponse
# Interface: ISubCaseResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ISubCaseResponse
## Hierarchy
- *SubCaseResponse*
↳ **ISubCaseResponse**
## Table of contents
### Properties
- [closed\_at](typedoc_interfaces.isubcaseresponse.md#closed_at)
- [closed\_by](typedoc_interfaces.isubcaseresponse.md#closed_by)
- [comments](typedoc_interfaces.isubcaseresponse.md#comments)
- [created\_at](typedoc_interfaces.isubcaseresponse.md#created_at)
- [created\_by](typedoc_interfaces.isubcaseresponse.md#created_by)
- [id](typedoc_interfaces.isubcaseresponse.md#id)
- [owner](typedoc_interfaces.isubcaseresponse.md#owner)
- [status](typedoc_interfaces.isubcaseresponse.md#status)
- [totalAlerts](typedoc_interfaces.isubcaseresponse.md#totalalerts)
- [totalComment](typedoc_interfaces.isubcaseresponse.md#totalcomment)
- [updated\_at](typedoc_interfaces.isubcaseresponse.md#updated_at)
- [updated\_by](typedoc_interfaces.isubcaseresponse.md#updated_by)
- [version](typedoc_interfaces.isubcaseresponse.md#version)
## Properties
### closed\_at
**closed\_at**: ``null`` \| *string*
Inherited from: SubCaseResponse.closed\_at
___
### closed\_by
**closed\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
Inherited from: SubCaseResponse.closed\_by
___
### comments
**comments**: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[]
Inherited from: SubCaseResponse.comments
___
### created\_at
**created\_at**: *string*
Inherited from: SubCaseResponse.created\_at
___
### created\_by
**created\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
Inherited from: SubCaseResponse.created\_by
___
### id
**id**: *string*
Inherited from: SubCaseResponse.id
___
### owner
**owner**: *string*
Inherited from: SubCaseResponse.owner
___
### status
**status**: CaseStatuses
Inherited from: SubCaseResponse.status
___
### totalAlerts
**totalAlerts**: *number*
Inherited from: SubCaseResponse.totalAlerts
___
### totalComment
**totalComment**: *number*
Inherited from: SubCaseResponse.totalComment
___
### updated\_at
**updated\_at**: ``null`` \| *string*
Inherited from: SubCaseResponse.updated\_at
___
### updated\_by
**updated\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
Inherited from: SubCaseResponse.updated\_by
___
### version
**version**: *string*
Inherited from: SubCaseResponse.version

View file

@ -0,0 +1,79 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ISubCasesFindResponse
# Interface: ISubCasesFindResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ISubCasesFindResponse
## Hierarchy
- *SubCasesFindResponse*
↳ **ISubCasesFindResponse**
## Table of contents
### Properties
- [count\_closed\_cases](typedoc_interfaces.isubcasesfindresponse.md#count_closed_cases)
- [count\_in\_progress\_cases](typedoc_interfaces.isubcasesfindresponse.md#count_in_progress_cases)
- [count\_open\_cases](typedoc_interfaces.isubcasesfindresponse.md#count_open_cases)
- [page](typedoc_interfaces.isubcasesfindresponse.md#page)
- [per\_page](typedoc_interfaces.isubcasesfindresponse.md#per_page)
- [subCases](typedoc_interfaces.isubcasesfindresponse.md#subcases)
- [total](typedoc_interfaces.isubcasesfindresponse.md#total)
## Properties
### count\_closed\_cases
**count\_closed\_cases**: *number*
Inherited from: SubCasesFindResponse.count\_closed\_cases
___
### count\_in\_progress\_cases
**count\_in\_progress\_cases**: *number*
Inherited from: SubCasesFindResponse.count\_in\_progress\_cases
___
### count\_open\_cases
**count\_open\_cases**: *number*
Inherited from: SubCasesFindResponse.count\_open\_cases
___
### page
**page**: *number*
Inherited from: SubCasesFindResponse.page
___
### per\_page
**per\_page**: *number*
Inherited from: SubCasesFindResponse.per\_page
___
### subCases
**subCases**: { `status`: CaseStatuses } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { `comments`: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[] }[]
Inherited from: SubCasesFindResponse.subCases
___
### total
**total**: *number*
Inherited from: SubCasesFindResponse.total

View file

@ -0,0 +1,11 @@
[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ISubCasesResponse
# Interface: ISubCasesResponse
[typedoc_interfaces](../modules/typedoc_interfaces.md).ISubCasesResponse
## Hierarchy
- *SubCasesResponse*
↳ **ISubCasesResponse**

View file

@ -0,0 +1,34 @@
[Cases Client API Interface](../cases_client_api.md) / [user_actions/client](../modules/user_actions_client.md) / UserActionGet
# Interface: UserActionGet
[user_actions/client](../modules/user_actions_client.md).UserActionGet
Parameters for retrieving user actions for a particular case
## Table of contents
### Properties
- [caseId](user_actions_client.useractionget.md#caseid)
- [subCaseId](user_actions_client.useractionget.md#subcaseid)
## Properties
### caseId
**caseId**: *string*
The ID of the case
Defined in: [user_actions/client.ts:19](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/user_actions/client.ts#L19)
___
### subCaseId
`Optional` **subCaseId**: *string*
If specified then a sub case will be used for finding all the user actions
Defined in: [user_actions/client.ts:23](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/user_actions/client.ts#L23)

View file

@ -0,0 +1,31 @@
[Cases Client API Interface](../cases_client_api.md) / [user_actions/client](../modules/user_actions_client.md) / UserActionsSubClient
# Interface: UserActionsSubClient
[user_actions/client](../modules/user_actions_client.md).UserActionsSubClient
API for interacting the actions performed by a user when interacting with the cases entities.
## Table of contents
### Methods
- [getAll](user_actions_client.useractionssubclient.md#getall)
## Methods
### getAll
**getAll**(`clientArgs`: [*UserActionGet*](user_actions_client.useractionget.md)): *Promise*<[*ICaseUserActionsResponse*](typedoc_interfaces.icaseuseractionsresponse.md)\>
Retrieves all user actions for a particular case.
#### Parameters
| Name | Type |
| :------ | :------ |
| `clientArgs` | [*UserActionGet*](user_actions_client.useractionget.md) |
**Returns:** *Promise*<[*ICaseUserActionsResponse*](typedoc_interfaces.icaseuseractionsresponse.md)\>
Defined in: [user_actions/client.ts:33](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/user_actions/client.ts#L33)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / attachments/add
# Module: attachments/add
## Table of contents
### Interfaces
- [AddArgs](../interfaces/attachments_add.addargs.md)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / attachments/client
# Module: attachments/client
## Table of contents
### Interfaces
- [AttachmentsSubClient](../interfaces/attachments_client.attachmentssubclient.md)

View file

@ -0,0 +1,10 @@
[Cases Client API Interface](../cases_client_api.md) / attachments/delete
# Module: attachments/delete
## Table of contents
### Interfaces
- [DeleteAllArgs](../interfaces/attachments_delete.deleteallargs.md)
- [DeleteArgs](../interfaces/attachments_delete.deleteargs.md)

View file

@ -0,0 +1,11 @@
[Cases Client API Interface](../cases_client_api.md) / attachments/get
# Module: attachments/get
## Table of contents
### Interfaces
- [FindArgs](../interfaces/attachments_get.findargs.md)
- [GetAllArgs](../interfaces/attachments_get.getallargs.md)
- [GetArgs](../interfaces/attachments_get.getargs.md)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / attachments/update
# Module: attachments/update
## Table of contents
### Interfaces
- [UpdateArgs](../interfaces/attachments_update.updateargs.md)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / cases/client
# Module: cases/client
## Table of contents
### Interfaces
- [CasesSubClient](../interfaces/cases_client.casessubclient.md)

View file

@ -0,0 +1,53 @@
[Cases Client API Interface](../cases_client_api.md) / cases/get
# Module: cases/get
## Table of contents
### Interfaces
- [CaseIDsByAlertIDParams](../interfaces/cases_get.caseidsbyalertidparams.md)
- [GetParams](../interfaces/cases_get.getparams.md)
### Functions
- [getReporters](cases_get.md#getreporters)
- [getTags](cases_get.md#gettags)
## Functions
### getReporters
**getReporters**(`params`: AllReportersFindRequest, `clientArgs`: CasesClientArgs): *Promise*<User[]\>
Retrieves the reporters from all the cases.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | AllReportersFindRequest |
| `clientArgs` | CasesClientArgs |
**Returns:** *Promise*<User[]\>
Defined in: [cases/get.ts:279](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L279)
___
### getTags
**getTags**(`params`: AllTagsFindRequest, `clientArgs`: CasesClientArgs): *Promise*<string[]\>
Retrieves the tags from all the cases.
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | AllTagsFindRequest |
| `clientArgs` | CasesClientArgs |
**Returns:** *Promise*<string[]\>
Defined in: [cases/get.ts:217](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L217)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / cases/push
# Module: cases/push
## Table of contents
### Interfaces
- [PushParams](../interfaces/cases_push.pushparams.md)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / client
# Module: client
## Table of contents
### Classes
- [CasesClient](../classes/client.casesclient.md)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / configure/client
# Module: configure/client
## Table of contents
### Interfaces
- [ConfigureSubClient](../interfaces/configure_client.configuresubclient.md)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / stats/client
# Module: stats/client
## Table of contents
### Interfaces
- [StatsSubClient](../interfaces/stats_client.statssubclient.md)

View file

@ -0,0 +1,9 @@
[Cases Client API Interface](../cases_client_api.md) / sub_cases/client
# Module: sub\_cases/client
## Table of contents
### Interfaces
- [SubCasesClient](../interfaces/sub_cases_client.subcasesclient.md)

View file

@ -0,0 +1,26 @@
[Cases Client API Interface](../cases_client_api.md) / typedoc_interfaces
# Module: typedoc\_interfaces
This file defines simpler types for typedoc. This helps reduce the type alias expansion for the io-ts types because it
can be very large. These types are equivalent to the io-ts aliases.
## Table of contents
### Interfaces
- [IAllCommentsResponse](../interfaces/typedoc_interfaces.iallcommentsresponse.md)
- [ICasePostRequest](../interfaces/typedoc_interfaces.icasepostrequest.md)
- [ICaseResponse](../interfaces/typedoc_interfaces.icaseresponse.md)
- [ICaseUserActionsResponse](../interfaces/typedoc_interfaces.icaseuseractionsresponse.md)
- [ICasesConfigurePatch](../interfaces/typedoc_interfaces.icasesconfigurepatch.md)
- [ICasesConfigureRequest](../interfaces/typedoc_interfaces.icasesconfigurerequest.md)
- [ICasesConfigureResponse](../interfaces/typedoc_interfaces.icasesconfigureresponse.md)
- [ICasesFindRequest](../interfaces/typedoc_interfaces.icasesfindrequest.md)
- [ICasesFindResponse](../interfaces/typedoc_interfaces.icasesfindresponse.md)
- [ICasesPatchRequest](../interfaces/typedoc_interfaces.icasespatchrequest.md)
- [ICasesResponse](../interfaces/typedoc_interfaces.icasesresponse.md)
- [ICommentsResponse](../interfaces/typedoc_interfaces.icommentsresponse.md)
- [ISubCaseResponse](../interfaces/typedoc_interfaces.isubcaseresponse.md)
- [ISubCasesFindResponse](../interfaces/typedoc_interfaces.isubcasesfindresponse.md)
- [ISubCasesResponse](../interfaces/typedoc_interfaces.isubcasesresponse.md)

View file

@ -0,0 +1,10 @@
[Cases Client API Interface](../cases_client_api.md) / user_actions/client
# Module: user\_actions/client
## Table of contents
### Interfaces
- [UserActionGet](../interfaces/user_actions_client.useractionget.md)
- [UserActionsSubClient](../interfaces/user_actions_client.useractionssubclient.md)

View file

@ -0,0 +1,25 @@
{
"entryPoints": [
"../server/client/client.ts",
"../server/client/typedoc_interfaces.ts",
"../server/client/attachments",
"../server/client/cases/client.ts",
"../server/client/cases/get.ts",
"../server/client/cases/push.ts",
"../server/client/configure/client.ts",
"../server/client/stats/client.ts",
"../server/client/sub_cases/client.ts",
"../server/client/user_actions/client.ts"
],
"exclude": [
"**/mock.ts",
"../server/client/cases/+(mock.ts|utils.ts|utils.test.ts|types.ts)"
],
"excludeExternals": true,
"out": "cases_client",
"theme": "markdown",
"plugin": "typedoc-plugin-markdown",
"entryDocument": "cases_client_api.md",
"readme": "none",
"name": "Cases Client API Interface"
}

View file

@ -3,7 +3,7 @@
"id": "cases",
"kibanaVersion": "kibana",
"extraPublicDirs": ["common"],
"requiredPlugins": ["actions", "esUiShared", "kibanaReact", "kibanaUtils", "triggersActionsUi"],
"requiredPlugins": ["actions", "esUiShared", "features", "kibanaReact", "kibanaUtils", "triggersActionsUi"],
"optionalPlugins": [
"spaces",
"security"

View file

@ -104,29 +104,3 @@ export const useCurrentUser = (): AuthenticatedElasticUser | null => {
}, [fetchUser]);
return user;
};
export interface UseGetUserSavedObjectPermissions {
crud: boolean;
read: boolean;
}
export const useGetUserSavedObjectPermissions = () => {
const [
savedObjectsPermissions,
setSavedObjectsPermissions,
] = useState<UseGetUserSavedObjectPermissions | null>(null);
const uiCapabilities = useKibana().services.application.capabilities;
useEffect(() => {
const capabilitiesCanUserCRUD: boolean =
typeof uiCapabilities.siem.crud === 'boolean' ? uiCapabilities.siem.crud : false;
const capabilitiesCanUserRead: boolean =
typeof uiCapabilities.siem.show === 'boolean' ? uiCapabilities.siem.show : false;
setSavedObjectsPermissions({
crud: capabilitiesCanUserCRUD,
read: capabilitiesCanUserRead,
});
}, [uiCapabilities]);
return savedObjectsPermissions;
};

View file

@ -10,6 +10,8 @@ import { I18nProvider } from '@kbn/i18n/react';
import React from 'react';
import { BehaviorSubject } from 'rxjs';
import { ThemeProvider } from 'styled-components';
import { SECURITY_SOLUTION_OWNER } from '../../../common';
import { OwnerProvider } from '../../components/owner_context';
import {
createKibanaContextProviderMock,
createStartServicesMock,
@ -29,7 +31,9 @@ const MockKibanaContextProvider = createKibanaContextProviderMock();
const TestProvidersComponent: React.FC<Props> = ({ children }) => (
<I18nProvider>
<MockKibanaContextProvider>
<ThemeProvider theme={() => ({ eui: euiDarkVars, darkMode: true })}>{children}</ThemeProvider>
<ThemeProvider theme={() => ({ eui: euiDarkVars, darkMode: true })}>
<OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}>{children}</OwnerProvider>
</ThemeProvider>
</MockKibanaContextProvider>
</I18nProvider>
);

View file

@ -7,18 +7,18 @@
import { i18n } from '@kbn/i18n';
export const SAVED_OBJECT_NO_PERMISSIONS_TITLE = i18n.translate(
'xpack.cases.caseSavedObjectNoPermissionsTitle',
export const CASES_FEATURE_NO_PERMISSIONS_TITLE = i18n.translate(
'xpack.cases.caseFeatureNoPermissionsTitle',
{
defaultMessage: 'Kibana feature privileges required',
}
);
export const SAVED_OBJECT_NO_PERMISSIONS_MSG = i18n.translate(
'xpack.cases.caseSavedObjectNoPermissionsMessage',
export const CASES_FEATURE_NO_PERMISSIONS_MSG = i18n.translate(
'xpack.cases.caseFeatureNoPermissionsMessage',
{
defaultMessage:
'To view cases, you must have privileges for the Saved Object Management feature in the Kibana space. For more information, contact your Kibana administrator.',
'To view cases, you must have privileges for the Cases feature in the Kibana space. For more information, contact your Kibana administrator.',
}
);

View file

@ -13,7 +13,7 @@ import { noop } from 'lodash/fp';
import { TestProviders } from '../../common/mock';
import { Router, routeData, mockHistory, mockLocation } from '../__mock__/router';
import { CommentRequest, CommentType } from '../../../common';
import { CommentRequest, CommentType, SECURITY_SOLUTION_OWNER } from '../../../common';
import { usePostComment } from '../../containers/use_post_comment';
import { AddComment, AddCommentRefObject } from '.';
import { CasesTimelineIntegrationProvider } from '../timeline_context';
@ -44,6 +44,7 @@ const defaultPostComment = {
const sampleData: CommentRequest = {
comment: 'what a cool comment',
type: CommentType.user,
owner: SECURITY_SOLUTION_OWNER,
};
describe('AddComment ', () => {

View file

@ -18,6 +18,7 @@ import { Form, useForm, UseField, useFormData } from '../../common/shared_import
import * as i18n from './translations';
import { schema, AddCommentFormSchema } from './schema';
import { InsertTimeline } from '../insert_timeline';
import { useOwnerContext } from '../owner_context/use_owner_context';
const MySpinner = styled(EuiLoadingSpinner)`
position: absolute;
top: 50%;
@ -47,6 +48,7 @@ export const AddComment = React.memo(
{ caseId, disabled, onCommentPosted, onCommentSaving, showLoading = true, subCaseId },
ref
) => {
const owner = useOwnerContext();
const { isLoading, postComment } = usePostComment();
const { form } = useForm<AddCommentFormSchema>({
@ -78,13 +80,13 @@ export const AddComment = React.memo(
}
postComment({
caseId,
data: { ...data, type: CommentType.user },
data: { ...data, type: CommentType.user, owner: owner[0] },
updateCase: onCommentPosted,
subCaseId,
});
reset();
}
}, [caseId, onCommentPosted, onCommentSaving, postComment, reset, submit, subCaseId]);
}, [submit, onCommentSaving, postComment, caseId, owner, onCommentPosted, subCaseId, reset]);
return (
<span id="add-comment-permLink">

View file

@ -14,7 +14,7 @@ import { useGetTags } from '../../containers/use_get_tags';
import { useGetReporters } from '../../containers/use_get_reporters';
import { useGetActionLicense } from '../../containers/use_get_action_license';
import { StatusAll } from '../../containers/types';
import { CaseStatuses } from '../../../common';
import { CaseStatuses, SECURITY_SOLUTION_OWNER } from '../../../common';
import { act } from 'react-dom/test-utils';
jest.mock('../../containers/use_get_reporters');
@ -32,6 +32,7 @@ const alertDataMock = {
},
index: 'index-id',
alertId: 'alert-id',
owner: SECURITY_SOLUTION_OWNER,
};
describe('AllCasesGeneric ', () => {

View file

@ -40,6 +40,7 @@ import { CasesTableFilters } from './table_filters';
import { EuiBasicTableOnChange } from './types';
import { CasesTable } from './table';
const ProgressLoader = styled(EuiProgress)`
${({ $isShow }: { $isShow: boolean }) =>
$isShow
@ -81,6 +82,7 @@ export const AllCasesGeneric = React.memo<AllCasesGenericProps>(
userCanCrud,
}) => {
const { actionLicense } = useGetActionLicense();
const firstAvailableStatus = head(difference(caseStatuses, hiddenStatuses));
const initialFilterOptions =
!isEmpty(hiddenStatuses) && firstAvailableStatus ? { status: firstAvailableStatus } : {};
@ -96,7 +98,7 @@ export const AllCasesGeneric = React.memo<AllCasesGenericProps>(
setFilters,
setQueryParams,
setSelectedCases,
} = useGetCases({}, initialFilterOptions);
} = useGetCases({ initialFilterOptions });
// Post Comment to Case
const { postComment, isLoading: isCommentUpdating } = usePostComment();

View file

@ -13,7 +13,7 @@ import '../../common/mock/match_media';
import { TestProviders } from '../../common/mock';
import { casesStatus, useGetCasesMockState, collectionCase } from '../../containers/mock';
import { CaseStatuses, CaseType, StatusAll } from '../../../common';
import { CaseStatuses, CaseType, SECURITY_SOLUTION_OWNER, StatusAll } from '../../../common';
import { getEmptyTagValue } from '../empty_value';
import { useDeleteCases } from '../../containers/use_delete_cases';
import { useGetCases } from '../../containers/use_get_cases';
@ -53,6 +53,7 @@ describe('AllCasesGeneric', () => {
onClick: jest.fn(),
},
userCanCrud: true,
owner: [SECURITY_SOLUTION_OWNER],
};
const dispatchResetIsDeleted = jest.fn();
@ -815,6 +816,7 @@ describe('AllCasesGeneric', () => {
},
},
id: '1',
owner: SECURITY_SOLUTION_OWNER,
status: 'open',
subCaseIds: [],
tags: ['coke', 'pepsi'],

View file

@ -6,9 +6,11 @@
*/
import React from 'react';
import { Owner } from '../../types';
import { CaseDetailsHrefSchema, CasesNavigation } from '../links';
import { OwnerProvider } from '../owner_context';
import { AllCasesGeneric } from './all_cases_generic';
export interface AllCasesProps {
export interface AllCasesProps extends Owner {
caseDetailsNavigation: CasesNavigation<CaseDetailsHrefSchema, 'configurable'>; // if not passed, case name is not displayed as a link (Formerly dependant on isSelector)
configureCasesNavigation: CasesNavigation; // if not passed, header with nav is not displayed (Formerly dependant on isSelector)
createCaseNavigation: CasesNavigation;
@ -16,7 +18,11 @@ export interface AllCasesProps {
}
export const AllCases: React.FC<AllCasesProps> = (props) => {
return <AllCasesGeneric {...props} />;
return (
<OwnerProvider owner={props.owner}>
<AllCasesGeneric {...props} />
</OwnerProvider>
);
};
// eslint-disable-next-line import/no-default-export

View file

@ -11,6 +11,7 @@ import { mount } from 'enzyme';
import { AllCasesSelectorModal } from '.';
import { TestProviders } from '../../../common/mock';
import { AllCasesGeneric } from '../all_cases_generic';
import { SECURITY_SOLUTION_OWNER } from '../../../../common';
jest.mock('../../../methods');
jest.mock('../all_cases_generic');
@ -20,6 +21,7 @@ const defaultProps = {
createCaseNavigation,
onRowClick,
userCanCrud: true,
owner: [SECURITY_SOLUTION_OWNER],
};
const updateCase = jest.fn();
@ -59,6 +61,7 @@ describe('AllCasesSelectorModal', () => {
},
index: 'index-id',
alertId: 'alert-id',
owner: SECURITY_SOLUTION_OWNER,
},
hiddenStatuses: [],
updateCase,

View file

@ -17,8 +17,10 @@ import {
import { CasesNavigation } from '../../links';
import * as i18n from '../../../common/translations';
import { AllCasesGeneric } from '../all_cases_generic';
import { Owner } from '../../../types';
import { OwnerProvider } from '../../owner_context';
export interface AllCasesSelectorModalProps {
export interface AllCasesSelectorModalProps extends Owner {
alertData?: Omit<CommentRequestAlertType, 'type'>;
createCaseNavigation: CasesNavigation;
hiddenStatuses?: CaseStatusWithAllStatus[];
@ -34,7 +36,7 @@ const Modal = styled(EuiModal)`
`}
`;
export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = ({
const AllCasesSelectorModalComponent: React.FC<AllCasesSelectorModalProps> = ({
alertData,
createCaseNavigation,
hiddenStatuses,
@ -70,5 +72,13 @@ export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = ({
</Modal>
) : null;
};
export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = React.memo((props) => {
return (
<OwnerProvider owner={props.owner}>
<AllCasesSelectorModalComponent {...props} />
</OwnerProvider>
);
});
// eslint-disable-next-line import/no-default-export
export { AllCasesSelectorModal as default };

View file

@ -13,8 +13,8 @@ import { ErrorMessage } from './types';
export const savedObjectReadOnlyErrorMessage: ErrorMessage = {
id: 'read-only-privileges-error',
title: i18n.READ_ONLY_SAVED_OBJECT_TITLE,
description: <>{i18n.READ_ONLY_SAVED_OBJECT_MSG}</>,
title: i18n.READ_ONLY_FEATURE_TITLE,
description: <>{i18n.READ_ONLY_FEATURE_MSG}</>,
errorType: 'warning',
};

View file

@ -7,17 +7,14 @@
import { i18n } from '@kbn/i18n';
export const READ_ONLY_SAVED_OBJECT_TITLE = i18n.translate('xpack.cases.readOnlySavedObjectTitle', {
export const READ_ONLY_FEATURE_TITLE = i18n.translate('xpack.cases.readOnlyFeatureTitle', {
defaultMessage: 'You cannot open new or update existing cases',
});
export const READ_ONLY_SAVED_OBJECT_MSG = i18n.translate(
'xpack.cases.readOnlySavedObjectDescription',
{
defaultMessage:
'You only have privileges to view cases. If you need to open and update cases, contact your Kibana administrator.',
}
);
export const READ_ONLY_FEATURE_MSG = i18n.translate('xpack.cases.readOnlyFeatureDescription', {
defaultMessage:
'You only have privileges to view cases. If you need to open and update cases, contact your Kibana administrator.',
});
export const DISMISS_CALLOUT = i18n.translate('xpack.cases.dismissErrorsPushServiceCallOutTitle', {
defaultMessage: 'Dismiss',

View file

@ -83,6 +83,7 @@ const CaseActionBarComponent: React.FC<CaseActionBarProps> = ({
<EuiDescriptionListDescription>
<StatusContextMenu
currentStatus={caseData.status}
disabled={disabled || isLoading}
onStatusChanged={onStatusChanged}
/>
</EuiDescriptionListDescription>

View file

@ -26,6 +26,18 @@ describe('SyncAlertsSwitch', () => {
expect(wrapper.find(`[data-test-subj="case-view-status-dropdown"]`).exists()).toBeTruthy();
});
it('it renders when disabled', async () => {
const wrapper = mount(
<StatusContextMenu
disabled={true}
currentStatus={CaseStatuses.open}
onStatusChanged={onStatusChanged}
/>
);
expect(wrapper.find(`[data-test-subj="case-view-status-dropdown"]`).exists()).toBeTruthy();
});
it('it renders the current status correctly', async () => {
const wrapper = mount(
<StatusContextMenu currentStatus={CaseStatuses.closed} onStatusChanged={onStatusChanged} />

View file

@ -13,16 +13,21 @@ import { Status } from '../status';
interface Props {
currentStatus: CaseStatuses;
disabled?: boolean;
onStatusChanged: (status: CaseStatuses) => void;
}
const StatusContextMenuComponent: React.FC<Props> = ({ currentStatus, onStatusChanged }) => {
const StatusContextMenuComponent: React.FC<Props> = ({
currentStatus,
onStatusChanged,
disabled = false,
}) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const closePopover = useCallback(() => setIsPopoverOpen(false), []);
const openPopover = useCallback(() => setIsPopoverOpen(true), []);
const popOverButton = useMemo(
() => <Status type={currentStatus} withArrow onClick={openPopover} />,
[currentStatus, openPopover]
() => <Status disabled={disabled} type={currentStatus} withArrow onClick={openPopover} />,
[disabled, currentStatus, openPopover]
);
const onContextMenuItemClick = useMemo(

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { AssociationType, CommentType } from '../../../common';
import { AssociationType, CommentType, SECURITY_SOLUTION_OWNER } from '../../../common';
import { Comment } from '../../containers/types';
import { getManualAlertIdsWithNoRuleId } from './helpers';
@ -28,6 +28,7 @@ const comments: Comment[] = [
updatedAt: null,
updatedBy: null,
version: 'WzQ3LDFc',
owner: SECURITY_SOLUTION_OWNER,
},
{
associationType: AssociationType.case,
@ -46,6 +47,7 @@ const comments: Comment[] = [
updatedAt: null,
updatedBy: null,
version: 'WzQ3LDFc',
owner: SECURITY_SOLUTION_OWNER,
},
];

View file

@ -43,6 +43,7 @@ import { Ecs } from '../../../common';
import { CasesTimelineIntegration, CasesTimelineIntegrationProvider } from '../timeline_context';
import { useTimelineContext } from '../timeline_context/use_timeline_context';
import { CasesNavigation } from '../links';
import { OwnerProvider } from '../owner_context';
const gutterTimeline = '70px'; // seems to be a timeline reference from the original file
export interface CaseViewComponentProps {
@ -450,6 +451,7 @@ export const CaseComponent = React.memo<CaseComponentProps>(
tags={caseData.tags}
onSubmit={onSubmitTags}
isLoading={isLoading && updateKey === 'tags'}
owner={[caseData.owner]}
/>
<EditConnector
caseFields={caseData.connector.fields}
@ -509,22 +511,24 @@ export const CaseView = React.memo(
return (
data && (
<CasesTimelineIntegrationProvider timelineIntegration={timelineIntegration}>
<CaseComponent
allCasesNavigation={allCasesNavigation}
caseData={data}
caseDetailsNavigation={caseDetailsNavigation}
caseId={caseId}
configureCasesNavigation={configureCasesNavigation}
getCaseDetailHrefWithCommentId={getCaseDetailHrefWithCommentId}
fetchCase={fetchCase}
onComponentInitialized={onComponentInitialized}
ruleDetailsNavigation={ruleDetailsNavigation}
showAlertDetails={showAlertDetails}
subCaseId={subCaseId}
updateCase={updateCase}
useFetchAlertData={useFetchAlertData}
userCanCrud={userCanCrud}
/>
<OwnerProvider owner={[data.owner]}>
<CaseComponent
allCasesNavigation={allCasesNavigation}
caseData={data}
caseDetailsNavigation={caseDetailsNavigation}
caseId={caseId}
configureCasesNavigation={configureCasesNavigation}
getCaseDetailHrefWithCommentId={getCaseDetailHrefWithCommentId}
fetchCase={fetchCase}
onComponentInitialized={onComponentInitialized}
ruleDetailsNavigation={ruleDetailsNavigation}
showAlertDetails={showAlertDetails}
subCaseId={subCaseId}
updateCase={updateCase}
useFetchAlertData={useFetchAlertData}
userCanCrud={userCanCrud}
/>
</OwnerProvider>
</CasesTimelineIntegrationProvider>
)
);

View file

@ -45,6 +45,7 @@ export const useCaseConfigureResponse: ReturnUseCaseConfigure = {
setCurrentConfiguration: jest.fn(),
setMappings: jest.fn(),
version: '',
id: '',
};
export const useConnectorsResponse: UseConnectorsResponse = {

View file

@ -10,7 +10,6 @@ import React, { memo, useMemo } from 'react';
import { CasesNavigation, LinkButton } from '../links';
// TODO: Potentially move into links component?
export interface ConfigureCaseButtonProps {
configureCasesNavigation: CasesNavigation;
isDisabled: boolean;

View file

@ -32,7 +32,7 @@ import {
useConnectorsResponse,
useActionTypesResponse,
} from './__mock__';
import { ConnectorTypes } from '../../../common';
import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common';
jest.mock('../../common/lib/kibana');
jest.mock('../../containers/configure/use_connectors');
@ -102,7 +102,9 @@ describe('ConfigureCases', () => {
useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] }));
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it renders the Connectors', () => {
@ -155,7 +157,9 @@ describe('ConfigureCases', () => {
}));
useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] }));
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it shows the warning callout when configuration is invalid', () => {
@ -200,7 +204,9 @@ describe('ConfigureCases', () => {
useConnectorsMock.mockImplementation(() => useConnectorsResponse);
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it renders with correct props', () => {
@ -220,9 +226,12 @@ describe('ConfigureCases', () => {
});
test('it disables correctly when the user cannot crud', () => {
const newWrapper = mount(<ConfigureCases userCanCrud={false} />, {
wrappingComponent: TestProviders,
});
const newWrapper = mount(
<ConfigureCases userCanCrud={false} owner={[SECURITY_SOLUTION_OWNER]} />,
{
wrappingComponent: TestProviders,
}
);
expect(newWrapper.find('button[data-test-subj="dropdown-connectors"]').prop('disabled')).toBe(
true
@ -282,7 +291,9 @@ describe('ConfigureCases', () => {
}));
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it disables correctly Connector when loading connectors', () => {
@ -315,7 +326,9 @@ describe('ConfigureCases', () => {
useActionTypesMock.mockImplementation(() => ({ ...useActionTypesResponse, loading: true }));
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
expect(wrapper.find(Connectors).prop('isLoading')).toBe(true);
});
});
@ -337,7 +350,9 @@ describe('ConfigureCases', () => {
useConnectorsMock.mockImplementation(() => useConnectorsResponse);
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it disables correctly Connector when saving configuration', () => {
@ -378,7 +393,9 @@ describe('ConfigureCases', () => {
...useConnectorsResponse,
}));
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it hides the update connector button when loading the configuration', () => {
@ -420,7 +437,9 @@ describe('ConfigureCases', () => {
useConnectorsMock.mockImplementation(() => useConnectorsResponse);
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it submits the configuration correctly when changing connector', () => {
@ -462,7 +481,9 @@ describe('ConfigureCases', () => {
},
}));
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
wrapper.update();
@ -508,7 +529,9 @@ describe('closure options', () => {
useConnectorsMock.mockImplementation(() => useConnectorsResponse);
useGetUrlSearchMock.mockImplementation(() => searchURL);
wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
});
test('it submits the configuration correctly when changing closure type', () => {
@ -555,7 +578,9 @@ describe('user interactions', () => {
});
test('it show the add flyout when pressing the add connector button', () => {
const wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
const wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
wrapper.update();
wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').simulate('click');
@ -576,7 +601,9 @@ describe('user interactions', () => {
});
test('it show the edit flyout when pressing the update connector button', () => {
const wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders });
const wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, {
wrappingComponent: TestProviders,
});
wrapper
.find('button[data-test-subj="case-configure-update-selected-connector-button"]')
.simulate('click');

View file

@ -31,6 +31,8 @@ import {
normalizeCaseConnector,
} from './utils';
import * as i18n from './translations';
import { Owner } from '../../types';
import { OwnerProvider } from '../owner_context';
const FormWrapper = styled.div`
${({ theme }) => css`
@ -50,11 +52,11 @@ const FormWrapper = styled.div`
`}
`;
export interface ConfigureCasesProps {
export interface ConfigureCasesProps extends Owner {
userCanCrud: boolean;
}
const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud }) => {
const ConfigureCasesComponent: React.FC<Omit<ConfigureCasesProps, 'owner'>> = ({ userCanCrud }) => {
const { triggersActionsUi } = useKibana().services;
const [connectorIsValid, setConnectorIsValid] = useState(true);
@ -223,6 +225,13 @@ const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud })
);
};
export const ConfigureCases = React.memo(ConfigureCasesComponent);
export const ConfigureCases: React.FC<ConfigureCasesProps> = React.memo((props) => {
return (
<OwnerProvider owner={props.owner}>
<ConfigureCasesComponent {...props} />
</OwnerProvider>
);
});
// eslint-disable-next-line import/no-default-export
export default ConfigureCases;

View file

@ -12,12 +12,13 @@ import styled from 'styled-components';
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { ActionParamsProps } from '../../../../../triggers_actions_ui/public/types';
import { CommentType } from '../../../../common';
import { CommentType, SECURITY_SOLUTION_OWNER } from '../../../../common';
import { CaseActionParams } from './types';
import { ExistingCase } from './existing_case';
import * as i18n from './translations';
import { OwnerProvider } from '../../owner_context';
const Container = styled.div`
${({ theme }) => `
@ -89,9 +90,15 @@ const CaseParamsFields: React.FunctionComponent<ActionParamsProps<CaseActionPara
actionParams.subAction,
]);
/**
* TODO: When the case connector is enabled we need to figure out
* how we can pass the owner to this component
*/
return (
<Container>
<ExistingCase onCaseChanged={onCaseChanged} selectedCase={selectedCase} />
<OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}>
<ExistingCase onCaseChanged={onCaseChanged} selectedCase={selectedCase} />
</OwnerProvider>
<EuiSpacer size="m" />
<EuiCallOut size="s" title={i18n.CASE_CONNECTOR_CALL_OUT_TITLE} iconType="iInCircle">
<p>{i18n.CASE_CONNECTOR_CALL_OUT_MSG}</p>

View file

@ -21,9 +21,12 @@ interface ExistingCaseProps {
}
const ExistingCaseComponent: React.FC<ExistingCaseProps> = ({ onCaseChanged, selectedCase }) => {
const { data: cases, loading: isLoadingCases, refetchCases } = useGetCases(DEFAULT_QUERY_PARAMS, {
...DEFAULT_FILTER_OPTIONS,
onlyCollectionType: true,
const { data: cases, loading: isLoadingCases, refetchCases } = useGetCases({
initialQueryParams: DEFAULT_QUERY_PARAMS,
initialFilterOptions: {
...DEFAULT_FILTER_OPTIONS,
onlyCollectionType: true,
},
});
const onCaseCreated = useCallback(

View file

@ -1,115 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { ReactNode } from 'react';
import { mount } from 'enzyme';
import { CreateCaseFlyout } from './flyout';
import { TestProviders } from '../../common/mock';
jest.mock('../create/form_context', () => {
return {
FormContext: ({
children,
onSuccess,
}: {
children: ReactNode;
onSuccess: ({ id }: { id: string }) => Promise<void>;
}) => {
return (
<>
<button
type="button"
data-test-subj="form-context-on-success"
onClick={async () => {
await onSuccess({ id: 'case-id' });
}}
>
{'submit'}
</button>
{children}
</>
);
},
};
});
jest.mock('../create/form', () => {
return {
CreateCaseForm: () => {
return <>{'form'}</>;
},
};
});
jest.mock('../create/submit_button', () => {
return {
SubmitCaseButton: () => {
return <>{'Submit'}</>;
},
};
});
const onCloseFlyout = jest.fn();
const onSuccess = jest.fn();
const defaultProps = {
onCloseFlyout,
onSuccess,
};
describe('CreateCaseFlyout', () => {
beforeEach(() => {
jest.resetAllMocks();
});
it('renders', () => {
const wrapper = mount(
<TestProviders>
<CreateCaseFlyout {...defaultProps} />
</TestProviders>
);
expect(wrapper.find(`[data-test-subj='create-case-flyout']`).exists()).toBeTruthy();
});
it('Closing modal calls onCloseCaseModal', () => {
const wrapper = mount(
<TestProviders>
<CreateCaseFlyout {...defaultProps} />
</TestProviders>
);
wrapper.find('.euiFlyout__closeButton').first().simulate('click');
expect(onCloseFlyout).toBeCalled();
});
it('pass the correct props to FormContext component', () => {
const wrapper = mount(
<TestProviders>
<CreateCaseFlyout {...defaultProps} />
</TestProviders>
);
const props = wrapper.find('FormContext').props();
expect(props).toEqual(
expect.objectContaining({
onSuccess,
})
);
});
it('onSuccess called when creating a case', () => {
const wrapper = mount(
<TestProviders>
<CreateCaseFlyout {...defaultProps} />
</TestProviders>
);
wrapper.find(`[data-test-subj='form-context-on-success']`).first().simulate('click');
expect(onSuccess).toHaveBeenCalledWith({ id: 'case-id' });
});
});

View file

@ -1,71 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { memo } from 'react';
import styled from 'styled-components';
import { EuiFlyout, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eui';
import { FormContext } from '../create/form_context';
import { CreateCaseForm } from '../create/form';
import { SubmitCaseButton } from '../create/submit_button';
import { Case } from '../../containers/types';
import * as i18n from '../../common/translations';
export interface CreateCaseModalProps {
onCloseFlyout: () => void;
onSuccess: (theCase: Case) => Promise<void>;
afterCaseCreated?: (theCase: Case) => Promise<void>;
}
const Container = styled.div`
${({ theme }) => `
margin-top: ${theme.eui.euiSize};
text-align: right;
`}
`;
const StyledFlyout = styled(EuiFlyout)`
${({ theme }) => `
z-index: ${theme.eui.euiZModal};
`}
`;
// Adding bottom padding because timeline's
// bottom bar gonna hide the submit button.
const FormWrapper = styled.div`
padding-bottom: 50px;
`;
const CreateCaseFlyoutComponent: React.FC<CreateCaseModalProps> = ({
onSuccess,
afterCaseCreated,
onCloseFlyout,
}) => {
return (
<StyledFlyout onClose={onCloseFlyout} data-test-subj="create-case-flyout">
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2>{i18n.CREATE_TITLE}</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<FormWrapper>
<FormContext onSuccess={onSuccess} afterCaseCreated={afterCaseCreated}>
<CreateCaseForm withSteps={false} />
<Container>
<SubmitCaseButton />
</Container>
</FormContext>
</FormWrapper>
</EuiFlyoutBody>
</StyledFlyout>
);
};
export const CreateCaseFlyout = memo(CreateCaseFlyoutComponent);
CreateCaseFlyout.displayName = 'CreateCaseFlyout';

View file

@ -15,6 +15,8 @@ import { useConnectors } from '../../containers/configure/use_connectors';
import { connectorsMock } from '../../containers/mock';
import { schema, FormProps } from './schema';
import { CreateCaseForm } from './form';
import { OwnerProvider } from '../owner_context';
import { SECURITY_SOLUTION_OWNER } from '../../../common';
jest.mock('../../containers/use_get_tags');
jest.mock('../../containers/configure/use_connectors');
@ -41,7 +43,11 @@ describe('CreateCaseForm', () => {
globalForm = form;
return <Form form={form}>{children}</Form>;
return (
<OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}>
<Form form={form}>{children}</Form>
</OwnerProvider>
);
};
beforeEach(() => {

View file

@ -10,7 +10,7 @@ import { mount, ReactWrapper } from 'enzyme';
import { act, waitFor } from '@testing-library/react';
import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
import { ConnectorTypes } from '../../../common';
import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common';
import { TestProviders } from '../../common/mock';
import { usePostCase } from '../../containers/use_post_case';
import { usePostComment } from '../../containers/use_post_comment';
@ -77,6 +77,7 @@ const defaultPostCase = {
const defaultCreateCaseForm = {
isLoadingConnectors: false,
connectors: [],
owner: SECURITY_SOLUTION_OWNER,
};
const defaultPostPushToService = {

View file

@ -21,6 +21,7 @@ import { useCaseConfigure } from '../../containers/configure/use_configure';
import { Case } from '../../containers/types';
import { CaseType, ConnectorTypes } from '../../../common';
import { UsePostComment, usePostComment } from '../../containers/use_post_comment';
import { useOwnerContext } from '../owner_context/use_owner_context';
const initialCaseValue: FormProps = {
description: '',
@ -47,6 +48,7 @@ export const FormContext: React.FC<Props> = ({
onSuccess,
}) => {
const { connectors, loading: isLoadingConnectors } = useConnectors();
const owner = useOwnerContext();
const { connector: configurationConnector } = useCaseConfigure();
const { postCase } = usePostCase();
const { postComment } = usePostComment();
@ -86,6 +88,7 @@ export const FormContext: React.FC<Props> = ({
type: caseType,
connector: connectorToUpdate,
settings: { syncAlerts },
owner: owner[0],
});
if (afterCaseCreated && updatedCase) {
@ -105,13 +108,14 @@ export const FormContext: React.FC<Props> = ({
}
},
[
caseType,
connectors,
postCase,
postComment,
onSuccess,
pushCaseToExternalService,
caseType,
owner,
afterCaseCreated,
onSuccess,
postComment,
pushCaseToExternalService,
]
);

View file

@ -29,6 +29,7 @@ import {
useGetFieldsByIssueTypeResponse,
} from './mock';
import { CreateCase } from '.';
import { SECURITY_SOLUTION_OWNER } from '../../../common';
jest.mock('../../containers/api');
jest.mock('../../containers/use_get_tags');
@ -91,7 +92,7 @@ describe('CreateCase case', () => {
it('it renders', async () => {
const wrapper = mount(
<TestProviders>
<CreateCase {...defaultProps} />
<CreateCase {...defaultProps} owner={[SECURITY_SOLUTION_OWNER]} />
</TestProviders>
);
@ -102,7 +103,7 @@ describe('CreateCase case', () => {
it('should call cancel on cancel click', async () => {
const wrapper = mount(
<TestProviders>
<CreateCase {...defaultProps} />
<CreateCase {...defaultProps} owner={[SECURITY_SOLUTION_OWNER]} />
</TestProviders>
);
@ -113,7 +114,7 @@ describe('CreateCase case', () => {
it('should redirect to new case when posting the case', async () => {
const wrapper = mount(
<TestProviders>
<CreateCase {...defaultProps} />
<CreateCase {...defaultProps} owner={[SECURITY_SOLUTION_OWNER]} />
</TestProviders>
);

View file

@ -20,6 +20,8 @@ import { CasesTimelineIntegration, CasesTimelineIntegrationProvider } from '../t
import { fieldName as descriptionFieldName } from './description';
import { InsertTimeline } from '../insert_timeline';
import { UsePostComment } from '../../containers/use_post_comment';
import { Owner } from '../../types';
import { OwnerProvider } from '../owner_context';
export const CommonUseField = getUseField({ component: Field });
@ -29,7 +31,7 @@ const Container = styled.div`
`}
`;
export interface CreateCaseProps {
export interface CreateCaseProps extends Owner {
afterCaseCreated?: (theCase: Case, postComment: UsePostComment['postComment']) => Promise<void>;
caseType?: CaseType;
hideConnectorServiceNowSir?: boolean;
@ -39,7 +41,7 @@ export interface CreateCaseProps {
withSteps?: boolean;
}
export const CreateCase = ({
const CreateCaseComponent = ({
afterCaseCreated,
caseType,
hideConnectorServiceNowSir,
@ -47,7 +49,7 @@ export const CreateCase = ({
onSuccess,
timelineIntegration,
withSteps,
}: CreateCaseProps) => (
}: Omit<CreateCaseProps, 'owner'>) => (
<CasesTimelineIntegrationProvider timelineIntegration={timelineIntegration}>
<FormContext
afterCaseCreated={afterCaseCreated}
@ -86,5 +88,12 @@ export const CreateCase = ({
</CasesTimelineIntegrationProvider>
);
export const CreateCase: React.FC<CreateCaseProps> = React.memo((props) => {
return (
<OwnerProvider owner={props.owner}>
<CreateCaseComponent {...props} />
</OwnerProvider>
);
});
// eslint-disable-next-line import/no-default-export
export { CreateCase as default };

View file

@ -5,7 +5,12 @@
* 2.0.
*/
import { CasePostRequest, CaseType, ConnectorTypes } from '../../../common';
import {
CasePostRequest,
CaseType,
ConnectorTypes,
SECURITY_SOLUTION_OWNER,
} from '../../../common';
import { choices } from '../connectors/mock';
export const sampleTags = ['coke', 'pepsi'];
@ -23,6 +28,7 @@ export const sampleData: CasePostRequest = {
settings: {
syncAlerts: true,
},
owner: SECURITY_SOLUTION_OWNER,
};
export const sampleConnectorData = { loading: false, connectors: [] };

View file

@ -19,7 +19,7 @@ export const schemaTags = {
labelAppend: OptionalFieldLabel,
};
export type FormProps = Omit<CasePostRequest, 'connector' | 'settings'> & {
export type FormProps = Omit<CasePostRequest, 'connector' | 'settings' | 'owner'> & {
connectorId: string;
fields: ConnectorTypeFields['fields'];
syncAlerts: boolean;

View file

@ -14,6 +14,8 @@ import { useForm, Form, FormHook } from '../../common/shared_imports';
import { useGetTags } from '../../containers/use_get_tags';
import { Tags } from './tags';
import { schema, FormProps } from './schema';
import { OwnerProvider } from '../owner_context';
import { SECURITY_SOLUTION_OWNER } from '../../../common';
jest.mock('../../containers/use_get_tags');
const useGetTagsMock = useGetTags as jest.Mock;
@ -31,7 +33,11 @@ describe('Tags', () => {
globalForm = form;
return <Form form={form}>{children}</Form>;
return (
<OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}>
<Form form={form}>{children}</Form>
</OwnerProvider>
);
};
beforeEach(() => {

Some files were not shown because too many files have changed in this diff Show more